Homelab Portfolio Project · Container Infrastructure
Ubuntu Server 24.04 running Docker Engine 29.6.1 with Portainer CE - the foundation hosting all containerised homelab services.
| IP Address | 192.168.86.53 |
| Hostname | dockerhost |
| OS | Ubuntu Server 24.04 LTS |
| Docker | Engine 29.6.1 |
| Portainer | CE 2.39.4 LTS |
| Status | Live |
Build a dedicated container host on Proxmox VM 102, using Docker and Portainer to deploy and manage multiple self-hosted services - each isolated in its own stack, accessible externally via a Cloudflare Tunnel with no port forwarding required.
A hardened Ubuntu Server VM running Docker Engine, managed through Portainer CE. All services are deployed as Docker Compose stacks, connected through a shared internal network (npm_default), and exposed externally via Nginx Proxy Manager and a Cloudflare Tunnel - giving every service a clean *.munyakazi.org subdomain with valid HTTPS.
Containers are the standard deployment model in modern IT and DevOps. Running a self-hosted Docker environment demonstrates practical knowledge of containerisation, networking, reverse proxies, and secure external access - skills directly relevant to cloud, infrastructure, and platform roles.
| Component | Value |
|---|---|
| VM ID | 102 |
| Hostname | dockerhost |
| OS | Ubuntu Server 24.04 LTS |
| CPU | 2 vCores |
| RAM | 4 GB |
| Disk | 40 GB (local-lvm) |
| Network | vmbr0 |
| Static IP | 192.168.86.53 |
Installed Docker Engine 29.6.1 from the official Docker apt repository (not the Ubuntu snap version). User Admin added to the docker group - no sudo required for docker commands.
Verified with:
docker run hello-world
Portainer deployed as a standalone container via docker run (not Compose), with a named volume for persistent data:
docker run -d \
--name portainer \
--restart=always \
-p 8000:8000 \
-p 9443:9443 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
Portainer accessible at https://192.168.86.53:9443.
All services share a common Docker network (npm_default) so Nginx Proxy Manager can route traffic to any container by name. Database containers are isolated on private stack networks - never exposed to the proxy network.
npm_default network (shared):
├── npm (Nginx Proxy Manager)
├── cloudflared (Cloudflare Tunnel)
├── nextcloud
├── wikijs
└── portainer
Private networks (isolated):
├── nextcloud_default → nextcloud-db only
└── wikijs_internal → wikijs-db only
| Stack | Services | External URL |
|---|---|---|
| npm | Nginx Proxy Manager | http://192.168.86.53:81 (admin) |
| cloudflared | Cloudflare Tunnel | — |
| nextcloud | Nextcloud + MariaDB | https://cloud.munyakazi.org |
| wikijs | Wiki.js + PostgreSQL | https://wiki.munyakazi.org |
| portainer | (standalone container) | https://portainer.munyakazi.org |
All services are reachable from the internet without any port forwarding on the router. The full path for every request:
User browser
↓ HTTPS
Cloudflare edge (TLS termination)
↓ Encrypted tunnel
cloudflared container (VM 102)
↓ http://npm:80
Nginx Proxy Manager
↓ http://container:port
Target service container
This architecture means the homelab works identically regardless of ISP, router, or location - no dynamic DNS or port forwarding needed.
Part of the Homelab Project series. coming Soon