Add one stack at a time
Choose an application, separate its configuration and data, and document recovery before expanding.
Finish the restore exercise before adding personal data. The catalog describes the groups used in my repository. It is not a public inventory of live hosts or a promise that every listed service is running.
homelab/
apps/<stack>/compose.yaml
apps/<stack>/.env.example
apps/<stack>/README.md
core/<stack>/...
ops/<stack>/...
Apps provide functions you use. Core handles shared connectivity and identity. Ops supports operation and recovery. Alphabetical navigation is not installation order. Start with one app and its necessary database; add shared systems when you can explain why they are needed. Some entries, such as Ansible, Tailscale on the host, and secret-handling procedures, are not container stacks.
Create a separate project
For example, create ~/homelab/apps/finance and enter it. Read the finance note and its linked official installation guide. Save the upstream Compose example for the selected release as compose.yaml. Inspect it before running: image versions, writable paths, secrets, host ports, device access, and dependencies. Do not paste a random full homelab bundle.
Use a unique Compose project name with name: or a consistent -p option on every command. The tutorial's single project is for learning; this directory layout normally gives each stack its own project. Separate projects do not automatically share networks or resolve each other's service names. An intentional proxy network must be created and declared consistently before connecting a new application.
Create .env only if the upstream configuration uses it. Put placeholder names in .env.example, never real values. Exclude .env, credentials, database files, uploads, and restore output from Git. Keep the actual data in documented volumes or paths. A Git repository is not an application-data backup.
# Run from the directory containing this stack's compose.yaml.
sudo docker compose config --quiet
sudo docker compose pull
sudo docker compose up -d
sudo docker compose ps -a
sudo docker compose logs --tail 50
Replace any upstream all-interface publication with loopback while learning, where the application supports that deployment. Some services need LAN discovery or hardware; read their exceptions rather than applying the web example blindly. Open the UI through SSH, create a test record, restart the service, and confirm that the record survives. Then restore that record into a separate test instance using the application's supported procedure.
Before updating
Read release notes, record the current image digest, make a verified backup, and check database migration requirements. pull alone does not replace a running container; up -d applies the selected image and configuration. An old image may not understand a migrated database, so rolling back the image alone is not a recovery plan.
Each stack note gives a bounded starting configuration and checks. The downloadable web/metrics/restic exercise was run; the other notes are setup guidance based on upstream documentation, not claims that all 29 installations were tested. Keep your private README with chosen versions, data locations, access rules, backup procedure, and last restore result. Public notes should use independent examples and omit account identifiers, routes, tokens, and unremediated findings.