services: db: image: postgres:15-alpine container_name: cloneforge-db restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-cloneforge} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-cloneforge_secret} POSTGRES_DB: ${POSTGRES_DB:-cloneforge} volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 10s timeout: 10s retries: 15 start_period: 60s redis: image: redis:7-alpine container_name: cloneforge-redis restart: unless-stopped ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 backend: build: context: ./backend dockerfile: Dockerfile container_name: cloneforge-backend restart: unless-stopped depends_on: db: condition: service_healthy redis: condition: service_healthy environment: - DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://cloneforge:cloneforge_secret@db:5432/cloneforge} - CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://redis:6379/0} - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND:-redis://redis:6379/0} - REDIS_URL=${REDIS_URL:-redis://redis:6379/0} - SECRET_KEY=${SECRET_KEY:-change-me-in-production} - FRONTEND_URL=${FRONTEND_URL:-http://localhost:3000} - FIRST_SUPERUSER_EMAIL=${FIRST_SUPERUSER_EMAIL:-admin@cloneforge.local} - FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD:-admin} - STORAGE_LOCAL_PATH=/app/storage/projects - MAX_CRAWL_DEPTH=${MAX_CRAWL_DEPTH:-5} - MAX_CONCURRENT_REQUESTS=${MAX_CONCURRENT_REQUESTS:-8} - ALLOW_PRIVATE_NETWORKS=${ALLOW_PRIVATE_NETWORKS:-false} volumes: - ./storage:/app/storage ports: - "8000:8000" command: > sh -c "alembic upgrade head && python -m app.reset_admin && uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload" worker: build: context: ./backend dockerfile: Dockerfile container_name: cloneforge-worker restart: unless-stopped depends_on: - db - redis environment: - DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://cloneforge:cloneforge_secret@db:5432/cloneforge} - CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://redis:6379/0} - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND:-redis://redis:6379/0} - REDIS_URL=${REDIS_URL:-redis://redis:6379/0} - SECRET_KEY=${SECRET_KEY:-change-me-in-production} - STORAGE_LOCAL_PATH=/app/storage/projects - MAX_CRAWL_DEPTH=${MAX_CRAWL_DEPTH:-5} - MAX_CONCURRENT_REQUESTS=${MAX_CONCURRENT_REQUESTS:-8} - ALLOW_PRIVATE_NETWORKS=${ALLOW_PRIVATE_NETWORKS:-false} volumes: - ./storage:/app/storage command: > sh -c "celery -A app.workers.celery_app worker --loglevel=info --concurrency=2" frontend: build: context: ./frontend dockerfile: Dockerfile target: runner container_name: cloneforge-frontend restart: unless-stopped depends_on: - backend environment: - NEXT_PUBLIC_API_URL=http://localhost:8000 - API_URL=http://backend:8000 ports: - "3000:3000" volumes: postgres_data: redis_data: