Files
TG_autoposter/docker-compose.prod.yml
2025-12-18 05:55:32 +09:00

392 lines
10 KiB
YAML

version: '3.8'
services:
# PostgreSQL Database with optimizations
postgres:
image: postgres:15-alpine
container_name: tg_autoposter_postgres_prod
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
POSTGRES_INITDB_ARGS: "-c shared_buffers=256MB -c max_connections=200 -c effective_cache_size=1GB"
volumes:
- postgres_data_prod:/var/lib/postgresql/data
- ./backups:/backups
ports:
- "5432:5432"
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
interval: 10s
timeout: 5s
retries: 10
start_period: 20s
restart: always
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '1'
memory: 512M
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
# Redis Cache with persistence
redis:
image: redis:7-alpine
container_name: tg_autoposter_redis_prod
command: >
redis-server
--requirepass ${REDIS_PASSWORD}
--appendonly yes
--appendfsync everysec
--maxmemory 512mb
--maxmemory-policy allkeys-lru
volumes:
- redis_data_prod:/data
ports:
- "6379:6379"
networks:
- backend
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 10s
timeout: 5s
retries: 10
start_period: 20s
restart: always
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
# Main Telegram Bot
bot:
image: ${DOCKER_USERNAME}/tg-autoposter:latest
container_name: tg_autoposter_bot_prod
build:
context: .
dockerfile: Dockerfile
environment:
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_API_ID=${TELEGRAM_API_ID}
- TELEGRAM_API_HASH=${TELEGRAM_API_HASH}
- ADMIN_ID=${ADMIN_ID}
- DB_HOST=postgres
- DB_PORT=5432
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_DB=0
- REDIS_PASSWORD=${REDIS_PASSWORD}
- CELERY_BROKER_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
- CELERY_RESULT_BACKEND_URL=redis://:${REDIS_PASSWORD}@redis:6379/1
- LOG_LEVEL=INFO
- DEBUG=False
volumes:
- ./logs:/app/logs
- ./sessions:/app/sessions
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- backend
restart: always
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
# Celery Worker - Message Queue (4 concurrent)
celery_worker_send:
image: ${DOCKER_USERNAME}/tg-autoposter:latest
container_name: tg_autoposter_worker_send_prod
build:
context: .
dockerfile: Dockerfile
command: celery -A app.celery_config worker -Q messages -n worker_send@%h -c 4 -l info --max-tasks-per-child=500 --without-gossip --without-mingle --without-heartbeat
environment:
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_API_ID=${TELEGRAM_API_ID}
- TELEGRAM_API_HASH=${TELEGRAM_API_HASH}
- ADMIN_ID=${ADMIN_ID}
- DB_HOST=postgres
- DB_PORT=5432
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_DB=0
- REDIS_PASSWORD=${REDIS_PASSWORD}
- CELERY_BROKER_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
- CELERY_RESULT_BACKEND_URL=redis://:${REDIS_PASSWORD}@redis:6379/1
- LOG_LEVEL=INFO
volumes:
- ./logs:/app/logs
- ./sessions:/app/sessions
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- backend
restart: always
deploy:
replicas: 2
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
update_config:
parallelism: 1
delay: 10s
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
# Celery Worker - Parsing Queue (2 concurrent)
celery_worker_parse:
image: ${DOCKER_USERNAME}/tg-autoposter:latest
container_name: tg_autoposter_worker_parse_prod
command: celery -A app.celery_config worker -Q parsing -n worker_parse@%h -c 2 -l info --max-tasks-per-child=100 --without-gossip --without-mingle --without-heartbeat
environment:
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_API_ID=${TELEGRAM_API_ID}
- TELEGRAM_API_HASH=${TELEGRAM_API_HASH}
- ADMIN_ID=${ADMIN_ID}
- DB_HOST=postgres
- DB_PORT=5432
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_DB=0
- REDIS_PASSWORD=${REDIS_PASSWORD}
- CELERY_BROKER_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
- CELERY_RESULT_BACKEND_URL=redis://:${REDIS_PASSWORD}@redis:6379/1
- LOG_LEVEL=INFO
volumes:
- ./logs:/app/logs
- ./sessions:/app/sessions
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- backend
restart: always
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
# Celery Worker - Maintenance Queue (1 concurrent)
celery_worker_maintenance:
image: ${DOCKER_USERNAME}/tg-autoposter:latest
container_name: tg_autoposter_worker_maintenance_prod
command: celery -A app.celery_config worker -Q maintenance -n worker_maintenance@%h -c 1 -l info --max-tasks-per-child=50 --without-gossip --without-mingle --without-heartbeat
environment:
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_API_ID=${TELEGRAM_API_ID}
- TELEGRAM_API_HASH=${TELEGRAM_API_HASH}
- ADMIN_ID=${ADMIN_ID}
- DB_HOST=postgres
- DB_PORT=5432
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_DB=0
- REDIS_PASSWORD=${REDIS_PASSWORD}
- CELERY_BROKER_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
- CELERY_RESULT_BACKEND_URL=redis://:${REDIS_PASSWORD}@redis:6379/1
- LOG_LEVEL=INFO
volumes:
- ./logs:/app/logs
- ./sessions:/app/sessions
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- backend
restart: always
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
# Celery Beat - Task Scheduler
celery_beat:
image: ${DOCKER_USERNAME}/tg-autoposter:latest
container_name: tg_autoposter_beat_prod
command: celery -A app.celery_config beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
environment:
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_API_ID=${TELEGRAM_API_ID}
- TELEGRAM_API_HASH=${TELEGRAM_API_HASH}
- ADMIN_ID=${ADMIN_ID}
- DB_HOST=postgres
- DB_PORT=5432
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_DB=0
- REDIS_PASSWORD=${REDIS_PASSWORD}
- CELERY_BROKER_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
- CELERY_RESULT_BACKEND_URL=redis://:${REDIS_PASSWORD}@redis:6379/1
- LOG_LEVEL=INFO
volumes:
- ./logs:/app/logs
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- backend
restart: always
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
# Flower - Celery Monitoring
flower:
image: mher/flower:2.0.1
container_name: tg_autoposter_flower_prod
command: celery -A app.celery_config flower --port=5555 --basic_auth=admin:${FLOWER_PASSWORD}
environment:
CELERY_BROKER_URL: redis://:${REDIS_PASSWORD}@redis:6379/0
CELERY_RESULT_BACKEND: redis://:${REDIS_PASSWORD}@redis:6379/1
ports:
- "5555:5555"
depends_on:
redis:
condition: service_healthy
networks:
- backend
restart: always
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
# Optional: Prometheus for metrics collection
prometheus:
image: prom/prometheus:latest
container_name: tg_autoposter_prometheus_prod
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
networks:
- backend
restart: always
deploy:
resources:
limits:
cpus: '1'
memory: 512M
volumes:
postgres_data_prod:
driver: local
redis_data_prod:
driver: local
prometheus_data:
driver: local
networks:
backend:
driver: bridge
driver_opts:
com.docker.network.bridge.name: br_tg_autoposter
ipam:
config:
- subnet: 172.20.0.0/16