# Coolify & Production Ready Docker Compose Configuration # Traefik in Coolify automatically routes traffic to the 'frontend' service on port 80 via expose. # Host port bindings (ports) are omitted to avoid host port 80 conflicts with Traefik. services: db: image: postgres:16-alpine environment: POSTGRES_DB: ${POSTGRES_DB:-shiftplan_db} POSTGRES_USER: ${POSTGRES_USER:-shiftplan_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-shiftplan_secure_password_123} volumes: - postgres_data:/var/lib/postgresql/data expose: - "5432" restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready"] interval: 3s timeout: 3s retries: 10 backend: build: context: ./backend dockerfile: Dockerfile command: > sh -c "python manage.py migrate --noinput && python manage.py collectstatic --noinput && python manage.py create_admin && gunicorn --bind 0.0.0.0:8000 --workers 3 shiftplan_backend.wsgi:application" environment: SECRET_KEY: ${SECRET_KEY:-prod-secret-key-change-in-coolify} DEBUG: ${DEBUG:-False} ALLOWED_HOSTS: ${ALLOWED_HOSTS:-*} POSTGRES_DB: ${POSTGRES_DB:-shiftplan_db} POSTGRES_USER: ${POSTGRES_USER:-shiftplan_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-shiftplan_secure_password_123} POSTGRES_HOST: db POSTGRES_PORT: "5432" volumes: - static_volume:/app/staticfiles depends_on: db: condition: service_healthy expose: - "8000" restart: unless-stopped frontend: build: context: ./frontend dockerfile: Dockerfile volumes: - static_volume:/usr/share/nginx/html/static expose: - "80" depends_on: - backend restart: unless-stopped volumes: postgres_data: static_volume: