Ctrl K
ComunidadGuías…

docker-compose.prod.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# niche-finder -- production overrides for a hosted copy (multi-user plan P1-13)
#
# Layered on top of docker-compose.yml, never used alone:
#   make prod-up
#   # = docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build \
#   #     postgres web worker mcp-http proxy backup
#
# What changes compared with a copy on your own machine (docs/hosting.md):
#   - Caddy (`proxy`) is the only thing published: ports 80 and 443 on
#     NF_DOMAIN, with a Let's Encrypt certificate it renews by itself. The
#     dashboard (8080) and Postgres (5433) are no longer published at all,
#     not even on 127.0.0.1.
#   - Accounts are on (NF_MULTI_USER=1), the sign-in cookie is Secure, the API
#     answers to NF_DOMAIN, and the request and sign-in limits count each
#     client by X-Forwarded-For from the proxy (NF_TRUSTED_PROXIES).
#   - MCP over HTTP runs all the time behind the same domain, at /mcp, and
#     accepts only personal API tokens.
#   - Logs are one JSON object per line (NF_LOG_FORMAT); /metrics on web
#     opens with NF_METRICS_TOKEN, for a Prometheus on the compose network.
#   - `backup` dumps the database every BACKUP_INTERVAL_HOURS into
#     BACKUP_DIR, checks that each dump restores, and keeps the newest
#     BACKUP_KEEP.
#
# Required in .env: NF_DOMAIN, POSTGRES_PASSWORD (compose refuses to start
# without them), YOUTUBE_API_KEY, OWN_TOKENS_KEY. Recommended:
# POSTGRES_APP_PASSWORD -- web and mcp-http then serve people's requests with a
# database login that Row-Level Security holds (it reaches them via env_file;
# the services set it up at start, docs/hosting.md). The checklist is in
# SECURITY.md, "What you have to do before you give anyone an account".

services:
  postgres:
    ports: !reset []
    environment:
      POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?set a strong POSTGRES_PASSWORD in .env}"

  web:
    ports: !reset []
    environment:
      NF_MULTI_USER: "1"
      NF_COOKIE_SECURE: "1"
      # NF_DOMAIN plus any extra names from .env's NF_ALLOWED_HOSTS (`web`,
      # how Prometheus reaches /metrics inside compose, is always allowed)
      NF_ALLOWED_HOSTS: "${NF_DOMAIN:?set NF_DOMAIN in .env, e.g. NF_DOMAIN=niches.example.com},${NF_ALLOWED_HOSTS:-}"
      NF_LOG_FORMAT: "${NF_LOG_FORMAT:-json}"
      # Only containers on this compose network can reach web:8080 (the port
      # is not published), so trusting Docker's private ranges means trusting
      # the proxy. Never '*'.
      NF_TRUSTED_PROXIES: "${NF_TRUSTED_PROXIES:-172.16.0.0/12,192.168.0.0/16}"

  worker:
    environment:
      NF_MULTI_USER: "1"
      NF_LOG_FORMAT: "${NF_LOG_FORMAT:-json}"

  mcp-http:
    profiles: !reset []
    environment:
      NF_MULTI_USER: "1"
      NF_LOG_FORMAT: "${NF_LOG_FORMAT:-json}"
      # tokens are required here; never start without them (P1-15)
      MCP_ALLOW_UNAUTHENTICATED: "0"
      MCP_PUBLIC_URL: "https://${NF_DOMAIN:?set NF_DOMAIN in .env}"

  proxy:
    image: caddy:2-alpine
    container_name: niche-finder-proxy
    restart: unless-stopped
    depends_on:
      - web
      - mcp-http
    environment:
      NF_DOMAIN: "${NF_DOMAIN:?set NF_DOMAIN in .env}"
    volumes:
      - ./infra/caddy/Caddyfile.prod:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"

  backup:
    # the database's own image, so pg_dump always matches the server version
    image: pgvector/pgvector:pg16
    container_name: niche-finder-backup
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    entrypoint: ["sh", "/backup.sh"]
    environment:
      PGHOST: postgres
      PGUSER: "${POSTGRES_USER:-niches}"
      PGPASSWORD: "${POSTGRES_PASSWORD:?set a strong POSTGRES_PASSWORD in .env}"
      PGDATABASE: "${POSTGRES_DB:-niches}"
      BACKUP_INTERVAL_HOURS: "${BACKUP_INTERVAL_HOURS:-24}"
      BACKUP_KEEP: "${BACKUP_KEEP:-14}"
      BACKUP_VERIFY: "${BACKUP_VERIFY:-1}"
      TZ: "${TZ:-Asia/Tashkent}"
    volumes:
      - ./infra/backup/backup.sh:/backup.sh:ro
      # a host folder, so the dumps are easy to copy off the server
      - "${BACKUP_DIR:-./backups}:/backups"