Compare commits
5 Commits
45271e15ac
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 6436fac3fc | |||
| fad417697a | |||
| 5aad7fd48f | |||
| a65ff61da6 | |||
| 81cd4eb803 |
18
Dockerfile
18
Dockerfile
@@ -98,10 +98,14 @@ HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
|
|||||||
|
|
||||||
# Run Uvicorn directly. --proxy-headers + --forwarded-allow-ips make
|
# Run Uvicorn directly. --proxy-headers + --forwarded-allow-ips make
|
||||||
# Starlette's ProxyHeadersMiddleware trust X-Forwarded-* only from the
|
# Starlette's ProxyHeadersMiddleware trust X-Forwarded-* only from the
|
||||||
# listed peer IPs (Caddy on the host). No --reload: this is a prod-shape
|
# listed peer IPs. The trusted-IP value is env-driven so the image
|
||||||
# image; local hot-reload is a dev concern and runs outside Docker.
|
# can be reused across topologies:
|
||||||
CMD ["uvicorn", "app.main:app", \
|
# - local: defaults to 127.0.0.1 (when running uvicorn on the host)
|
||||||
"--host", "0.0.0.0", \
|
# - docker/compose behind Caddy: set FORWARDED_ALLOW_IPS="*" in .env
|
||||||
"--port", "8080", \
|
# because the container's source IP is the bridge gateway, not
|
||||||
"--proxy-headers", \
|
# 127.0.0.1. Safe because the host only binds 127.0.0.1:8080 so
|
||||||
"--forwarded-allow-ips", "127.0.0.1"]
|
# nothing off-host can reach uvicorn directly.
|
||||||
|
# `sh -c exec` keeps uvicorn as PID 1 so SIGTERM still triggers a
|
||||||
|
# graceful shutdown (exec form was fine before, but we need shell
|
||||||
|
# expansion for ${FORWARDED_ALLOW_IPS}).
|
||||||
|
CMD ["sh", "-c", "exec uvicorn app.main:app --host 0.0.0.0 --port 8080 --proxy-headers --forwarded-allow-ips \"${FORWARDED_ALLOW_IPS:-127.0.0.1}\""]
|
||||||
|
|||||||
69
docker-compose.prod.yml
Normal file
69
docker-compose.prod.yml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Chicken Babies R Us — production compose file.
|
||||||
|
#
|
||||||
|
# Meant for the Debian 12 VM behind Caddy. Unlike docker-compose.yml (which
|
||||||
|
# builds the image from source for local dev), this file pulls the pre-built
|
||||||
|
# image from the Gitea container registry so the VM stays a thin runner.
|
||||||
|
#
|
||||||
|
# Ansible responsibilities (not this file):
|
||||||
|
# - render /opt/chicken-babies/.env with real secrets
|
||||||
|
# - ensure data/ exists and is owned by uid:gid 10001:10001
|
||||||
|
# sudo install -d -o 10001 -g 10001 /opt/chicken-babies/data/media
|
||||||
|
# sudo install -d -o 10001 -g 10001 /opt/chicken-babies/data/backups
|
||||||
|
# - `docker login git.sneakygeek.net -u <user> -p <REGISTRY_TOKEN>`
|
||||||
|
# - copy this file as /opt/chicken-babies/docker-compose.yml
|
||||||
|
# - run `docker compose pull && docker compose up -d`
|
||||||
|
#
|
||||||
|
# Update flow on the VM (after a CI build publishes a new :latest):
|
||||||
|
# docker compose pull
|
||||||
|
# docker compose up -d # restarts only if the image SHA changed
|
||||||
|
# docker image prune -f # reclaim space from the old layers
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: git.sneakygeek.net/ptarrant/chicken_babies_site:latest
|
||||||
|
# Docker pulls :latest on `docker compose pull`; no build context needed.
|
||||||
|
pull_policy: always
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
# Override the Dockerfile CMD so uvicorn trusts X-Forwarded-* headers.
|
||||||
|
# Caddy lives on another server (10.10.99.10) and speaks HTTP to this
|
||||||
|
# VM on port 8080. Even so, the source IP *inside* the container is
|
||||||
|
# the Docker bridge gateway (typically 172.17.0.1), NOT 10.10.99.10,
|
||||||
|
# because Docker NATs the inbound connection. That means allowlisting
|
||||||
|
# 10.10.99.10 would never match — uvicorn would still drop X-Forwarded-*
|
||||||
|
# and Starlette would build http:// URLs under an https:// page,
|
||||||
|
# tripping `img-src 'self'` CSP on the logo, fonts, etc.
|
||||||
|
#
|
||||||
|
# "*" is acceptable here because access to port 8080 is controlled
|
||||||
|
# at the network layer (host firewall / VLAN) — only the Caddy box
|
||||||
|
# can reach it. If you later move Caddy onto this same host, change
|
||||||
|
# this back to a specific gateway IP.
|
||||||
|
command: >
|
||||||
|
uvicorn app.main:app
|
||||||
|
--host 0.0.0.0
|
||||||
|
--port 8080
|
||||||
|
--proxy-headers
|
||||||
|
--forwarded-allow-ips *
|
||||||
|
ports:
|
||||||
|
# Caddy on 10.10.99.10 reverse-proxies to <this-vm>:8080. Binding
|
||||||
|
# on all interfaces keeps the compose portable; lock down access
|
||||||
|
# with the VM's host firewall (nftables / ufw) or upstream
|
||||||
|
# (OPNsense) to only permit 10.10.99.10 → :8080.
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
# SQLite DB + media uploads live on the host so container rebuilds /
|
||||||
|
# image rolls don't wipe content. The container runs as uid 10001;
|
||||||
|
# the host dir must be chown'd to match (see Ansible notes above).
|
||||||
|
- ./data:/app/data
|
||||||
|
restart: unless-stopped
|
||||||
|
# Docker picks up the HEALTHCHECK baked into the image. `docker compose
|
||||||
|
# ps` surfaces health status; systemd / Ansible tasks can gate on it.
|
||||||
|
# Container-level logging caps so a chatty bot run doesn't fill the
|
||||||
|
# VM disk before the host-side logrotate catches it.
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "5"
|
||||||
Reference in New Issue
Block a user