Day 154 — Week 2 review + recall¶
Month 6 · Week 2 · ⬅ Day 153 · Day 155 ➡ · Journal index
🎯 Learning Objective¶
Consolidate the week's shipping skills — containerize, compose, harden, CI, config/secrets, graceful shutdown — and prove retention with active recall.
📚 Topics¶
- Multi-stage builds · distroless hardening · Compose stacks
- GitHub Actions (vet/race/cover/govulncheck) · 12-factor config & secrets · signals/shutdown
📖 Reading / Sources¶
- Re-read my notes for [[day-148]]–[[day-153]]
- Full week review →
📝 Notes¶
- This is a light consolidation day; the full retro, re-quiz, and metrics live in the week review.
- One-line thread: the same static binary flows through build → harden → compose → CI → run, configured by the environment and shut down cleanly on a signal.
💻 Code Examples¶
// The shape every service in this week shares: load config, start, drain.
func main() {
cfg, err := config.Load() // 12-factor: env in, fail fast
if err != nil { log.Fatal(err) }
ctx, stop := signal.NotifyContext(context.Background(),
syscall.SIGINT, syscall.SIGTERM) // catch SIGTERM from `docker stop`
defer stop()
run(ctx, cfg) // ListenAndServe + Shutdown drain
}
Runnable:
examples/month-06/graceful·examples/month-06/config
🏋️ Exercises / Practice¶
| Exercise | Status | Link |
|---|---|---|
envconfig · secretsource · drain (all go test green) |
✅ | exercises/month-06/week-2/ |
🐛 Mistakes Made¶
- Early in the week I conflated "container started" with "service ready" — healthchecks and graceful shutdown both hinge on that distinction.
❓ Open Questions¶
- Where does observability (metrics/tracing) bolt onto this lifecycle? → next week.
🧠 Active Recall (answer without looking)¶
- Q: Trace one static binary from
go buildto a running, hardened, gracefully-stopping container — name the key tool at each step.A
CGO_ENABLED=0 go build (static binary) → multi-stage Dockerfile into distroless static:nonroot (small, non-root, has CA certs) → docker compose for the local stack → GitHub Actions runs vet/-race/cover/govulncheck → config from env (os.LookupEnv + errors.Join), secrets via *_FILE → signal.NotifyContext + srv.Shutdown(ctx) drains on SIGTERM.
2. Q: Two production "fail-fast vs drain-slow" rules from this week? A
Fail fast at startup on bad config (errors.Join all problems, exit non-zero). Drain slow at shutdown: bound Shutdown with a timeout shorter than the platform kill grace, treating http.ErrServerClosed as success.
🪶 Feynman Reflection¶
This week was about the gap between "my code compiles" and "my service runs in production." That gap is packaging, configuration, automation, and lifecycle — none of it changes the business logic, all of it decides whether the thing survives a deploy, a restart, and a bad dependency.
🕳️ Knowledge Gaps¶
- See the week review "Weaknesses" section.
✅ Summary¶
Week 2 done: I can ship a Go service as a small hardened image, run it in a local stack, gate it in CI, configure it the 12-factor way, and shut it down gracefully.
⏭️ Next Steps / Prep for Tomorrow¶
- Month 6 · Week 3: observability — metrics, tracing, and dashboards on top of this lifecycle.
| Time spent | Difficulty | Confidence |
|---|---|---|
| 75 min | 🟦⬜⬜⬜⬜ | 🟦🟦🟦🟦⬜ |
Suggested commit: docs(journal): week 2 review + recall (day 154)