# Topology Every VM is a Docker host. Proxmox and Cloud-Init only create the machine and bootstrap Ansible; service placement is controlled by inventory. ## Edge VM The edge VM runs: - Docker - Traefik - authentik IAM It publishes Traefik entrypoints on host ports `80` and `443`. authentik can run behind the same local Traefik instance by setting: ```yaml nbops_service_routing_mode: traefik authentik_domain: auth.example.invalid ``` ## Downstream VMs Downstream VMs also run Docker. Instead of publishing each application port on the host, run Traefik on the VM and attach application containers to the shared Docker proxy network. ```yaml nbops_roles: - base - ssh - ufw - updates - docker - traefik - gitea - immich nbops_service_routing_mode: traefik nbops_traefik_entrypoint: web nbops_traefik_tls: false ``` In this mode application roles do not publish their HTTP ports. They render Traefik labels and join `nbops_proxy_network`, which defaults to `proxy`. Only Traefik entrypoints should be exposed on the downstream host firewall. Use `traefik_bind_address` to bind those entrypoints to the VM's internal address. ## Routing Modes Application roles support: - `host`: publish application ports directly and open those ports in UFW. - `traefik`: do not publish HTTP ports; attach to Traefik and render labels. Gitea is special: HTTP can be routed through Traefik while SSH remains published with `gitea_publish_ssh: true`.