Homelab Academy / Modules
Guided practice + break/fix + lab gate.
Module: Module 1: Infrastructure & Addressing
Activity type: Lab (Practice)
Objective: Given a running Compose service, the learner can inspect health and logs, perform a controlled image update, and roll back to a known-good state with evidence.
Use the Class 2 compose-lab web service (or recreate it). Goal: prove you can update an explicit image tag and roll back with commands, not vibes.
Record the current image identity (last-known-good).
cd $HOME\compose-lab
docker compose ps
docker compose images
docker image inspect nginx:stable --format "Id={{.Id}} RepoTags={{.RepoTags}}"
Copy-Item compose.yaml compose.yaml.bak
curl.exe -s http://127.0.0.1:8080/ | findstr UNIQUE
cd ~/compose-lab
docker compose ps
docker compose images
docker image inspect nginx:stable --format 'Id={{.Id}} RepoTags={{.RepoTags}}'
cp compose.yaml compose.yaml.bak
curl -s http://127.0.0.1:8080/ | grep UNIQUE
Write the image ID and tag in the workbook. That is your rollback target.
Run the acceptance test (before change).
Browser or curl must show your unique phrase. Record “PASS” + timestamp.
Change to another explicit tag, validate, pull, recreate.
Edit image: from nginx:stable to a newer explicit tag you choose from Docker Hub (example pattern nginx:1.27, pick one that exists today). Then:
docker compose config
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=80 web
docker compose images
docker compose config
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=80 web
docker image inspect $(docker compose images -q web) --format '{{.RepoTags}} {{.Id}}'
Re-run the acceptance test.
curl the unique phrase again. If it fails, do not continue, roll back now.
Simulate a bad update (nonexistent tag), then restore.
# Temporarily set image: nginx:this-tag-does-not-exist-otacon
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=40 web
Copy-Item compose.yaml.bak compose.yaml -Force
docker compose pull
docker compose up -d
curl.exe -s http://127.0.0.1:8080/ | findstr UNIQUE
# edit image to nginx:this-tag-does-not-exist-otacon, then:
docker compose pull || true
docker compose up -d || true
docker compose ps
docker compose logs --tail=40 web
cp compose.yaml.bak compose.yaml
docker compose pull
docker compose up -d
curl -s http://127.0.0.1:8080/ | grep UNIQUE
Fill a mini service contract (also use templates/service_contract.csv):
purpose: compose-lab nginx demo
image/version: (tag + image id)
configuration path: ./compose.yaml: ./site
media/download paths: n/a
internal address/port: web:80
published address/port: DOCKER-HOST:8080
dependencies: none
health test: curl unique phrase
backup method: copy compose.yaml + site/
update procedure: change tag -> config -> pull -> up -d -> test
rollback procedure: restore compose.yaml.bak -> pull -> up -d -> test
Run with commands; change only one variable at a time.
docker compose ps + docker inspect --format '{{.State.ExitCode}} {{.State.Error}}' CID + first error in logs.netstat -ano | findstr :8080
ss -lntp | grep 8080 || sudo lsof -i :8080
docker system df and host df -h / PowerShell Get-PSDrive. Do not run docker system prune --volumes casually.All boxes must be true before the next class unlocks. If you fail: feedback → targeted review → new practice → reassess.