# ============================================== # Docker Compose — Universal (dev / prod) # ============================================== # Все различия между dev и prod определяются в .env: # COMPOSE_PROJECT_NAME, ENVIRONMENT, порты, target сборки и т.д. # # ВАЖНО: НЕ используйте: docker compose down --volumes (удалит данные БД!) # Для запуска: docker compose up -d --build # ============================================== services: db: image: postgres:16-alpine container_name: ${COMPOSE_PROJECT_NAME}_db restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "${DB_PORT:-5432}:5432" volumes: - postgres_data:/var/lib/postgresql/data networks: - app_network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine container_name: ${COMPOSE_PROJECT_NAME}_redis restart: unless-stopped ports: - "${REDIS_PORT:-6379}:6379" volumes: - redis_data:/data networks: - app_network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 web: build: context: ./backend dockerfile: Dockerfile container_name: ${COMPOSE_PROJECT_NAME}_web restart: unless-stopped user: "0:0" env_file: .env command: sh -c "python manage.py migrate && python manage.py init_subjects && daphne -b 0.0.0.0 -p 8000 config.asgi:application" environment: - DEBUG=${DEBUG:-False} - SECRET_KEY=${SECRET_KEY} - ALLOWED_HOSTS=${ALLOWED_HOSTS} - CORS_ALLOWED_ORIGINS=${CORS_ALLOWED_ORIGINS} - CSRF_TRUSTED_ORIGINS=${CSRF_TRUSTED_ORIGINS} - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${COMPOSE_PROJECT_NAME}_db:5432/${POSTGRES_DB} - REDIS_URL=redis://${COMPOSE_PROJECT_NAME}_redis:6379/0 - CELERY_BROKER_URL=redis://${COMPOSE_PROJECT_NAME}_redis:6379/1 - CELERY_RESULT_BACKEND=redis://${COMPOSE_PROJECT_NAME}_redis:6379/2 - EMAIL_BACKEND=${EMAIL_BACKEND:-smtp} - EMAIL_HOST=${EMAIL_HOST} - EMAIL_PORT=${EMAIL_PORT:-2525} - EMAIL_USE_TLS=${EMAIL_USE_TLS:-True} - EMAIL_USE_SSL=${EMAIL_USE_SSL:-False} - EMAIL_HOST_USER=${EMAIL_HOST_USER} - EMAIL_HOST_PASSWORD=${EMAIL_HOST_PASSWORD} - DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL} - EMAIL_TIMEOUT=${EMAIL_TIMEOUT:-10} - FRONTEND_URL=${FRONTEND_URL} - LIVEKIT_PUBLIC_URL=${LIVEKIT_PUBLIC_URL} - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN} - TELEGRAM_USE_WEBHOOK=${TELEGRAM_USE_WEBHOOK:-False} - TELEGRAM_WEBHOOK_URL=${TELEGRAM_WEBHOOK_URL:-} - TELEGRAM_WEBHOOK_SECRET_TOKEN=${TELEGRAM_WEBHOOK_SECRET_TOKEN:-} ports: - "${WEB_PORT:-8000}:8000" volumes: - ./backend:/app depends_on: db: condition: service_healthy redis: condition: service_healthy networks: - app_network celery: build: context: ./backend dockerfile: Dockerfile container_name: ${COMPOSE_PROJECT_NAME}_celery restart: unless-stopped user: "0:0" env_file: .env command: celery -A config worker -l info environment: - DEBUG=${DEBUG:-False} - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${COMPOSE_PROJECT_NAME}_db:5432/${POSTGRES_DB} - REDIS_URL=redis://${COMPOSE_PROJECT_NAME}_redis:6379/0 - CELERY_BROKER_URL=redis://${COMPOSE_PROJECT_NAME}_redis:6379/1 - CELERY_RESULT_BACKEND=redis://${COMPOSE_PROJECT_NAME}_redis:6379/2 - EMAIL_BACKEND=${EMAIL_BACKEND:-smtp} - EMAIL_HOST=${EMAIL_HOST} - EMAIL_PORT=${EMAIL_PORT:-2525} - EMAIL_USE_TLS=${EMAIL_USE_TLS:-True} - EMAIL_USE_SSL=${EMAIL_USE_SSL:-False} - EMAIL_HOST_USER=${EMAIL_HOST_USER} - EMAIL_HOST_PASSWORD=${EMAIL_HOST_PASSWORD} - DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL} - EMAIL_TIMEOUT=${EMAIL_TIMEOUT:-10} - FRONTEND_URL=${FRONTEND_URL} - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN} - TELEGRAM_USE_WEBHOOK=${TELEGRAM_USE_WEBHOOK:-False} - TELEGRAM_WEBHOOK_URL=${TELEGRAM_WEBHOOK_URL:-} - TELEGRAM_WEBHOOK_SECRET_TOKEN=${TELEGRAM_WEBHOOK_SECRET_TOKEN:-} volumes: - ./backend:/app depends_on: - db - redis - web networks: - app_network celery-beat: build: context: ./backend dockerfile: Dockerfile container_name: ${COMPOSE_PROJECT_NAME}_celery_beat restart: unless-stopped user: "0:0" env_file: .env command: celery -A config beat -l info environment: - DEBUG=${DEBUG:-False} - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${COMPOSE_PROJECT_NAME}_db:5432/${POSTGRES_DB} - REDIS_URL=redis://${COMPOSE_PROJECT_NAME}_redis:6379/0 - CELERY_BROKER_URL=redis://${COMPOSE_PROJECT_NAME}_redis:6379/1 - CELERY_RESULT_BACKEND=redis://${COMPOSE_PROJECT_NAME}_redis:6379/2 - EMAIL_BACKEND=${EMAIL_BACKEND:-smtp} - EMAIL_HOST=${EMAIL_HOST} - EMAIL_PORT=${EMAIL_PORT:-2525} - EMAIL_USE_TLS=${EMAIL_USE_TLS:-True} - EMAIL_USE_SSL=${EMAIL_USE_SSL:-False} - EMAIL_HOST_USER=${EMAIL_HOST_USER} - EMAIL_HOST_PASSWORD=${EMAIL_HOST_PASSWORD} - DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL} - EMAIL_TIMEOUT=${EMAIL_TIMEOUT:-10} - FRONTEND_URL=${FRONTEND_URL} - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN} - TELEGRAM_USE_WEBHOOK=${TELEGRAM_USE_WEBHOOK:-False} - TELEGRAM_WEBHOOK_URL=${TELEGRAM_WEBHOOK_URL:-} - TELEGRAM_WEBHOOK_SECRET_TOKEN=${TELEGRAM_WEBHOOK_SECRET_TOKEN:-} volumes: - ./backend:/app depends_on: - db - redis - web networks: - app_network telegram-bot: build: context: ./backend dockerfile: Dockerfile container_name: ${COMPOSE_PROJECT_NAME}_telegram_bot restart: unless-stopped user: "0:0" env_file: .env command: python manage.py runtelegrambot environment: - DEBUG=${DEBUG:-False} - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${COMPOSE_PROJECT_NAME}_db:5432/${POSTGRES_DB} - REDIS_URL=redis://${COMPOSE_PROJECT_NAME}_redis:6379/0 - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN} - TELEGRAM_USE_WEBHOOK=${TELEGRAM_USE_WEBHOOK:-False} - TELEGRAM_WEBHOOK_URL=${TELEGRAM_WEBHOOK_URL:-} - TELEGRAM_WEBHOOK_SECRET_TOKEN=${TELEGRAM_WEBHOOK_SECRET_TOKEN:-} volumes: - ./backend:/app depends_on: - db - redis - web networks: - app_network livekit: image: livekit/livekit-server:latest container_name: ${COMPOSE_PROJECT_NAME}_livekit restart: unless-stopped command: ["/livekit-server", "--config", "/etc/livekit/livekit-config.yaml"] volumes: - ./docker/livekit/livekit-config.yaml:/etc/livekit/livekit-config.yaml:ro environment: - "LIVEKIT_KEYS=APIKeyPlatform2024Secret: ThisIsAVerySecureSecretKeyForPlatform2024VideoConf" ports: - "${LIVEKIT_PORT:-7880}:7880" - "${LIVEKIT_RTC_PORT:-7881}:7881" networks: - app_network nginx: image: nginx:alpine container_name: ${COMPOSE_PROJECT_NAME}_nginx restart: unless-stopped ports: - "${NGINX_PORT:-80}:80" volumes: - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./docker/nginx/conf.d:/etc/nginx/conf.d:ro depends_on: - web networks: - app_network front_material: build: context: ./front_material dockerfile: Dockerfile target: ${FRONTEND_BUILD_TARGET:-development} args: - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} - NEXT_PUBLIC_WS_URL=${NEXT_PUBLIC_WS_URL} - NEXT_PUBLIC_LIVEKIT_URL=${NEXT_PUBLIC_LIVEKIT_URL} - NEXT_PUBLIC_EXCALIDRAW_URL=${NEXT_PUBLIC_EXCALIDRAW_URL:-} container_name: ${COMPOSE_PROJECT_NAME}_front_material restart: unless-stopped volumes: - ./front_material:/app - /app/node_modules env_file: .env environment: - NODE_ENV=${NODE_ENV:-development} - HOSTNAME=0.0.0.0 - NEXT_PUBLIC_EXCALIDRAW_URL=${NEXT_PUBLIC_EXCALIDRAW_URL:-} - NEXT_PUBLIC_EXCALIDRAW_PATH=${NEXT_PUBLIC_EXCALIDRAW_PATH:-/excalidraw} ports: - "${FRONTEND_PORT:-3000}:3000" networks: - app_network front_minimal: build: context: ./front_minimal dockerfile: Dockerfile args: - VITE_SERVER_URL=${NEXT_PUBLIC_API_URL} - VITE_API_URL=${NEXT_PUBLIC_API_URL} - VITE_WS_URL=${NEXT_PUBLIC_WS_URL} - VITE_LIVEKIT_URL=${NEXT_PUBLIC_LIVEKIT_URL} - VITE_EXCALIDRAW_PATH=${NEXT_PUBLIC_EXCALIDRAW_PATH} container_name: ${COMPOSE_PROJECT_NAME}_front_minimal restart: unless-stopped volumes: - ./front_minimal:/app - /app/node_modules env_file: .env environment: - NODE_ENV=${NODE_ENV:-development} - HOST=0.0.0.0 ports: - "${FRONTEND_MINIMAL_PORT:-3005}:3000" networks: - app_network yjs-whiteboard: build: context: ./yjs-whiteboard-server dockerfile: Dockerfile container_name: ${COMPOSE_PROJECT_NAME}_yjs_whiteboard restart: unless-stopped ports: - "${YJS_PORT:-1234}:1234" networks: - app_network excalidraw: build: context: ./excalidraw-server dockerfile: Dockerfile args: - NEXT_PUBLIC_BASE_PATH=/devboard container_name: ${COMPOSE_PROJECT_NAME}_excalidraw restart: unless-stopped environment: - NODE_ENV=${NODE_ENV:-production} - NEXT_PUBLIC_BASE_PATH=/devboard ports: - "${EXCALIDRAW_PORT:-3001}:3001" networks: - app_network volumes: postgres_data: name: ${COMPOSE_PROJECT_NAME}_postgres_data redis_data: name: ${COMPOSE_PROJECT_NAME}_redis_data networks: app_network: name: ${COMPOSE_PROJECT_NAME}_network driver: bridge