services: ssl-init: image: alpine:3.20 container_name: shop-ssl-init volumes: - postgres_ssl:/certs - ./postgres/ssl/generate-certs.sh:/generate-certs.sh:ro entrypoint: ["/bin/sh", "-c", "apk add --no-cache openssl > /dev/null && /generate-certs.sh /certs"] restart: "no" postgres: image: postgres:17-alpine container_name: shop-postgres depends_on: ssl-init: condition: service_completed_successfully environment: POSTGRES_USER: ${POSTGRES_USER:-shop} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-shop_secret} POSTGRES_DB: ${POSTGRES_DB:-shopdb} volumes: - postgres_data:/var/lib/postgresql/data - postgres_ssl:/var/lib/postgresql/ssl:ro - ./postgres/init:/docker-entrypoint-initdb.d:ro command: - postgres - -c - ssl=on - -c - ssl_cert_file=/var/lib/postgresql/ssl/server.crt - -c - ssl_key_file=/var/lib/postgresql/ssl/server.key - -c - ssl_min_protocol_version=TLSv1.2 healthcheck: test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"] interval: 5s timeout: 5s retries: 10 start_period: 15s networks: - backend restart: unless-stopped app: build: context: . dockerfile: Dockerfile container_name: shop-app depends_on: postgres: condition: service_healthy environment: APP_PORT: "8080" DATABASE_URL: postgres://${POSTGRES_USER:-shop}:${POSTGRES_PASSWORD:-shop_secret}@postgres:5432/${POSTGRES_DB:-shopdb}?sslmode=require networks: - backend - frontend restart: unless-stopped caddy: image: caddy:2-alpine container_name: shop-caddy depends_on: - app ports: - "${HTTP_PORT:-80}:80" - "${HTTPS_PORT:-443}:443" volumes: - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro - caddy_data:/data - caddy_config:/config networks: - frontend restart: unless-stopped volumes: postgres_data: postgres_ssl: caddy_data: caddy_config: networks: backend: frontend: