Chapter 17 of Be Your Own Cloud adds three small services to close out Part 3. This page sets each one up in more detail, and builds out the dashboard the chapter leaves as optional — with two tested compose files, since the book doesn’t print one.
Uptime Kuma
Deploy it
mkdir -p /opt/stacks/uptime-kuma
cd /opt/stacks/uptime-kuma
services:
uptime-kuma:
image: louislam/uptime-kuma:2.5.5
container_name: uptime-kuma
restart: unless-stopped
volumes:
- ./data:/app/data
ports:
- '3001:3001' docker compose up -d
Open http://192.168.1.50:3001, choose SQLite (Chapter 17 explains why), and create the admin account.
To give it a proper address, add a proxy host for status.home.yourdomain.com forwarding to 192.168.1.50, port 3001, with Websockets Support on — Uptime Kuma’s whole interface runs over a websocket, and without it the page loads and then sits there empty.
Monitors worth adding
Add New Monitor for each of these. Chapter 21 covers which ones matter most and adds the notifications.
- Each service’s subdomain — type HTTP(s), URL
https://vault.home.yourdomain.comand so on. Under Advanced, tick Certificate Expiry Notification: it warns you before a certificate lapses, not after. - Pi-hole answering — type DNS. Hostname
vault.home.yourdomain.com, Resolver Server192.168.1.50, port53, record typeA. This asks Pi-hole directly, so it fails if Pi-hole stops answering or loses your local records. - Things with no web page — type TCP Port, for example
192.168.1.50port53.
If subdomain monitors fail with “ENOTFOUND”
Uptime Kuma looks names up the way the server does, and the server doesn’t ask Pi-hole: Chapter 5’s netplan file gives it 192.168.1.1 and 1.1.1.1, and neither knows your *.home.yourdomain.com names. So an HTTP(s) monitor on https://vault.home.yourdomain.com can fail even when Vaultwarden is fine.
One fix is to send just this container’s lookups to Pi-hole. Add a dns: line to the uptime-kuma service in its compose file:
dns:
- 192.168.1.50
then docker compose up -d.
PrivateBin
Deploy it
mkdir -p /opt/stacks/privatebin
cd /opt/stacks/privatebin
services:
privatebin:
image: privatebin/nginx-fpm-alpine:2.0.6
container_name: privatebin
restart: unless-stopped
volumes:
- ./data:/srv/data
ports:
- '8280:8080' The folder has to belong to PrivateBin’s user before the first start, as Chapter 17 explains:
mkdir -p data
sudo chown 65534:82 data docker compose up -d
Put it behind HTTPS — it needs it
PrivateBin encrypts each paste in your browser, and browsers only allow the encryption it uses on secure pages: HTTPS, or localhost. Open it as http://192.168.1.50:8280 from a laptop and it will refuse to create pastes. So give it a proxy host: paste.home.yourdomain.com → 192.168.1.50, port 8280, with your certificate and Force SSL on.
Using it well
When you create a paste, choose:
- Expires — as short as the recipient needs. The default is a week.
- Burn after reading — deleted the first time it’s opened. Good for passwords.
- Password — optional, and sent separately from the link (a different app, or a phone call).
The part of the link after # is the decryption key. Browsers never send that part to the server, which is why even you, running the server, can’t read what’s stored.
A dashboard: Homepage or Homarr
Chapter 17 names both. They solve the same problem differently:
- Homepage is configured with YAML files, fast, and read-only in the browser — you edit files to change it.
- Homarr is configured by dragging things around in the browser, with its own accounts.
Pick one. Both compose files below follow the book’s conventions — their own folder, pinned versions, secrets in .env — and both were run in the test lab.
Homepage
Uses port 3000, which nothing else in the book’s port table uses.
mkdir -p /opt/stacks/homepage
cd /opt/stacks/homepage
services:
homepage:
image: ghcr.io/gethomepage/homepage:v2.4.0
container_name: homepage
restart: unless-stopped
environment:
# the addresses you'll open it on -- it refuses any other
- HOMEPAGE_ALLOWED_HOSTS=dash.home.yourdomain.com,192.168.1.50:3000
volumes:
- ./config:/app/config
ports:
- '3000:3000'
HOMEPAGE_ALLOWED_HOSTS is required: Homepage answers only to the hostnames listed, and returns an error for anything else. In testing, a request for any other host got a 400. List the name you’ll use through the proxy, and the IP-and-port for direct access.
Start it, and it creates ./config with starter files. Your links go in config/services.yaml — create or replace it:
- Security:
- Vaultwarden:
href: https://vault.home.yourdomain.com
description: Passwords
- Pi-hole:
href: http://192.168.1.50:8081/admin
description: DNS and ad blocking
- Media:
- Immich:
href: https://immich.home.yourdomain.com
description: Photos
- Jellyfin:
href: https://jellyfin.home.yourdomain.com
description: Films and TV
Homepage picks up changes without a restart. The files in ./config are owned by root once the container creates them, so edit them with sudo.
Homarr
Uses port 7575.
mkdir -p /opt/stacks/homarr
cd /opt/stacks/homarr
echo "SECRET_ENCRYPTION_KEY=$(openssl rand -hex 32)" > .env
chmod 600 .env
services:
homarr:
image: ghcr.io/homarr-labs/homarr:v1.77.2
container_name: homarr
restart: unless-stopped
environment:
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
volumes:
- ./appdata:/appdata
ports:
- '7575:7575'
The encryption key protects any passwords or API keys you later give Homarr for its widgets. Keep a copy in Vaultwarden: if .env is lost, Homarr can’t read what it stored.
docker compose up -d, open http://192.168.1.50:7575, and its first-run setup creates your admin account. Add apps and arrange the board from the browser.
Its own address
Either way, add a proxy host — dash.home.yourdomain.com → 192.168.1.50, port 3000 for Homepage or 7575 for Homarr, Websockets on — and set it as your browser’s home page.
Backups and updates
All three services keep everything in their folder under /opt/stacks, which Chapter 18 already backs up, and Chapter 19’s first restore drill uses PrivateBin on purpose. Update each by bumping its tag, after reading its release notes.
Official documentation
- Uptime Kuma wiki and releases
- PrivateBin — the Docker image and its FAQ
- Homepage documentation — services.yaml and Docker install
- Homarr documentation
Stuck on a step? Get in touch.