services: postgres: image: postgres:16.9-alpine restart: unless-stopped init: true environment: POSTGRES_DB: ${POSTGRES_DB:-theatre_lab} POSTGRES_USER: ${POSTGRES_USER:-theatre_lab} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-replace-with-a-local-password} volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 10 start_period: 5s security_opt: - no-new-privileges:true backend: build: context: ./backend restart: unless-stopped init: true environment: DATABASE_URL: ${DATABASE_URL:-postgresql://theatre_lab:replace-with-a-local-password@postgres:5432/theatre_lab} DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:-replace-with-a-long-random-development-key} DJANGO_DEBUG: ${DJANGO_DEBUG:-true} DJANGO_ALLOWED_HOSTS: ${DJANGO_ALLOWED_HOSTS:-localhost,127.0.0.1,backend} WAGTAILADMIN_BASE_URL: ${WAGTAILADMIN_BASE_URL:-http://localhost:8000} volumes: - media_data:/app/media ports: - "127.0.0.1:8000:8000" depends_on: postgres: condition: service_healthy healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health/', timeout=2)"] interval: 10s timeout: 5s retries: 10 start_period: 20s security_opt: - no-new-privileges:true frontend: build: context: ./frontend restart: unless-stopped init: true environment: PUBLIC_CMS_API_URL: ${PUBLIC_CMS_API_URL:-http://backend:8000} ports: - "127.0.0.1:4321:4321" depends_on: backend: condition: service_healthy healthcheck: test: [ "CMD", "node", "-e", "fetch('http://localhost:4321/').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))", ] interval: 10s timeout: 5s retries: 10 start_period: 20s security_opt: - no-new-privileges:true volumes: postgres_data: media_data: