services: db: image: postgres:17 container_name: vpn-bot-postgres restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-vpnbot} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-vpnbot} POSTGRES_DB: ${POSTGRES_DB:-vpnbot} volumes: - pgdata:/var/lib/postgresql/data networks: - bot-net healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-vpnbot} -d ${POSTGRES_DB:-vpnbot}"] interval: 5s timeout: 5s retries: 10 bot: build: . container_name: vpn-telegram-bot env_file: - .env environment: REMNAWAVE_BASE_URL: ${REMNAWAVE_BASE_URL} REMNAWAVE_TOKEN: ${REMNAWAVE_TOKEN} REMNAWAVE_USERNAME: ${REMNAWAVE_USERNAME:-} REMNAWAVE_PASSWORD: ${REMNAWAVE_PASSWORD:-} CADDY_TOKEN: ${CADDY_TOKEN:-} BOT_TOKEN: ${BOT_TOKEN} ADMIN_IDS: ${ADMIN_IDS:-} # Платежи / Stars / TOPUP_CODE_PAY_URL — только из env_file (.env), # чтобы админка могла писать ключи без перетирания пустыми ${...:-} DATABASE_URL: postgresql://${POSTGRES_USER:-vpnbot}:${POSTGRES_PASSWORD:-vpnbot}@db:5432/${POSTGRES_DB:-vpnbot} POSTGRES_HOST: db POSTGRES_PORT: "5432" POSTGRES_USER: ${POSTGRES_USER:-vpnbot} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-vpnbot} POSTGRES_DB: ${POSTGRES_DB:-vpnbot} TARIFFS_PATH: /app/tariffs.json ENV_FILE: /app/.env WEBAPP_URL: ${WEBAPP_URL} WEBAPP_HOST: 0.0.0.0 WEBAPP_PORT: "8080" # WEB_ADMIN_* — только из env_file (.env), без ${...:-} expose: - "8080" volumes: - ./.env:/app/.env:rw - ./tariffs.json:/app/tariffs.json:rw - ./webapp:/app/webapp:ro - ./backups:/app/backups networks: - bot-net depends_on: db: condition: service_healthy restart: unless-stopped command: ["python", "bot.py"] caddy: image: caddy:2.9 container_name: vpn-bot-caddy restart: unless-stopped ports: - "80:80" - "443:443" - "443:443/udp" environment: WEBAPP_DOMAIN: ${WEBAPP_DOMAIN:-bot.example.com} volumes: - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro - caddy-data:/data - caddy-config:/config networks: - bot-net depends_on: - bot networks: bot-net: name: bot-net driver: bridge volumes: pgdata: caddy-data: caddy-config: