best / docker-compose.prod.yml
anky2002's picture
fix(P0): Production compose removes direct backend/frontend ports, only nginx exposed
5d7a505 verified
Raw
History Blame Contribute Delete
2.74 kB
version: "3.8"
# PRODUCTION docker-compose
# Only nginx is exposed to the host network.
# Backend and frontend are internal services accessed via nginx reverse proxy.
services:
db:
image: pgvector/pgvector:pg17
restart: always
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: always
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru --requirepass ${REDIS_PASSWORD:-}
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
backend:
build:
context: ./backend
dockerfile: Dockerfile
restart: always
env_file:
- .env
environment:
- POSTGRES_SERVER=db
- REDIS_URL=redis://:${REDIS_PASSWORD:-}@redis:6379/0
expose:
- "8000"
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
command: >
sh -c "uv run alembic upgrade head &&
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4"
worker:
build:
context: ./backend
dockerfile: Dockerfile
restart: always
env_file:
- .env
environment:
- POSTGRES_SERVER=db
- REDIS_URL=redis://:${REDIS_PASSWORD:-}@redis:6379/0
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
command: uv run celery -A app.worker.celery_config.celery_app worker --loglevel=warning --concurrency=2
beat:
build:
context: ./backend
dockerfile: Dockerfile
restart: always
env_file:
- .env
environment:
- POSTGRES_SERVER=db
- REDIS_URL=redis://:${REDIS_PASSWORD:-}@redis:6379/0
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
command: uv run celery -A app.worker.celery_config.celery_app beat --loglevel=warning
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
restart: always
environment:
# Empty = same-origin. Browser calls /api/v1 which nginx proxies to backend.
- NEXT_PUBLIC_API_URL=
expose:
- "3000"
depends_on:
- backend
nginx:
image: nginx:alpine
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- frontend
- backend
volumes:
postgres_data: