name: topsysops-app services: db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - db_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 10 backend: build: ./backend restart: unless-stopped depends_on: db: condition: service_healthy environment: DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} JWT_SECRET: ${JWT_SECRET} ADMIN_USERNAME: ${ADMIN_USERNAME} ADMIN_PASSWORD: ${ADMIN_PASSWORD} COOKIE_SECURE: ${COOKIE_SECURE:-true} PORT: 4000 OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-} OPENROUTER_MODEL: ${OPENROUTER_MODEL:-openai/gpt-4o-mini} PUBLIC_SITE_URL: ${PUBLIC_SITE_URL:-} # Next.js: публичный сайт + блог, с серверным рендерингом (SEO). nextjs: build: context: ./public-site args: NEXT_PUBLIC_SITE_URL: ${PUBLIC_SITE_URL:-https://top-sysops.ru} NEXT_PUBLIC_CHAT_PROVIDER: ${CHAT_PROVIDER:-none} NEXT_PUBLIC_TOPTICKET_WIDGET_URL: ${TOPTICKET_WIDGET_URL:-} NEXT_PUBLIC_TOPTICKET_WIDGET_KEY: ${TOPTICKET_WIDGET_KEY:-} NEXT_PUBLIC_CHATWOOT_BASE_URL: ${CHATWOOT_BASE_URL:-} NEXT_PUBLIC_CHATWOOT_WEBSITE_TOKEN: ${CHATWOOT_WEBSITE_TOKEN:-} restart: unless-stopped depends_on: - backend environment: # Внутренний адрес бэкенда по docker-сети - используется в Server Components # (SSR) для прямых запросов, в обход Caddy. BACKEND_INTERNAL_URL: http://backend:4000 NEXT_PUBLIC_SITE_URL: ${PUBLIC_SITE_URL:-https://top-sysops.ru} # Caddy: единственный сервис с портами наружу. Отдаёт статику admin-app # (/admin, /account), проксирует /api на backend, всё остальное - на nextjs. web: build: context: ./admin-app restart: unless-stopped depends_on: - backend - nextjs environment: DOMAIN: ${DOMAIN:-:80} ports: - "${HTTP_PORT:-80}:80" # Порт 443 контейнеру не нужен, если TLS терминирует внешний реверс-прокси # (например, Nginx Proxy Manager) - именно ваш случай. Строка закомментирована; # раскомментируйте её, только если хотите, чтобы Caddy сам получал # сертификат Let's Encrypt (тогда нужен реальный DOMAIN без схемы http://). # - "${HTTPS_PORT:-443}:443" volumes: - caddy_data:/data - caddy_config:/config volumes: db_data: caddy_data: caddy_config: