Each lab has two files:
| File | Purpose | When |
|---|---|---|
knowledge.md |
Concepts, terms, and questions: the why and how it works | Before practicing |
README.md |
Goal, "Done when", steps, what broke, lessons: the doing | During and after |
- Copy
labs/_template/tolabs/NN-short-name/(or fill in the existing stub). - Work on a branch:
lab/NN-short-name. - Study: read
knowledge.mdand add your own notes. You're ready when you can answer "Before you start" without looking. - Practice: follow
README.md. Write notes while doing the lab, not after: commands, errors, fixes. - Anything reusable goes into an infrastructure folder (see below); the lab README links to it.
- Review: answer "After the lab, check yourself" in
knowledge.md, then fill in "Lessons learned". - A lab is ✅ only when every "Done when" item is checked. Update the roadmap in the root README.
- Merge to
main. Tag milestones if useful (phase-1-done). - Tick the matching checkpoints in learning-roadmap.md.
| Kind of code | Folder | Example |
|---|---|---|
| Sample app being deployed | apps/<name>/ |
apps/demo-api/ |
| Docker Compose stack | stacks/<name>/compose.yaml |
stacks/traefik/ |
| Standalone shell script | scripts/ |
scripts/backup.sh |
| Server config | ansible/ (roles per concern) |
ansible/roles/hardening/ |
| Cloud resources | terraform/ |
terraform/envs/prod/ |
| Kubernetes | k8s/ |
k8s/apps/demo-api/ |
| Pipelines | .github/workflows/ |
deploy-demo-api.yml |
Throwaway experiments may stay inside the lab folder under labs/NN-*/scratch/.
- Real values go in
.envfiles (git-ignored). Commit a.env.examplewith placeholder values next to it. - Ansible secrets:
ansible-vault. Terraform:*.tfvars(git-ignored) or environment variables. - CI secrets: GitHub Actions secrets.
- Never write real IPs, SSH ports, or tokens into lab notes — use placeholders like
<VPS_IP>,<SSH_PORT>. - If something leaks: rotate it first, then clean the history.
- Folders and files:
kebab-case. - Labs: two-digit number + short name:
07-cicd-pipeline. - Subdomains: one per service,
<service>.<domain>(e.g.git.example.com). - Branches:
lab/NN-name,fix/...,docs/.... - Commits: Conventional Commits —
feat(ansible): add hardening role,docs(lab-01): add lessons learned.
When choosing between tools (Traefik vs Nginx Proxy Manager, GitHub Actions vs Jenkins, Argo CD vs Flux…), write a short record in docs/decisions/NNNN-title.md: context, options, choice, why. See 0001.