Ctrl K
ComunidadGuías…

docker-compose.yml

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

Archivo original ↗Preguntar a KiBot
# Self-hosted Aglyn (AGL-905): the console (management UI) and the tenant
# runtime (serves published sites) as two containers.
#
#   cp .env.selfhost.example .env.selfhost   # fill it in — see docs/SELF_HOSTING.md
#   docker compose up --build
#
# The env file is used twice: as a BuildKit secret during the image build
# (Next.js inlines NEXT_PUBLIC_* into the client bundles) and as runtime env
# for the server-side secrets. Rebuild the images whenever a NEXT_PUBLIC_*
# value changes — runtime env alone cannot update the client bundle.
#
# In front of these, run your own reverse proxy (Caddy/nginx/Traefik):
# console on one hostname, tenant on a wildcard domain for your sites.

services:
  console:
    build:
      context: .
      dockerfile: docker/console.Dockerfile
      args:
        # Stamps the build so /api/health can say which one it is (AGL-2091).
        # Optional — empty means the health body reports `commit: null` rather
        # than a made-up id, and `version` answers regardless.
        #   COMMIT_REF=$(git rev-parse HEAD) docker compose up --build
        COMMIT_REF: ${COMMIT_REF:-}
      secrets:
        - selfhost_env
    env_file: .env.selfhost
    # Published on LOOPBACK, so the only way in is the reverse proxy the
    # runbook puts in front (docs/SELF_HOSTING.md §5 proxies to
    # `localhost:4200` / `localhost:4500`, i.e. this same host).
    #
    # A bare `4200:4200` binds every interface, so the container also answers
    # requests that never passed through the proxy — and those carry whatever
    # `x-forwarded-for` the caller typed. Every rate limiter in the product
    # keys on the first hop of that header, so a directly reachable container
    # hands an attacker a fresh bucket per request on passkey sign-in,
    # password reset, org creation and form submission. Nothing errors; the
    # limits simply stop counting.
    #
    # If your proxy runs on another host or in another Docker network, do NOT
    # widen this — put the proxy on this host's network, or add a
    # `docker-compose.override.yml` and make sure the port you expose is
    # firewalled to the proxy alone.
    ports:
      - '127.0.0.1:4200:4200'
    restart: unless-stopped

  tenant:
    build:
      context: .
      dockerfile: docker/tenant.Dockerfile
      args:
        COMMIT_REF: ${COMMIT_REF:-}
      secrets:
        - selfhost_env
    env_file: .env.selfhost
    # Published on LOOPBACK, so the only way in is the reverse proxy the
    # runbook puts in front (docs/SELF_HOSTING.md §5 proxies to
    # `localhost:4200` / `localhost:4500`, i.e. this same host).
    #
    # A bare `4200:4200` binds every interface, so the container also answers
    # requests that never passed through the proxy — and those carry whatever
    # `x-forwarded-for` the caller typed. Every rate limiter in the product
    # keys on the first hop of that header, so a directly reachable container
    # hands an attacker a fresh bucket per request on passkey sign-in,
    # password reset, org creation and form submission. Nothing errors; the
    # limits simply stop counting.
    #
    # If your proxy runs on another host or in another Docker network, do NOT
    # widen this — put the proxy on this host's network, or add a
    # `docker-compose.override.yml` and make sure the port you expose is
    # firewalled to the proxy alone.
    ports:
      - '127.0.0.1:4500:4500'
    restart: unless-stopped

secrets:
  selfhost_env:
    file: .env.selfhost