# J621 — backend-only deployment: API + database + nginx proxy + Tailscale. # # cd deploy && cp .env.example .env # TS_AUTHKEY, SECRET_KEY, hosts, CORS # docker compose -f compose.backend.yml up -d # # Funnel: https://..ts.net:8443 (an allowed funnel port) # reaches the nginx service, which routes /api, /admin, /static and /health to # Django. "/" answers a small JSON hint because no frontend is attached. # # Because the frontend lives elsewhere it is cross-origin — set in .env: # CORS_ALLOWED_ORIGINS=https://..ts.net # CSRF_TRUSTED_ORIGINS=... (same value; only needed for the admin) # and add this host to ALLOWED_HOSTS (comma separated list). name: j621-backend-deploy services: mariadb: image: mariadb:11.4 restart: unless-stopped environment: MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-j621root} MARIADB_DATABASE: ${DB_NAME:-j621} MARIADB_USER: ${DB_USER:-j621} MARIADB_PASSWORD: ${DB_PASSWORD:-j621} volumes: - ./data/mariadb:/var/lib/mysql healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] interval: 5s timeout: 5s retries: 20 redis: image: redis:7-alpine restart: unless-stopped command: ["redis-server", "--appendonly", "yes"] volumes: - ./data/redis:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 20 backend: image: ${J621_REGISTRY:-gitea.rainbow-herring.ts.net/jakebreath}/j621-backend:${J621_TAG:-latest} build: context: .. dockerfile: deploy/J621-Backend # Bake the commit into the image so the shell's version pill shows it; # the push scripts pass --build-arg themselves. args: GIT_HASH: ${GIT_HASH:-unknown} restart: unless-stopped env_file: [./.env] environment: DB_HOST: mariadb DB_PORT: "3306" REDIS_URL: redis://redis:6379/1 TRUST_PROXY_HEADERS: "true" volumes: - ./data/media:/app/media - ./data/logs:/app/logs depends_on: mariadb: condition: service_healthy redis: condition: service_healthy nginx: image: nginx:1.29-alpine restart: unless-stopped volumes: - ./nginx-proxy.conf:/etc/nginx/conf.d/default.conf:ro depends_on: backend: condition: service_healthy healthcheck: test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1/nginx-health || exit 1"] interval: 30s timeout: 3s retries: 3 start_period: 10s tailscale: image: tailscale/tailscale:latest restart: unless-stopped # Shares the nginx service's network namespace: 127.0.0.1:80 is the proxy. network_mode: "service:nginx" environment: TS_AUTHKEY: ${TS_AUTHKEY:?Set TS_AUTHKEY in deploy/.env} TS_HOSTNAME: ${TS_HOSTNAME:-j621-backend} TS_AUTH_ONCE: "true" TS_STATE_DIR: /var/lib/tailscale TS_SERVE_CONFIG: /config/serve.json volumes: - ./tailscale-state:/var/lib/tailscale - ./serve.backend.json:/config/serve.json:ro - /etc/ssl/certs:/etc/ssl/certs:ro depends_on: nginx: condition: service_healthy healthcheck: test: ["CMD", "tailscale", "status"] interval: 30s timeout: 5s retries: 3 start_period: 30s