Files
ResumeSite/deploy/docker-compose.yml
cesnimda 9088dcffb9 feat: Docker images, compose stacks, nginx config, Gitea CI
- site image: multi-stage node build -> unprivileged nginx (non-root, read-only)
- nginx: CSP + security headers, immutable asset caching, revalidated HTML,
  canonical trailing slash, preserved /Linkedin 301, legacy-WP 410s, custom 404
- externalise theme-init so CSP uses script-src 'self' (no inline hash)
- prod + dev compose; .env.example; relay Dockerfile fixed (image ships app user)
- Gitea Actions: quality, e2e, lighthouse budgets, relay build, image push on main
- verified: both images build; relay healthz 200; site serves EN/NO with CSP + redirect

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 06:21:35 +02:00

48 lines
1.3 KiB
YAML

# Production stack (DOCKER_SPEC §2). Publishes no host ports — the existing host
# reverse proxy routes cesnimda.co.uk -> site:8080 and /api/contact -> relay:8081
# over the shared external proxy network.
services:
site:
build:
context: ../site
dockerfile: Dockerfile
image: git.cesnimda.uk/cesnimda/resumesite-site:latest
restart: unless-stopped
read_only: true
tmpfs:
- /tmp
- /var/cache/nginx
- /var/run
networks: [web]
logging:
driver: json-file
options: { max-size: '10m', max-file: '3' }
relay:
build:
context: ../relay
dockerfile: Dockerfile
image: git.cesnimda.uk/cesnimda/resumesite-relay:latest
restart: unless-stopped
read_only: true
environment:
- Smtp__Host=${SMTP_HOST}
- Smtp__Port=${SMTP_PORT:-587}
- Smtp__User=${SMTP_USER}
- Smtp__Password=${SMTP_PASSWORD}
- Relay__FromAddress=${RELAY_FROM:-}
- Relay__ToAddress=${RELAY_TO}
- Relay__AllowedOrigin=${RELAY_ALLOWED_ORIGIN:-https://cesnimda.co.uk}
- Relay__RateLimitPerWindow=${RELAY_RATE_LIMIT:-5}
- Relay__WindowSeconds=${RELAY_WINDOW_SECONDS:-600}
networks: [web]
logging:
driver: json-file
options: { max-size: '10m', max-file: '3' }
networks:
web:
external: true
name: ${PROXY_NETWORK:-web}