292 lines
11 KiB
YAML
292 lines
11 KiB
YAML
# ==============================================
|
||
# Docker Compose PROD (порты не пересекаются с dev на одном хосте)
|
||
# ==============================================
|
||
# Порты на хосте (prod): db 5434, redis 6381, web 8123, nginx 8084,
|
||
# front_material 3010, yjs 1236, excalidraw 3004, livekit 7880/7881,
|
||
# celery/beat — без портов (внутренние)
|
||
# Dev использует: 5433, 6380, 8124, 8081, 3002, 1235, 3003, 8082, livekit 7890/7891
|
||
#
|
||
# ВАЖНО: PROD использует отдельную сеть (prod_network) и именованные volumes
|
||
# НЕ используйте: docker compose down --volumes (удалит данные БД!)
|
||
# Используйте: docker compose down (остановит контейнеры, сохранит volumes)
|
||
# Для полной очистки: сначала сделайте бэкап БД, затем docker compose down --volumes
|
||
|
||
services:
|
||
db:
|
||
image: postgres:16-alpine
|
||
container_name: platform_prod_db
|
||
restart: unless-stopped
|
||
environment:
|
||
POSTGRES_DB: platform_prod_db
|
||
POSTGRES_USER: platform_prod_user
|
||
POSTGRES_PASSWORD: platform_prod_password
|
||
ports:
|
||
- "5434:5432"
|
||
volumes:
|
||
- prod_postgres_data:/var/lib/postgresql/data
|
||
networks:
|
||
- prod_network
|
||
|
||
redis:
|
||
image: redis:7-alpine
|
||
container_name: platform_prod_redis
|
||
restart: unless-stopped
|
||
ports:
|
||
- "6381:6379"
|
||
volumes:
|
||
- prod_redis_data:/data
|
||
networks:
|
||
- prod_network
|
||
|
||
web:
|
||
build:
|
||
context: ./backend
|
||
dockerfile: Dockerfile
|
||
container_name: platform_prod_web
|
||
restart: unless-stopped
|
||
user: "0:0"
|
||
env_file: .env
|
||
# Daphne (ASGI): HTTP + WebSocket (/ws/notifications/, /ws/chat/, /ws/board/ и т.д.)
|
||
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://platform_prod_user:platform_prod_password@platform_prod_db:5432/platform_prod_db
|
||
- REDIS_URL=redis://platform_prod_redis:6379/0
|
||
- CELERY_BROKER_URL=redis://platform_prod_redis:6379/1
|
||
- CELERY_RESULT_BACKEND=redis://platform_prod_redis:6379/2
|
||
# Явно передаём переменные почты из .env (иначе контейнер может не видеть их)
|
||
- 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}
|
||
# Ссылки в письмах (сброс пароля, подтверждение, приглашения) — без localhost
|
||
- FRONTEND_URL=${FRONTEND_URL:-https://app.uchill.online}
|
||
# LiveKit: публичный URL для браузера (обязательно в prod — иначе клиент идёт на 127.0.0.1)
|
||
- LIVEKIT_PUBLIC_URL=${LIVEKIT_PUBLIC_URL:-wss://api.uchill.online/livekit}
|
||
# Telegram бот (профиль: bot-info, привязка аккаунта)
|
||
- 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:
|
||
- "8123:8000"
|
||
volumes:
|
||
- ./backend:/app
|
||
depends_on:
|
||
- db
|
||
- redis
|
||
networks:
|
||
- prod_network
|
||
|
||
celery:
|
||
build:
|
||
context: ./backend
|
||
dockerfile: Dockerfile
|
||
container_name: platform_prod_celery
|
||
restart: unless-stopped
|
||
user: "0:0"
|
||
env_file: .env
|
||
command: celery -A config worker -l info
|
||
environment:
|
||
- DEBUG=${DEBUG:-False}
|
||
- DATABASE_URL=postgresql://platform_prod_user:platform_prod_password@platform_prod_db:5432/platform_prod_db
|
||
- REDIS_URL=redis://platform_prod_redis:6379/0
|
||
- CELERY_BROKER_URL=redis://platform_prod_redis:6379/1
|
||
- CELERY_RESULT_BACKEND=redis://platform_prod_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:-https://app.uchill.online}
|
||
- 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:
|
||
- prod_network
|
||
|
||
celery-beat:
|
||
build:
|
||
context: ./backend
|
||
dockerfile: Dockerfile
|
||
container_name: platform_prod_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://platform_prod_user:platform_prod_password@platform_prod_db:5432/platform_prod_db
|
||
- REDIS_URL=redis://platform_prod_redis:6379/0
|
||
- CELERY_BROKER_URL=redis://platform_prod_redis:6379/1
|
||
- CELERY_RESULT_BACKEND=redis://platform_prod_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:-https://app.uchill.online}
|
||
- 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:
|
||
- prod_network
|
||
|
||
# Telegram бот (polling): получает /start, /link <код> и т.д. Если используете webhook — не поднимайте этот сервис.
|
||
telegram-bot:
|
||
build:
|
||
context: ./backend
|
||
dockerfile: Dockerfile
|
||
container_name: platform_prod_telegram_bot
|
||
restart: unless-stopped
|
||
user: "0:0"
|
||
env_file: .env
|
||
command: python manage.py runtelegrambot
|
||
environment:
|
||
- DEBUG=${DEBUG:-False}
|
||
- DATABASE_URL=postgresql://platform_prod_user:platform_prod_password@platform_prod_db:5432/platform_prod_db
|
||
- REDIS_URL=redis://platform_prod_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:
|
||
- prod_network
|
||
|
||
# Видеоуроки: 2K, высокий битрейт. Nginx проксирует /livekit на 7880.
|
||
# Конфиг: docker/livekit/livekit-config.yaml (буферы под 2K, RTC).
|
||
livekit:
|
||
image: livekit/livekit-server:latest
|
||
container_name: platform_prod_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:
|
||
# Переопределение ключей через env (опционально)
|
||
- "LIVEKIT_KEYS=APIKeyPlatform2024Secret: ThisIsAVerySecureSecretKeyForPlatform2024VideoConf"
|
||
ports:
|
||
- "7880:7880"
|
||
- "7881:7881"
|
||
networks:
|
||
- prod_network
|
||
|
||
nginx:
|
||
image: nginx:alpine
|
||
container_name: platform_prod_nginx
|
||
restart: unless-stopped
|
||
ports:
|
||
- "8084:80"
|
||
volumes:
|
||
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||
- ./docker/nginx/conf.d:/etc/nginx/conf.d:ro
|
||
depends_on:
|
||
- web
|
||
networks:
|
||
- prod_network
|
||
|
||
front_material:
|
||
build:
|
||
context: ./front_material
|
||
dockerfile: Dockerfile
|
||
target: production
|
||
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: platform_prod_front_material
|
||
restart: unless-stopped
|
||
env_file: .env
|
||
environment:
|
||
- NODE_ENV=production
|
||
- HOSTNAME=0.0.0.0
|
||
# Доска: поддомен board.uchill.online (прокси nginx на 3004) или путь на том же домене
|
||
- NEXT_PUBLIC_EXCALIDRAW_URL=${NEXT_PUBLIC_EXCALIDRAW_URL:-}
|
||
- NEXT_PUBLIC_EXCALIDRAW_PATH=${NEXT_PUBLIC_EXCALIDRAW_PATH:-/excalidraw}
|
||
ports:
|
||
- "3010:3000"
|
||
networks:
|
||
- prod_network
|
||
|
||
yjs-whiteboard:
|
||
build:
|
||
context: ./yjs-whiteboard-server
|
||
dockerfile: Dockerfile
|
||
container_name: platform_prod_yjs_whiteboard
|
||
restart: unless-stopped
|
||
ports:
|
||
- "1236:1234"
|
||
networks:
|
||
- prod_network
|
||
|
||
excalidraw:
|
||
build:
|
||
context: ./excalidraw-server
|
||
dockerfile: Dockerfile
|
||
target: production
|
||
container_name: platform_prod_excalidraw
|
||
restart: unless-stopped
|
||
environment:
|
||
- NODE_ENV=production
|
||
# Поддомен board.uchill.online: basePath не нужен (приложение на корне поддомена)
|
||
- NEXT_PUBLIC_BASE_PATH=
|
||
ports:
|
||
- "3004:3001"
|
||
networks:
|
||
- prod_network
|
||
|
||
volumes:
|
||
# ВАЖНО: Эти volumes содержат данные БД и Redis
|
||
# НЕ используйте docker compose down --volumes без бэкапа!
|
||
prod_postgres_data:
|
||
name: platform_prod_postgres_data
|
||
prod_redis_data:
|
||
name: platform_prod_redis_data
|
||
front_material_node_modules:
|
||
name: platform_prod_front_material_node_modules
|
||
front_material_next:
|
||
name: platform_prod_front_material_next
|
||
|
||
networks:
|
||
prod_network:
|
||
name: platform_prod_network
|
||
driver: bridge
|