Ctrl K
ComunidadGuías…

docker-compose.yml

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

Archivo original ↗Preguntar a KiBot
# UnifiOptimizer daemon, one command: `docker compose up -d`.
#
# Builds Dockerfile.netadmin from this checkout and runs the single daemon
# process (collector, detectors, issue engine, SLE, FastAPI + WebSocket).
# Controller access is read-only. See docs/CONTAINER.md for the full walkthrough
# and for the bind-mount variant.
#
# THREE THINGS THIS FILE GETS RIGHT ON PURPOSE, do not "simplify" them away:
#
# 1. The published port is `127.0.0.1:8765:8765`, not `8765:8765`. GET reads on
#    the API are open by design once configured (docs/ARCHITECTURE.md 18.1), so
#    the bare form, which binds 0.0.0.0 on the host, would hand your whole
#    network inventory to anyone on the LAN. State-changing routes already fail
#    closed without `NETADMIN_API_TOKEN`, and `/mcp` (18.3) is separately gated
#    by `NETADMIN_MCP_TOKEN` below — 404 when unset, 401 on a wrong or missing
#    bearer — but neither of those makes a LAN publish free, since the read
#    surface above is still exposed. Put a reverse proxy with auth in front, or
#    widen the port deliberately, if you want LAN or remote access.
#
# 2. Storage is a named volume, not a `./data` bind mount. The image runs as a
#    non-root user (uid 501 by default, see Dockerfile.netadmin) and Docker
#    seeds a fresh named volume from the image with that ownership already
#    correct, on any host, with no uid bookkeeping from you. A bind mount only
#    works when the host directory happens to be writable by the container's
#    uid; docs/CONTAINER.md shows how to do that deliberately if you want the
#    files on the host.
#
# 3. NETADMIN_DATA_DIR is set explicitly even though /app/data is also where the
#    default cwd-relative lookup lands. It pins secrets.env, config.yaml, the
#    SQLite database, and the logs to the volume regardless of the working
#    directory, so an upgrade cannot silently start writing somewhere else.

services:
  netadmin:
    build:
      context: .
      dockerfile: Dockerfile.netadmin
    image: unifioptimizer:local
    container_name: unifioptimizer
    restart: unless-stopped

    # Loopback only. See note 1 above.
    ports:
      - "127.0.0.1:8765:8765"

    environment:
      NETADMIN_DATA_DIR: /app/data
      # Tells self-update (docs/ARCHITECTURE.md section 23) which host command
      # to show: `git pull && docker compose up -d --build`. The image already
      # sets NETADMIN_INSTALL_METHOD=container; this just picks the variant.
      NETADMIN_UPDATE_VARIANT: compose
      # Uncomment to gate fix apply/revert over HTTP. Reads stay open; without a
      # token every mutating endpoint is refused, which is the safe default.
      # NETADMIN_API_TOKEN: ${NETADMIN_API_TOKEN:-}
      # Uncomment to enable the remote MCP mount at /mcp (docs/MCP_SERVER.md).
      # A SEPARATE credential from NETADMIN_API_TOKEN, with no fallback either
      # direction: the API token authorizes controller mutations, this one only
      # gates read-only MCP tool calls. Unset (the default) means /mcp answers
      # 404 -- the feature is simply absent, not merely unauthenticated.
      # NETADMIN_MCP_TOKEN: ${NETADMIN_MCP_TOKEN:-}

    volumes:
      - netadmin-data:/app/data

    # No curl in the python:3.12-slim base, so probe with the interpreter that
    # is already there.
    healthcheck:
      test:
        - CMD
        - python
        - -c
        - |
          import sys, urllib.request
          with urllib.request.urlopen("http://127.0.0.1:8765/api/health", timeout=5) as r:
              sys.exit(0 if r.status == 200 else 1)
      interval: 30s
      timeout: 10s
      start_period: 30s
      retries: 3

    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  netadmin-data: