Tools server
Small services the other servers depend on - see Infrastructure.
Written for Ubuntu 24.04 LTS.
Server
- 1 vCPU and 2 GB RAM
- at another provider than GitLab, staging and production
it holds the keys to restore every other server - losing one provider account should not take them too
Base setup
Set up the VPS as a new server.
Firewall
Create a cloud firewall named tools in the provider panel - by role, not by ports, since the rules change with the server.
Inbound
| Description | Protocol | Port | Sources |
|---|---|---|---|
| SSH | TCP | 22 | All IPv4, All IPv6 |
| Certificate challenge and redirect to HTTPS | TCP | 80 | All IPv4, All IPv6 |
| Services over HTTPS | TCP | 443 | All IPv4, All IPv6 |
Apply to
- tag
tools, then put the tag on the VPS - a rebuilt VPS gets the firewall back with the tag
ports published by Docker bypass
ufw- Docker writes its own iptables rules, so a closedufwport stays open
Docker
Follow Install Docker Engine on Ubuntu - not the docker.io package from Ubuntu repositories.
Compose
All services run as one compose project from servers/tools in this repository - the root file includes a directory per service.
include:
- caddy/compose.yaml
- vaultwarden/compose.yaml- one default network - Caddy reaches services by container name, services publish no ports
- each service keeps its
compose.yamlanddatain its own directory
Clone
sudo git clone https://github.com/tednaaa/homelab /opt/homelab
cd /opt/homelab/servers/toolsWARNING
never run git clean -x in /opt/homelab - data directories are git-ignored and would be deleted with the vault
Environment
Domains and settings live in .env, out of git:
sudo cp .env.example .env
sudo vim .envStart
NOTE
start only once dig returns the VPS IP for every domain in .env - see Let's Encrypt
sudo docker compose up -d
sudo docker compose logs -f caddyUpdate
cd /opt/homelab
sudo git pull
cd servers/tools
sudo docker compose up -d
sudo docker compose exec -w /etc/caddy caddy caddy reload
up -drecreates only containers whose compose config changed - a changedCaddyfileneeds the reload
Caddy
One reverse proxy for every service - it owns ports 80 and 443 and gets a Let's Encrypt certificate per domain by itself.
a Caddy per service would fight over
80and443with the next one
Add a service
- add a directory with its
compose.yamlunderservers/tools→ - include it in
servers/tools/compose.yaml→ - add its domain block to
caddy/conf/Caddyfileand pass the domain variable to Caddy → - add its variables to
.env.exampleand the server's.env→ - list its page in Environment and Services →
- add its pre-backup step to
backup.shand its restore steps to Backup, if its data needs them → - update the server