srv-docker01 — Docker host
A general-purpose Docker host handed to one person to run their own stacks, published on the
Internet as test3.isc-vs.ch. Created 2026-08-27, replacing the static-site container that held
the same address.
| Guest | srv-docker01 — VM 105 on rumba, 192.168.88.154, Debian 13 cloud image, 4 cores / 8 GB / 40 GB local-lvm |
| URL | https://test3.isc-vs.ch through srv-web01, behind the user gate; http://srv-docker01.isc3:8080/ over the VPN with no authentication |
| Root | by SSH key, the same list as the PVE nodes (provisioning/pve/root-ssh-keys.sh) |
| Managed from | provisioning/docker01/ — deploy-docker01.sh (idempotent), rename-dns.sh |
A VM and not an LXC: Docker in an unprivileged container needs nesting plus keyctl and still
breaks on overlay2, cgroups and sandboxed systemd units, and root here belongs to someone running
arbitrary images.
The contract: one port
srv-web01 forwards test3.isc-vs.ch to 192.168.88.154:8080 and nothing else. Whatever answers
HTTP on that port is what the public name serves; the stack behind it is the user's, and changing
it needs no edit here. Publishing anything on another port of the VM exposes it to the VPN and the
LAN, never to the Internet — the two inbound dst-nat rules on the CCR2004 send 80 and 443 to
srv-web01 alone.
Several services on one name are the user's own problem to solve, with a router container
(Traefik, Caddy, nginx) on 8080 fanning out by path. A second hostname needs a CNAME in the
isc-vs.ch zone and a second vhost in provisioning/web/Caddyfile — ask.
Deploying a stack
TLS, the certificate and the login are handled upstream. On the VM there is nothing to configure but the containers.
ssh root@srv-docker01.isc3 # over the VPN
cd /srv/app
/srv/app/compose.yml holds a starter nginx so the chain can be tested end to end. Replace it:
services:
app:
image: <your-image>
restart: unless-stopped
ports:
- "8080:<port your app listens on>"
docker compose up -d # start, or apply a change
docker compose logs -f app # follow
docker compose ps # what is running, and on which ports
Three things worth getting right:
restart: unless-stoppedon every service, or the stack does not come back after a reboot of the VM or of rumba.- Bind 8080 on all interfaces, not
127.0.0.1:8080— the proxy connects from192.168.88.150. - Named volumes or paths under
/srv/appfor anything that must survivedocker compose down. The whole VM is in the nightly backups (02:00 to thehddpool, 03:00 to PBS), so a volume is restorable, but a container's writable layer is not something to rely on.
The application sees the visitor's address in X-Forwarded-For and the original scheme in
X-Forwarded-Proto; the connection from the proxy itself is plain HTTP and always comes from
192.168.88.150. Anything that builds absolute URLs must be told its public name is
test3.isc-vs.ch.
Who can reach it
The public name is behind the user gate: membership of isc or
hevs, filled from edu-ID claims at every login, so there is no list to maintain. It was put
there while the box is being set up and is not a property of the service — opening it to everyone
is a two-line deletion in provisioning/web/Caddyfile followed by provisioning/web/deploy.sh.
Over the VPN the VM is reachable directly on srv-docker01.isc3:8080 with no gate. Anyone on
the VPN, students included, can therefore reach whatever runs here — do not put anything on it
that the gate is what protects.
Root on this VM is root on a machine in the 192.168.88.0/24 subnet, which reaches the NAS, the
PDU and the MikroTiks. It is held by the rack administrators only.