Skip to content

Customising the stack (docker-compose.override.yml)

You want to adapt the Vesana containers to your environment, for example:

  • attach the Vesana web server to your reverse proxy's Docker network (Nginx Proxy Manager, Traefik, Caddy)
  • use an overlay network across several hosts (Docker Swarm)
  • set labels (Traefik routing, Watchtower exclusion, backup tools)
  • add resource limits (mem_limit, cpus) or your own bind mounts

There is exactly one place for this: the file docker-compose.override.yml in the installation directory (default /opt/vesana), right next to docker-compose.prod.yml.

Why not in docker-compose.prod.yml or the .env?

File Owned by On an update
docker-compose.prod.yml Vesana is replaced (an online update downloads it from the licence portal, an offline update takes it from the package; the old copy is kept as a backup in the updater volume)
.env you is kept — the updater only changes its own lines (e.g. VESANA_VERSION, compose profiles, sizing profile, agent gateway port). But the .env can only set values, not networks, labels or mounts
docker-compose.override.yml you stays untouched. Vesana loads it on every update and every restart, but never writes, backs up or deletes it

So changes made directly in docker-compose.prod.yml are gone after the next update.

Creating it

  1. Create the file. It contains only your additions:

    # /opt/vesana/docker-compose.override.yml
    services:
      nginx:
        labels:
          com.example.team: "monitoring"
    
  2. Check that Compose understands both files together:

    cd /opt/vesana
    docker compose -f docker-compose.prod.yml -f docker-compose.override.yml config --quiet && echo ok
    
  3. Apply it:

    docker compose -f docker-compose.prod.yml -f docker-compose.override.yml up -d
    

From now on Vesana includes the file in everything that recreates the stack: GUI update, automatic update, offline update, the agent gateway and Ollama switches, the split-container assistant and the sizing profile.

Manual commands without -f twice

If you add the line COMPOSE_FILE=docker-compose.prod.yml:docker-compose.override.yml to the .env, a plain docker compose up -d in the installation directory is enough. The updater doesn't need that line; it finds the file on its own.

Examples

Attach the web server to a reverse proxy's network

Your reverse proxy (e.g. Nginx Proxy Manager) runs in its own Docker network proxy. This lets it reach Vesana under the name nginx without port 443 being open on the host:

services:
  nginx:
    networks:
      - default
      - proxy

networks:
  proxy:
    external: true

Important: default must stay in the list, otherwise the web server can no longer reach the Vesana API.

Overlay network across several hosts (Docker Swarm)

A Compose stack can join an attachable overlay network that you created in the swarm:

# once, on a swarm manager
docker network create --driver overlay --attachable --opt encrypted proxy-overlay
services:
  nginx:
    networks:
      - default
      - proxy-overlay

networks:
  proxy-overlay:
    external: true

Keep in mind:

  • Vesana still runs as a normal Compose stack. It does not run as a swarm stack (docker stack deploy), and the updater could not update one.
  • If the overlay network is unavailable (swarm trouble), the nginx container does not start, not even after an update. Vesana then depends on your swarm infrastructure.
  • Without --opt encrypted, traffic between the hosts is unencrypted (VXLAN).

Labels (Traefik, backup tools, Watchtower)

services:
  nginx:
    labels:
      traefik.enable: "true"
      com.centurylinklabs.watchtower.enable: "false"

Inside the container, the Vesana web server speaks HTTPS on port 443 with the stack's certificate. A proxy in front therefore has to forward via HTTPS and either trust that certificate or skip verification for this one target.

Resource limits

services:
  worker:
    mem_limit: 2g
  ollama:
    cpus: 4

For memory and the number of workers there is also the built-in sizing profile (see Resources). Use the override file only for what the profile doesn't cover.

What Vesana guarantees and what it doesn't

Guaranteed:

  • The file is loaded on every update and every restart done by Vesana.
  • Vesana never modifies it.
  • Pre-check before every update: after downloading the new docker-compose.prod.yml, the updater checks both files together (docker compose config). If they no longer fit together, the update is aborted before anything is pulled or stopped. The old compose file is restored and Vesana keeps running on its current version. The message on the update page names the file and the error reported by Compose.

Not guaranteed:

  • Service names and internal details are not a stable interface. If a release renames a service or changes its networks, you need to adjust your file. The pre-check makes sure you notice before anything breaks.
  • Problems caused by your additions are not covered by Vesana support. The support bundle shows that an override file is active and which services it touches (names only, no values).

Security: what never belongs in a foreign network

Attach only the web server (nginx) to foreign networks. Never api, api-admin, postgres, redis, updater or the workers.

  • Vesana trusts its own stack networks as proxies. If the API sits in a foreign network, that network automatically counts as trusted. Any container in it could then forge its source address and bypass the admin IP allowlist.
  • postgres and redis should only be reachable inside the stack network.
  • The updater holds the Docker socket; it must never be reachable from another network.
  • Don't publish additional ports (ports:) for these services.

Behind a reverse proxy: three points

Whether your proxy reaches Vesana via a shared Docker network or via https://<server>:443:

  1. Real client addresses: add your proxy's address or network as a trusted proxy under Admin → Login & Security → Admin Access → "Advanced: reverse proxies (X-Forwarded-For)". Otherwise login lockouts, the session list and the audit log show every user with the proxy's address.
  2. Don't decrypt the agent gateway (port 8443): agents and collectors check the Vesana stack certificate there. Pass the port through as a plain TCP stream (Nginx Proxy Manager: "Streams") or keep it directly reachable. See Distribution & reachability.
  3. Address: the address users open Vesana at is the proxy's, without a port.

Undoing it

Rename or delete the file and recreate the stack:

cd /opt/vesana
mv docker-compose.override.yml docker-compose.override.yml.off
docker compose -f docker-compose.prod.yml up -d

Next