Launch Your First Services
Launch Your First Services
Saturday afternoon. Linux is running, Docker is installed, and Portainer is sitting there looking satisfying in your browser.
Now we set up the plumbing.
Before we launch Immich, Nextcloud, Jellyfin, Vaultwarden, and Paperless, we need to solve a small problem: each application runs on a different port number. Without anything in between, you’d access your photo app at 192.168.1.100:2283, your file cloud at 192.168.1.100:8080, your media server at 192.168.1.100:8096 — not exactly elegant, and impossible to share easily with family members.
A reverse proxy solves this. It sits in front of all your applications and routes requests to the right place. Instead of remembering port numbers, you use clean names: photos.home, files.home, media.home.
Why Caddy?
There are several popular reverse proxies for self-hosting: Nginx, Traefik, and Caddy are the most common.
Caddy is the right choice for beginners because of one thing: its configuration file is remarkably human-readable. Where Nginx configuration involves cryptic blocks of directives, Caddy’s Caddyfile reads almost like plain English.
It also handles HTTPS automatically if you ever want to expose services to the internet — but for now, we’re keeping everything on your local network.
Set Up Your Local DNS
Before configuring Caddy, we need a way to turn friendly names like photos.home into your server’s IP address on your local network.
The easiest approach for beginners: edit the hosts file on each device you want to use.
On your main computer:
Mac/Linux:
sudo nano /etc/hosts
Windows (open Notepad as Administrator, then open):
C:\Windows\System32\drivers\etc\hosts
Add these lines, replacing 192.168.1.100 with your server’s actual IP:
192.168.1.100 photos.home
192.168.1.100 files.home
192.168.1.100 media.home
192.168.1.100 vault.home
192.168.1.100 docs.home
Save the file. Now your computer knows where to find each service name.
You’ll need to repeat this on each device in your home — or better yet, configure it in your router’s DNS settings so it applies automatically to everything on your network. Check your router’s documentation for “custom DNS entries” or “local DNS.”
Install Caddy
Create the Caddy folder and configuration:
mkdir -p ~/docker/caddy/config
cd ~/docker/caddy
Create the Caddyfile:
nano config/Caddyfile
Paste this starting configuration:
photos.home {
reverse_proxy immich_server:3001
}
files.home {
reverse_proxy nextcloud:80
}
media.home {
reverse_proxy jellyfin:8096
}
vault.home {
reverse_proxy vaultwarden:80
}
docs.home {
reverse_proxy paperless:8000
}
Save and exit (Ctrl+X, Y, Enter).
Now create the docker-compose.yml for Caddy:
nano docker-compose.yml
services:
caddy:
image: caddy:latest
container_name: caddy
ports:
- "80:80"
- "443:443"
volumes:
- ./config/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
networks:
- proxy
restart: unless-stopped
volumes:
caddy_data:
caddy_config:
networks:
proxy:
name: proxy
driver: bridge
Start Caddy:
docker compose up -d
The Proxy Network
Notice the networks section in the Caddy compose file. We created a shared network called proxy. Every application you install will connect to this same network — that’s how Caddy can reach them by name instead of IP address.
When you install each app in the coming chapters, you’ll see the same proxy network referenced in their compose files. This is the thread that connects everything together.
Test Your Setup
Caddy is running, but the apps it’s trying to proxy don’t exist yet — so browsing to photos.home right now will show an error. That’s expected. What we’re checking is that Caddy itself started cleanly:
cd ~/docker/caddy
docker compose logs
You should see Caddy starting up without errors. If you see configuration errors, double-check your Caddyfile for typos.
You can also check that port 80 is listening:
sudo ss -tlnp | grep :80
Create a Shared Docker Network for Apps
Each of your apps needs to be on the same proxy network so Caddy can reach them. We’ll reference this in every app’s compose file. To make sure the network exists before the apps try to connect to it, create it explicitly:
docker network create proxy
If Docker says the network already exists, that’s fine — Caddy already created it.
What You’ve Built
The infrastructure layer is now in place:
- Caddy reverse proxy running and listening on port 80
- Local DNS names mapped to your server
- A shared
proxynetwork ready for your applications - A clean, readable configuration you can easily extend
Everything is plumbed together. Time to start filling the pipes.
Cactus Commons Media