Docker Host
The Docker host is a virtual machine on Proxmox that runs my containerized services.
About this page. The virtual machine settings were read from the running system. Addresses, MAC addresses, and USB device identifiers are left out on purpose.
- Type
- Virtual machine on Proxmox VE
- Software
- Docker 29.7 on Manjaro Linux, managed with Portainer CE 2.45
- Containers
- 19 running, in three Compose stacks plus Portainer
- VM ID
- 101
- Virtual CPUs
- 4, on one socket
- Memory
- 8 GiB
- Disk
- 64 GiB on
local-lvm, write-back cache - Network
- One VirtIO interface on
vmbr0 - USB
- One host USB device passed through
- Start at boot
- Yes
Nineteen containers, grouped by purpose.
Everything on this host is deployed and managed through Portainer. Services are grouped into numbered Docker Compose stacks by function, so related containers start, update, and stop together, and the numbering leaves room for new groups. Docker uses the overlay2 storage driver, and 17 volumes hold the persistent data.
| Stack | What it contains | Running |
|---|---|---|
2000-infrastructure | A dashboard (Homepage), uptime monitoring (Uptime Kuma), and internet speed tracking (Speedtest Tracker) | 3 |
3000-organizer | Bookmarks with full-text search (Karakeep, Meilisearch, and a headless browser for page capture), tasks (Vikunja), calendar and contacts (Radicale), a PostgreSQL database, and a few other personal services | 8 |
4000-entertainment | Defined for media services, with nothing running at the moment | 0 |
| Helper containers | Small containers that feed live widgets to the dashboard: host metrics (Glances), image update checks (What’s Up Docker), and status feeds from other systems in the lab. They run outside a stack. | 7 |
opt | Portainer itself | 1 |
| Total | 19 |
Creating the virtual machine in Proxmox.
- Upload the installer. Download the Manjaro XFCE minimal ISO and upload it under
local > ISO Images. - Start the wizard. Click Create VM, give it ID
101and the namedocker, and tick Start at boot. Select the ISO and set the guest type to Linux. - System and disk. Set the SCSI controller to VirtIO SCSI single, then create a 64 GiB disk on
local-lvmwith IO thread ticked and the Write back cache mode. - CPU and memory. One socket with 4 cores of type
x86-64-v2-AES, and8192MiB of memory. - Network. One VirtIO network card on
vmbr0, the LAN bridge. - Install the system. Start the VM, boot the live environment, and run the installer, letting it use the whole 64 GiB disk. When it finishes, detach the ISO under
Hardware > CD/DVD Driveand reboot.
From a fresh install to a working engine.
- Update the system and install Docker with its Compose plugin:
$ sudo pacman -Syu $ sudo pacman -S docker docker-compose - Start it now and at every boot:
$ sudo systemctl enable --now docker - Let your user run Docker without
sudo, then sign out and back in so the change takes effect:$ sudo usermod -aG docker $USER - Check that it works:
$ docker run --rm hello-world - Reserve the VM’s address. Give the Docker host a static mapping on the firewall (OPNsense Guide 1) so that the reverse proxy always finds it.
Managing containers with Portainer.
Portainer gives the Docker host a web interface for containers, volumes, networks, and Compose stacks. It runs as a container itself, from its own Compose file in /opt, and it reaches Docker through the engine’s socket.
- Deploy Portainer. Save this as
compose.yamlin a folder such as/opt/portainerand start it withdocker compose up -d:services: portainer: image: portainer/portainer-ce:latest restart: unless-stopped ports: - "9443:9443" volumes: - /var/run/docker.sock:/var/run/docker.sock - portainer_data:/data volumes: portainer_data: - Create the administrator. Browse to
https://<host-address>:9443within a few minutes of the first start and set the admin password. Portainer locks the setup page if it is left too long. - Add a stack. Open
Stacks > Add stack, name it (for example2000-infrastructure), paste a Compose file into the web editor, and click Deploy the stack. - Update a stack. Open the stack, edit the file if needed, and update it with the option to re-pull images, which recreates the containers on the newest image.
- Create an access token. Under
My account > Access tokens, add a token for scripts or read-only inspection. It is sent in anX-API-Keyheader, and it carries the same rights as your account.
Notes
- Treat Portainer like root. Access to the Docker socket is effectively administrator access to the whole host. Keep Portainer behind the reverse proxy with an access list, or reach it over the VPN, and use a strong password.
- Staying current. Most images follow their
latesttag, and What’s Up Docker watches for newer versions, so updates are a deliberate redeploy from Portainer rather than something that happens by surprise.
A small service to prove the path end to end.
A tiny web service that reports which container answered is a good first test. Save this as compose.yaml in a new folder:
services:
whoami:
image: traefik/whoami
ports:
- "8080:80"
restart: unless-stopped
Start it, then request it from another device on the network (using your Docker host’s reserved address in place of the example one):
$ docker compose up -d
$ curl http://192.168.10.20:8080
The same address and port are what you enter as the upstream in the Caddy handler (OPNsense Guide 4), which puts the service behind a trusted HTTPS hostname. restart: unless-stopped brings the container back after a reboot.
Giving the VM a physical USB device.
One USB device on the mini PC is passed through to this VM, so software in a container can talk to the hardware directly.
- Open the VM’s
Hardware > Add > USB Device. - Choose Use USB Port and pick the port the device is plugged into. This setup uses the port form, so the device keeps working after it is unplugged and plugged back in, as long as it stays in the same socket. Use USB Vendor/Device ID follows the device to any socket instead.
- Restart the VM, then confirm the guest sees it with
lsusb. - To give a container access, pass the device node through in Compose with a
devices:entry.
Far less memory in use than it looks.
| Measure | Reading | Note |
|---|---|---|
| Processor | 3.3% of 4 vCPUs on average | Highest reading 7.0% |
| Memory, as Proxmox sees it | 7.23 GiB of 8 GiB (90%) | Highest reading 7.48 GiB |
| Memory, used by containers | 1.62 GiB (about 20%) | Measured once, on 19 September 2026 |
| Network | about 35 KiB/s in and 3 KiB/s out | Average |
Proxmox readings are averages over the eight days to 19 September 2026, taken roughly every three hours, so short spikes do not show. The container figure is the sum of each running container’s working set, read from Portainer at one moment.
The two memory figures differ by more than 5 GiB. The guest has no QEMU guest agent, so Proxmox counts everything the guest has touched, including Linux’s file cache, as used. The cache is reclaimed whenever it is needed, so it is not real pressure. Where the container memory goes:
| Group | Containers | Working set |
|---|---|---|
3000-organizer | 8 | 0.76 GiB |
2000-infrastructure | 3 | 0.48 GiB |
| Helper containers | 7 | 0.29 GiB |
| Portainer | 1 | 0.09 GiB |
| Total | 19 | 1.62 GiB |
- Room to shrink. With the containers using about 1.6 GiB, the 8 GiB allocation is generous. Reducing it, to around 4 GiB as a first step, would free memory for the Proxmox host and leave room for another guest. Watch it for a week afterward, since some containers spike when they index or update.
- Processor. Load is very light, so four virtual CPUs is more than the workload needs.
- Guest agent. Installing the QEMU guest agent (the
qemu-guest-agentpackage on Manjaro) and turning on QEMU Guest Agent under the VM’sOptionsgives Proxmox accurate memory figures, clean shutdowns, and consistent snapshots. - Tidy up. The installer ISO is still attached and listed in the boot order, and two stopped helper containers left over from earlier changes can be removed.
The rest of the lab.
- ProxmoxThe hypervisor that hosts this virtual machine.
- OPNsenseAn open-source firewall and routing platform.
- Home Assistant OSThe appliance operating system for Home Assistant.