285 lines
9.9 KiB
YAML
285 lines
9.9 KiB
YAML
# ==============================================
|
||
# Docker Compose PROD (порты не пересекаются с dev на одном хосте)
|
||
# ==============================================
|
||
# Порты на хосте (prod): db 5434, redis 6381, web 8123, nginx 8084,
|
||
# front_material 3010, yjs 1236, excalidraw 3004, whiteboard 8083,
|
||
# livekit 7880/7881, celery/beat — без портов (внутренние)
|
||
# Dev использует: 5433, 6380, 8124, 8081, 3002, 1235, 3003, 8082, livekit 7890/7891
|
||
|
||
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:
|
||
- dev_network
|
||
|
||
redis:
|
||
image: redis:7-alpine
|
||
container_name: platform_prod_redis
|
||
restart: unless-stopped
|
||
ports:
|
||
- "6381:6379"
|
||
volumes:
|
||
- prod_redis_data:/data
|
||
networks:
|
||
- dev_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:-True}
|
||
- SECRET_KEY=dev_secret_key
|
||
- ALLOWED_HOSTS=api.uchill.online,app.uchill.online,uchill.online,www.uchill.online,localhost,127.0.0.1,85.192.56.185
|
||
- DATABASE_URL=postgresql://platform_prod_user:platform_prod_password@db:5432/platform_prod_db
|
||
- REDIS_URL=redis://redis:6379/0
|
||
- CELERY_BROKER_URL=redis://redis:6379/1
|
||
- CELERY_RESULT_BACKEND=redis://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:
|
||
- dev_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:-True}
|
||
- DATABASE_URL=postgresql://platform_prod_user:platform_prod_password@db:5432/platform_prod_db
|
||
- REDIS_URL=redis://redis:6379/0
|
||
- CELERY_BROKER_URL=redis://redis:6379/1
|
||
- CELERY_RESULT_BACKEND=redis://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:
|
||
- dev_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:-True}
|
||
- DATABASE_URL=postgresql://platform_prod_user:platform_prod_password@db:5432/platform_prod_db
|
||
- REDIS_URL=redis://redis:6379/0
|
||
- CELERY_BROKER_URL=redis://redis:6379/1
|
||
- CELERY_RESULT_BACKEND=redis://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:
|
||
- dev_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:-True}
|
||
- DATABASE_URL=postgresql://platform_prod_user:platform_prod_password@db:5432/platform_prod_db
|
||
- REDIS_URL=redis://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:
|
||
- dev_network
|
||
|
||
# Видеоуроки: хост nginx (api.uchill.online) проксирует /livekit на 7880. Dev на том же хосте — 7890.
|
||
# LIVEKIT_KEYS — строго один ключ в формате "key: secret" (пробел после двоеточия). В .env задайте одну строку: LIVEKIT_KEYS=APIKeyPlatform2024Secret: ThisIsAVerySecureSecretKeyForPlatform2024VideoConf
|
||
livekit:
|
||
image: livekit/livekit-server:latest
|
||
container_name: platform_prod_livekit
|
||
restart: unless-stopped
|
||
environment:
|
||
# Одна строка "key: secret" (пробел после двоеточия). В кавычках, чтобы YAML не воспринял двоеточие как ключ.
|
||
- "LIVEKIT_KEYS=APIKeyPlatform2024Secret: ThisIsAVerySecureSecretKeyForPlatform2024VideoConf"
|
||
ports:
|
||
- "7880:7880"
|
||
- "7881:7881"
|
||
networks:
|
||
- dev_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:
|
||
- dev_network
|
||
|
||
front_material:
|
||
build:
|
||
context: ./front_material
|
||
dockerfile: Dockerfile
|
||
target: development
|
||
container_name: platform_prod_front_material
|
||
restart: unless-stopped
|
||
env_file: .env
|
||
environment:
|
||
- NODE_ENV=development
|
||
- WATCHPACK_POLLING=true
|
||
- HOSTNAME=0.0.0.0
|
||
- CHOKIDAR_USEPOLLING=true
|
||
# Доска: поддомен 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"
|
||
volumes:
|
||
- ./front_material:/app
|
||
- front_material_node_modules:/app/node_modules
|
||
- front_material_next:/app/.next
|
||
networks:
|
||
- dev_network
|
||
|
||
yjs-whiteboard:
|
||
build:
|
||
context: ./yjs-whiteboard-server
|
||
dockerfile: Dockerfile
|
||
container_name: platform_prod_yjs_whiteboard
|
||
restart: unless-stopped
|
||
ports:
|
||
- "1236:1234"
|
||
networks:
|
||
- dev_network
|
||
|
||
excalidraw:
|
||
build:
|
||
context: ./excalidraw-server
|
||
dockerfile: Dockerfile
|
||
container_name: platform_prod_excalidraw
|
||
restart: unless-stopped
|
||
environment:
|
||
# basePath в next.config.js: иначе /_next/ запросы уходят на основной фронт и доска пустая
|
||
- NEXT_PUBLIC_BASE_PATH=/excalidraw
|
||
ports:
|
||
- "3004:3001"
|
||
networks:
|
||
- dev_network
|
||
|
||
whiteboard:
|
||
build:
|
||
context: ./whiteboard-server
|
||
dockerfile: Dockerfile
|
||
container_name: platform_prod_whiteboard
|
||
restart: unless-stopped
|
||
ports:
|
||
- "8083:8080"
|
||
networks:
|
||
- dev_network
|
||
|
||
volumes:
|
||
prod_postgres_data:
|
||
prod_redis_data:
|
||
front_material_node_modules:
|
||
front_material_next:
|
||
|
||
networks:
|
||
dev_network:
|
||
driver: bridge
|