Run the practice lab
Download the example, create a local secret, start three services, and check the result.
Complete Docker installation first. Run the commands below on your practice server, as the same user each time. Keep this directory: Compose resolves the relative bind mounts from it.
Download and inspect
The archive contains a Compose file, an HTML page, routing and metrics configuration, and a README. It contains no credentials. The checksum detects a damaged or mismatched download; it is not an independent signature. Stop if verification fails. Read compose.yaml and README.md before starting.
The package also contains two Dockerfiles. docker compose build web backup builds the patched web image and the offline backup tool before starting the lab. The first build downloads source and dependencies and can take several minutes. These are teaching builds; see the included README for their scope and license.
mkdir -p ~/homelab-practice
cd ~/homelab-practice
curl -fSLO https://qazizada.de/downloads/homelab-starter.tar.gz
curl -fSLO https://qazizada.de/downloads/homelab-starter.tar.gz.sha256
sha256sum -c homelab-starter.tar.gz.sha256
tar -tzf homelab-starter.tar.gz
tar -xzf homelab-starter.tar.gz
mkdir -p secrets restore
chmod 700 secrets
# Run only when the password file does not exist.
(umask 077; set -C; openssl rand -hex 32 > secrets/restic-password)
sudo docker compose config --quiet
sudo docker compose build web backup
sudo docker compose up -d web gateway metrics
sudo docker compose ps
The password command refuses to overwrite an existing file. Save that password somewhere separate before relying on a backup. Compose validates quietly so interpolated secrets are not printed. up -d downloads images and starts the services in the background. The backup job is not started.
Check the result
Run these on the server. Allow about 30 seconds for the first metrics scrape.
curl --fail --resolve lab.test:18080:127.0.0.1 http://lab.test:18080/
curl --fail 'http://127.0.0.1:19090/api/v1/query?query=up'
The first response contains Homelab practice. The second contains two up results whose values are 1. up means that Prometheus could scrape that target, not that every application function works.
To open the pages from your laptop, run this in a separate terminal on your laptop, replacing the user and server placeholders:
ssh -N -L 18080:127.0.0.1:18080 -L 19090:127.0.0.1:19090 learner@YOUR_SERVER
Keep that terminal open. Visit http://127.0.0.1:19090 for Prometheus. For the web page, add 127.0.0.1 lab.test to your laptop's hosts file using your operating system's instructions, then visit http://lab.test:18080. Alternatively, use the curl command above on the laptop without editing hosts. The gateway matches the requested hostname; browsing its bare IP returns 404.
Stop and resume
From the project directory, sudo docker compose stop pauses the containers; sudo docker compose start resumes them. sudo docker compose down removes containers and project networks, preserving named volumes. up -d web gateway metrics recreates them. Adding --volumes deletes the metric and backup volumes. Do not use it to fix an unexplained error.
If a port is occupied, run sudo ss -ltnp to identify its owner. Pick another loopback port in compose.yaml and update your curl command and SSH forward together. Do not stop an unrelated service. If a bind source is missing, check your directory and archive extraction rather than creating an empty configuration file.
Next: understand the settings.