version: "3.8" services: db: image: postgres:16 environment: POSTGRES_USER: ${DB_USER:-liferpg} POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme123} POSTGRES_DB: ${DB_NAME:-liferpg} # Security configurations POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256 --auth-local=scram-sha-256" ports: - "${DB_PORT:-5432}:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./backend/db_security.sql:/docker-entrypoint-initdb.d/01-security.sql:ro healthcheck: test: ["CMD", "bash", "-lc", "cat < /dev/tcp/127.0.0.1/5432"] interval: 10s timeout: 5s retries: 10 security_opt: - no-new-privileges:true read_only: true tmpfs: - /tmp - /var/run/postgresql networks: - backend redis: image: redis:7-alpine command: redis-server --requirepass ${REDIS_PASSWORD:-redispassword123} --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru ports: - "${REDIS_PORT:-6379}:6379" volumes: - redis_data:/data healthcheck: test: [ "CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-redispassword123}", "ping", ] interval: 5s timeout: 3s retries: 10 networks: - backend security_opt: - no-new-privileges:true backend: build: context: .. dockerfile: modern/backend/Dockerfile environment: DATABASE_URL: postgresql+psycopg2://${DB_USER:-liferpg}:${DB_PASSWORD:-changeme123}@db:5432/${DB_NAME:-liferpg} FRONTEND_ORIGIN: ${FRONTEND_ORIGIN:-http://localhost:5173} CSRF_ENABLE: "true" COOKIE_SECURE: "${COOKIE_SECURE:-false}" COOKIE_SAMESITE: ${COOKIE_SAMESITE:-lax} REDIS_URL: redis://:${REDIS_PASSWORD:-redispassword123}@redis:6379/0 LIFERPG_JWT_SECRET: ${LIFERPG_JWT_SECRET} ENVIRONMENT: ${ENVIRONMENT:-development} depends_on: db: condition: service_healthy redis: condition: service_started ports: - "${BACKEND_PORT:-8000}:8000" networks: - backend - frontend security_opt: - no-new-privileges:true worker: build: context: .. dockerfile: modern/backend/Dockerfile environment: DATABASE_URL: postgresql+psycopg2://${DB_USER:-liferpg}:${DB_PASSWORD:-changeme123}@db:5432/${DB_NAME:-liferpg} REDIS_URL: redis://:${REDIS_PASSWORD:-redispassword123}@redis:6379/0 LIFERPG_JWT_SECRET: ${LIFERPG_JWT_SECRET} ENVIRONMENT: ${ENVIRONMENT:-development} depends_on: db: condition: service_healthy redis: condition: service_healthy command: ["bash", "-lc", "rq worker -u $REDIS_URL default"] networks: - backend security_opt: - no-new-privileges:true frontend: build: context: .. dockerfile: modern/frontend/Dockerfile ports: - "${FRONTEND_PORT:-5173}:5173" depends_on: - backend networks: - frontend security_opt: - no-new-privileges:true networks: backend: driver: bridge internal: false # Backend network can access external services ipam: config: - subnet: 172.20.0.0/16 frontend: driver: bridge internal: false # Frontend network for user-facing services volumes: postgres_data: driver: local redis_data: driver: local