# Backend is intentionally not published to the host: the browser only ever # talks to the frontend, which proxies /api to it over the internal network. # That keeps sessions same-origin, exactly as the Vite dev proxy does. services: redis: image: redis:8-alpine command: ["redis-server", "--save", "60", "1"] volumes: - redis-data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 5 restart: unless-stopped backend: build: context: . target: backend environment: NODE_ENV: production # No default in env.ts - the server exits on boot without it. SESSION_SECRET: ${SESSION_SECRET:?set SESSION_SECRET in .env} DATABASE_URL: file:/data/blog.db REDIS_URL: redis://redis:6379 volumes: - blog-data:/data depends_on: redis: condition: service_healthy restart: unless-stopped frontend: build: context: . target: frontend environment: NODE_ENV: production PORT: 5173 BACKEND_ORIGIN: http://backend:3000 ports: - "${FRONTEND_PORT:-5173}:5173" depends_on: backend: condition: service_healthy restart: unless-stopped volumes: blog-data: redis-data: