This commit is contained in:
talorr
2026-03-27 03:36:08 +03:00
parent 8a97ce6d54
commit cda36918e8
225 changed files with 35641 additions and 0 deletions

354
docker-compose.yml Normal file
View File

@@ -0,0 +1,354 @@
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
restart: unless-stopped
chat-postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${CHAT_POSTGRES_DB}
POSTGRES_USER: ${CHAT_POSTGRES_USER}
POSTGRES_PASSWORD: ${CHAT_POSTGRES_PASSWORD}
volumes:
- chat_postgres_data:/var/lib/postgresql/data
postgres-backup:
image: postgres:16-alpine
restart: unless-stopped
depends_on:
- postgres
- chat-postgres
environment:
TZ: ${BACKUP_TZ:-Europe/Moscow}
BACKUP_DIR: /backups
BACKUP_INTERVAL_SECONDS: ${BACKUP_INTERVAL_SECONDS:-86400}
BACKUP_RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-7}
BACKUP_GZIP_LEVEL: ${BACKUP_GZIP_LEVEL:-6}
BACKUP_INCLUDE_CHAT_DB: ${BACKUP_INCLUDE_CHAT_DB:-true}
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
CHAT_POSTGRES_HOST: chat-postgres
CHAT_POSTGRES_PORT: 5432
CHAT_POSTGRES_DB: ${CHAT_POSTGRES_DB}
CHAT_POSTGRES_USER: ${CHAT_POSTGRES_USER}
CHAT_POSTGRES_PASSWORD: ${CHAT_POSTGRES_PASSWORD}
command: ["/bin/sh", "/scripts/pg-backup.sh"]
volumes:
- ./scripts/pg-backup.sh:/scripts/pg-backup.sh:ro
- ./backups:/backups
adminer:
image: adminer:5
restart: unless-stopped
depends_on:
- postgres
expose:
- "8080"
networks:
- default
- proxy
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.routers.alpinbet-adminer.rule=Host(`db.antigol.ru`)
- traefik.http.routers.alpinbet-adminer.entrypoints=websecure
- traefik.http.routers.alpinbet-adminer.tls.certresolver=letsencrypt
- traefik.http.services.alpinbet-adminer.loadbalancer.server.port=8080
dockmon:
image: darthnorse/dockmon:latest
restart: unless-stopped
environment:
TZ: Europe/Moscow
PYTHONPATH: /app/backend
PYTHONUNBUFFERED: 1
REVERSE_PROXY_MODE: "true"
DOCKMON_EXTERNAL_URL: https://monitor.antigol.ru
DOCKMON_CORS_ORIGINS: https://monitor.antigol.ru
expose:
- "80"
volumes:
- dockmon_data:/app/data
- /var/run/docker.sock:/var/run/docker.sock
networks:
- default
- proxy
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.routers.alpinbet-dockmon.rule=Host(`monitor.antigol.ru`)
- traefik.http.routers.alpinbet-dockmon.entrypoints=websecure
- traefik.http.routers.alpinbet-dockmon.tls.certresolver=letsencrypt
- traefik.http.services.alpinbet-dockmon.loadbalancer.server.port=80
backend:
build:
context: ./backend
restart: unless-stopped
depends_on:
- postgres
- redis
command: npm run start:api:with-db-url
environment:
REDIS_URL: redis://redis:6379
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_SCHEMA: public
PORT: 4000
JWT_SECRET: ${JWT_SECRET}
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
CORS_ORIGIN: ${CORS_ORIGIN}
APP_PUBLIC_URL: ${APP_PUBLIC_URL}
SMTP_HOST: ${SMTP_HOST:-}
SMTP_PORT: ${SMTP_PORT:-587}
SMTP_SECURE: ${SMTP_SECURE:-false}
SMTP_USER: ${SMTP_USER:-}
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
SMTP_FROM_EMAIL: ${SMTP_FROM_EMAIL:-}
SMTP_FROM_NAME: ${SMTP_FROM_NAME:-Alpinbet}
PASSWORD_RESET_TTL_MINUTES: ${PASSWORD_RESET_TTL_MINUTES:-60}
APP_LATEST_VERSION: ${APP_LATEST_VERSION:-}
APP_MIN_SUPPORTED_VERSION: ${APP_MIN_SUPPORTED_VERSION:-}
APP_UPDATE_URL: ${APP_UPDATE_URL:-}
APP_UPDATE_MESSAGE: ${APP_UPDATE_MESSAGE:-}
VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY:-}
VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY:-}
VAPID_SUBJECT: ${VAPID_SUBJECT:-mailto:admin@example.com}
FIREBASE_PROJECT_ID: ${FIREBASE_PROJECT_ID:-}
FIREBASE_CLIENT_EMAIL: ${FIREBASE_CLIENT_EMAIL:-}
FIREBASE_PRIVATE_KEY: ${FIREBASE_PRIVATE_KEY:-}
FIREBASE_SERVICE_ACCOUNT_JSON: ${FIREBASE_SERVICE_ACCOUNT_JSON:-}
SETTLEMENT_INTERVAL_MS: ${SETTLEMENT_INTERVAL_MS:-60000}
PARSER_INTERNAL_SECRET: ${PARSER_INTERNAL_SECRET}
VAPID_STATE_DIR: /app/runtime
expose:
- "4000"
volumes:
- backend_runtime:/app/runtime
networks:
- default
- proxy
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.routers.alpinbet-backend.rule=Host(`api.antigol.ru`)
- traefik.http.routers.alpinbet-backend.entrypoints=websecure
- traefik.http.routers.alpinbet-backend.tls.certresolver=letsencrypt
- traefik.http.services.alpinbet-backend.loadbalancer.server.port=4000
backend-signals-worker:
build:
context: ./backend
restart: unless-stopped
depends_on:
- postgres
- redis
command: npm run start:signals-worker:with-db-url
environment:
REDIS_URL: redis://redis:6379
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_SCHEMA: public
PORT: 4000
JWT_SECRET: ${JWT_SECRET}
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
CORS_ORIGIN: ${CORS_ORIGIN}
APP_PUBLIC_URL: ${APP_PUBLIC_URL}
SMTP_HOST: ${SMTP_HOST:-}
SMTP_PORT: ${SMTP_PORT:-587}
SMTP_SECURE: ${SMTP_SECURE:-false}
SMTP_USER: ${SMTP_USER:-}
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
SMTP_FROM_EMAIL: ${SMTP_FROM_EMAIL:-}
SMTP_FROM_NAME: ${SMTP_FROM_NAME:-Alpinbet}
PASSWORD_RESET_TTL_MINUTES: ${PASSWORD_RESET_TTL_MINUTES:-60}
APP_LATEST_VERSION: ${APP_LATEST_VERSION:-}
APP_MIN_SUPPORTED_VERSION: ${APP_MIN_SUPPORTED_VERSION:-}
APP_UPDATE_URL: ${APP_UPDATE_URL:-}
APP_UPDATE_MESSAGE: ${APP_UPDATE_MESSAGE:-}
VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY:-}
VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY:-}
VAPID_SUBJECT: ${VAPID_SUBJECT:-mailto:admin@example.com}
FIREBASE_PROJECT_ID: ${FIREBASE_PROJECT_ID:-}
FIREBASE_CLIENT_EMAIL: ${FIREBASE_CLIENT_EMAIL:-}
FIREBASE_PRIVATE_KEY: ${FIREBASE_PRIVATE_KEY:-}
FIREBASE_SERVICE_ACCOUNT_JSON: ${FIREBASE_SERVICE_ACCOUNT_JSON:-}
SETTLEMENT_INTERVAL_MS: ${SETTLEMENT_INTERVAL_MS:-60000}
PARSER_INTERNAL_SECRET: ${PARSER_INTERNAL_SECRET}
VAPID_STATE_DIR: /app/runtime
volumes:
- backend_runtime:/app/runtime
backend-push-worker:
build:
context: ./backend
restart: unless-stopped
depends_on:
- postgres
- redis
command: npm run start:push-worker:with-db-url
environment:
REDIS_URL: redis://redis:6379
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_SCHEMA: public
PORT: 4000
JWT_SECRET: ${JWT_SECRET}
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
CORS_ORIGIN: ${CORS_ORIGIN}
APP_PUBLIC_URL: ${APP_PUBLIC_URL}
SMTP_HOST: ${SMTP_HOST:-}
SMTP_PORT: ${SMTP_PORT:-587}
SMTP_SECURE: ${SMTP_SECURE:-false}
SMTP_USER: ${SMTP_USER:-}
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
SMTP_FROM_EMAIL: ${SMTP_FROM_EMAIL:-}
SMTP_FROM_NAME: ${SMTP_FROM_NAME:-Alpinbet}
PASSWORD_RESET_TTL_MINUTES: ${PASSWORD_RESET_TTL_MINUTES:-60}
APP_LATEST_VERSION: ${APP_LATEST_VERSION:-}
APP_MIN_SUPPORTED_VERSION: ${APP_MIN_SUPPORTED_VERSION:-}
APP_UPDATE_URL: ${APP_UPDATE_URL:-}
APP_UPDATE_MESSAGE: ${APP_UPDATE_MESSAGE:-}
VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY:-}
VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY:-}
VAPID_SUBJECT: ${VAPID_SUBJECT:-mailto:admin@example.com}
FIREBASE_PROJECT_ID: ${FIREBASE_PROJECT_ID:-}
FIREBASE_CLIENT_EMAIL: ${FIREBASE_CLIENT_EMAIL:-}
FIREBASE_PRIVATE_KEY: ${FIREBASE_PRIVATE_KEY:-}
FIREBASE_SERVICE_ACCOUNT_JSON: ${FIREBASE_SERVICE_ACCOUNT_JSON:-}
SETTLEMENT_INTERVAL_MS: ${SETTLEMENT_INTERVAL_MS:-60000}
PARSER_INTERNAL_SECRET: ${PARSER_INTERNAL_SECRET}
VAPID_STATE_DIR: /app/runtime
volumes:
- backend_runtime:/app/runtime
chat-service:
build:
context: ./chat-service
restart: unless-stopped
depends_on:
- chat-postgres
command: npm run start:with-db-url
environment:
CHAT_POSTGRES_HOST: chat-postgres
CHAT_POSTGRES_PORT: 5432
CHAT_POSTGRES_DB: ${CHAT_POSTGRES_DB}
CHAT_POSTGRES_USER: ${CHAT_POSTGRES_USER}
CHAT_POSTGRES_PASSWORD: ${CHAT_POSTGRES_PASSWORD}
CHAT_POSTGRES_SCHEMA: public
PORT: 4050
JWT_SECRET: ${JWT_SECRET}
CORS_ORIGIN: ${CORS_ORIGIN}
expose:
- "4050"
networks:
- default
- proxy
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.routers.alpinbet-chat.rule=Host(`chat.antigol.ru`)
- traefik.http.routers.alpinbet-chat.entrypoints=websecure
- traefik.http.routers.alpinbet-chat.tls.certresolver=letsencrypt
- traefik.http.services.alpinbet-chat.loadbalancer.server.port=4050
parser:
build:
context: .
dockerfile: ./parser/Dockerfile
depends_on:
- redis
- forecast-ocr
command: npm run start
env_file:
- ./parser/.env
environment:
REDIS_URL: redis://redis:6379
BACKEND_INTERNAL_URL: http://backend:4000
PARSER_INTERNAL_SECRET: ${PARSER_INTERNAL_SECRET}
FORECAST_OCR_URL: http://forecast-ocr:4010
volumes:
- ./parser/data:/app/parser/data
restart: unless-stopped
forecast-ocr:
build:
context: ./forecast-ocr-service
restart: unless-stopped
expose:
- "4010"
frontend:
build:
context: ./frontend
depends_on:
- backend
- chat-service
environment:
NUXT_PUBLIC_API_BASE: ${NUXT_PUBLIC_API_BASE}
NUXT_PUBLIC_CHAT_API_BASE: ${NUXT_PUBLIC_CHAT_API_BASE}
NUXT_API_BASE_INTERNAL: http://backend:4000
expose:
- "3000"
networks:
- default
- proxy
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.routers.alpinbet-frontend.rule=Host(`antigol.ru`)
- traefik.http.routers.alpinbet-frontend.entrypoints=websecure
- traefik.http.routers.alpinbet-frontend.tls.certresolver=letsencrypt
- traefik.http.services.alpinbet-frontend.loadbalancer.server.port=3000
downloads:
build:
context: ./downloads-service
restart: unless-stopped
expose:
- "8080"
volumes:
- ./downloads:/app/downloads:ro
networks:
- default
- proxy
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.http.routers.alpinbet-downloads.rule=Host(`files.antigol.ru`)
- traefik.http.routers.alpinbet-downloads.entrypoints=websecure
- traefik.http.routers.alpinbet-downloads.tls.certresolver=letsencrypt
- traefik.http.services.alpinbet-downloads.loadbalancer.server.port=8080
volumes:
postgres_data:
chat_postgres_data:
backend_runtime:
dockmon_data:
networks:
proxy:
external: true