Skip to main content

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.

Guestsrv-docker01VM 105 on rumba, 192.168.88.154, Debian 13 cloud image, 4 cores / 8 GB / 40 GB local-lvm
URLhttps://test3.isc-vs.ch through srv-web01, behind the user gate; http://srv-docker01.isc3:8080/ over the VPN with no authentication
Rootby SSH key, the same list as the PVE nodes (provisioning/pve/root-ssh-keys.sh)
Managed fromprovisioning/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-stopped on 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 from 192.168.88.150.
  • Named volumes or paths under /srv/app for anything that must survive docker compose down. The whole VM is in the nightly backups (02:00 to the hdd pool, 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.