Update tech_docs/docker_compose_guide.md

This commit is contained in:
2025-08-05 23:27:45 -05:00
parent 75757a0557
commit b7fa21be0e

View File

@@ -1,3 +1,150 @@
Learning-GOAL: “I can read, reason about and harden any Dockerfile or `docker run` incantation I meet—without drowning in trivia.”
Below is a **minimal, language-agnostic curriculum** expressed as executable **pseudocode**.
Each block is a self-contained kata you can type, break, fix and extend.
```plaintext
--------------------------------------------------
0. Bootstrapping Sandbox
--------------------------------------------------
function bootstrap():
vm = create_ephemeral_vm() // multipass, lima, or cloud instance
install("docker engine") // or podman, nerdctl
alias d="docker"
return vm
--------------------------------------------------
1. Core Primitives (must be muscle memory)
--------------------------------------------------
// 1.1 Image = read-only template
function image_primitives():
img = build("Dockerfile_hello") // FROM alpine; COPY hello.sh /; CMD ["sh","/hello.sh"]
tag = tag(img, "demo:v1")
id = inspect(tag, ".Id")
layers = history(tag) // list of diff-IDs
return {img, tag, id, layers}
// 1.2 Container = writable runtime instance
function container_primitives():
c1 = run("-d --name c1 demo:v1")
top = exec(c1, "ps aux") // whats running?
delta = diff(c1) // which files changed?
commit(c1, "demo:v1-smeared") // bake delta into new image
rm(c1)
// 1.3 Registry = image transport
function registry_primitives():
reg = start_local_registry() // docker run -d -p 5000:5000 registry:2
push("demo:v1", reg)
rmi("demo:v1")
pull("demo:v1", reg)
--------------------------------------------------
2. Storage & State (volumes, bind mounts, tmpfs)
--------------------------------------------------
function storage_primitives():
vol = volume_create("db_data")
c2 = run("-d -v db_data:/var/lib/postgresql postgres:15")
c3 = run("-d --mount src=$(pwd),dst=/src,type=bind alpine sh -c 'sleep 3600'")
c4 = run("--tmpfs /tmp:size=100m alpine sh -c 'dd if=/dev/zero of=/tmp/big'")
cleanup([c2,c3,c4])
--------------------------------------------------
3. Networking (CNB model)
--------------------------------------------------
function networking_primitives():
net = network_create("demo_net", driver="bridge")
nginx = run("-d --net demo_net --name web nginx")
curl = run("--rm --net demo_net alpine/curl curl http://web")
assert "Welcome to nginx" in curl.output
rm(nginx); network_rm(net)
--------------------------------------------------
4. Build Secrets & Multi-stage (no plaintext keys)
--------------------------------------------------
function build_hardening():
// Dockerfile.multi
// FROM golang:1.22 AS build
// RUN --mount=type=secret,id=gh_token \
// git config --global http.extraheader "Authorization: Bearer $(cat /run/secrets/gh_token)"
// COPY . .
// RUN go build -o app .
// FROM gcr.io/distroless/static
// COPY --from=build /src/app /app
// CMD ["/app"]
img = build("--secret id=gh_token,env=GH_TOKEN -f Dockerfile.multi .")
scan(img) // trivy or grype
--------------------------------------------------
5. Security Profiles
--------------------------------------------------
function security_primitives():
c5 = run("--cap-drop ALL \
--cap-add NET_BIND_SERVICE \
--security-opt no-new-privileges:true \
--user 1000:1000 \
--read-only \
--tmpfs /tmp \
alpine:latest whoami")
assert c5.stdout == "1000"
--------------------------------------------------
6. Orchestration Lite (Compose as state-machine)
--------------------------------------------------
function compose_primitives():
services = load("compose.yml") // web, redis, db
stack = compose_up(services)
assert http_get("http://localhost:8080") == 200
compose_down(stack)
--------------------------------------------------
7. Observability & Debug (no black boxes)
--------------------------------------------------
function observability():
c6 = run("-d demo:v1")
logs_tail(c6)
stats = container_stats(c6) // cpu, mem, blkio
enter(c6, "sh") // nsenter for low-level poke
rm(c6)
--------------------------------------------------
8. Cleanup Ritual
--------------------------------------------------
function cleanup(containers):
for c in containers:
stop(c, timeout=5)
rm(c, volumes=True)
system_prune(all=True)
--------------------------------------------------
9. Mastery Checklist
--------------------------------------------------
can_i:
▢ explain the difference between an image, a layer, and a container
▢ build multi-stage with secrets and non-root user
▢ launch two containers on a custom bridge and capture traffic
▢ run a read-only container that still writes temporary files
▢ read `docker inspect` JSON and spot the security-options stanza
▢ translate a `docker run` one-liner into compose YAML and back
▢ upgrade base image without cache, then surgically bust only the vulnerable layer
--------------------------------------------------
10. Exit Condition
--------------------------------------------------
if mastery_checklist.all_true():
print("You now own the primitives. Dive into BuildKit, rootless, or Kubernetes.")
else:
iterate()
--------------------------------------------------
Usage Notes
--------------------------------------------------
- Replace every function with real shell commands (`docker build …`, `docker network create …`).
- No single file is more than 40 lines; the goal is repetition, not rote memorization.
- Re-run the entire pseudocode weekly on a fresh VM to avoid stale muscle memory.
```
---
Ah, I see—youre asking for a **meta-comparison** that aligns with your framing of *"deterministic serendipity"* (predictable yet flexible configurations) and focuses on **functional parallels** between Docker Compose and Talos Linuxs approach, even if their primary use cases differ. Lets reframe this as: Ah, I see—youre asking for a **meta-comparison** that aligns with your framing of *"deterministic serendipity"* (predictable yet flexible configurations) and focuses on **functional parallels** between Docker Compose and Talos Linuxs approach, even if their primary use cases differ. Lets reframe this as:
--- ---