name: sexy services: postgres: image: postgres:16-alpine container_name: sexy_postgres restart: unless-stopped ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data environment: POSTGRES_DB: sexy POSTGRES_USER: sexy POSTGRES_PASSWORD: sexy healthcheck: test: ["CMD-SHELL", "pg_isready -U sexy"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine container_name: sexy_redis restart: unless-stopped ports: - "6379:6379" volumes: - redis_data:/data command: redis-server --appendonly yes healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 backend: build: context: . dockerfile: Dockerfile.backend container_name: sexy_backend restart: unless-stopped ports: - "4000:4000" volumes: - uploads_data:/data/uploads environment: DATABASE_URL: postgresql://sexy:sexy@sexy_postgres:5432/sexy REDIS_URL: redis://sexy_redis:6379 UPLOAD_DIR: /data/uploads CORS_ORIGIN: http://localhost:3000 PORT: 4000 NODE_ENV: production COOKIE_SECRET: change-me-in-production SMTP_HOST: localhost SMTP_PORT: 587 EMAIL_FROM: noreply@sexy.pivoine.art PUBLIC_URL: http://localhost:3000 depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4000/health"] interval: 30s timeout: 10s retries: 3 start_period: 20s frontend: build: context: . dockerfile: Dockerfile container_name: sexy_frontend restart: unless-stopped ports: - "3000:3000" environment: NODE_ENV: production PORT: 3000 HOST: 0.0.0.0 PUBLIC_API_URL: http://sexy_backend:4000 PUBLIC_URL: http://localhost:3000 depends_on: backend: condition: service_healthy volumes: uploads_data: driver: local postgres_data: driver: local redis_data: driver: local