Chapter 42Lesson 05~240 minutes

Production Capstone: Build, Secure, Publish, Operate, Observe, and Recover a Complete Dockerized Application: Final Operational Review and Handoff

Assemble the final operational review packet, run an independent clean-shell verification, prove restore and rollback evidence, remove only lab-owned resources, and hand off upgrade/backup/incident obligations.

HandoffVerificationEvidence packetCleanupCourse complete

Learning objectives

  • Assemble one final evidence directory proving requirements, source-to-digest lineage, supply-chain evidence, runtime controls, persistent state, incidents, backup/restore, and limitations.
  • Run a clean-shell verification that depends on explicit evidence and immutable digests rather than hidden environment variables or mutable tags.
  • Write the production operating handoff: upgrade/patch cadence, retention/backup policy, incident entry points, rollback, ownership, and platform boundaries.
  • Remove every lab-owned container, network, volume, builder, registry artifact, and temporary private key by exact identity while protecting unrelated Docker state.
  • Close the Docker course with a clear boundary to Kubernetes, Helm, OpenShift, and other platform courses.

1. Final evidence directory contract

find evidence -maxdepth 3 -type f -print | sort > evidence/final-file-list.txt
sha256sum evidence/backups/state.tgz > evidence/final-backup-checksum.txt
printf 'final_review_utc=%s
' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > evidence/final-review.txt
printf 'source_sha=%s
subject=%s
release_tag=%s
' "$SOURCE_SHA" "$SUBJECT" "$RELEASE_TAG" >> evidence/final-review.txt
printf 'context=%s
' "$(docker context show)" >> evidence/final-review.txt
Packet area Expected evidence
Requirements/threat model Lesson 1 matrix, constraints, accepted limitations
Source/build identity source.txt, toolchain.txt, base digest, builder.txt, build.log, metadata
Release identity subject.txt, imagetools.txt, promotion.txt
Supply chain SBOM, provenance, Trivy scan JSON, Cosign public key + verification
Runtime contract normalized Compose, app inspect, network/volume IDs, resource/log settings
Application state before/increment/after-replace responses
Observability health, logs, events/stats samples
Backup/recovery archive hash, metadata, restore timing, recovered-state/runtime evidence
Incidents build/process/network/storage drill evidence and runbook updates
Governance limitations register, readiness checklist, owners/next steps

2. Independent clean-shell verification

Open a new shell in the project directory. Do not rely on SUBJECT, SOURCE_SHA, or other exported variables from previous lessons. Reconstruct identity from evidence first.

set -eu
SUBJECT="$(sed -n 's/^subject=//p' evidence/subject.txt)"
SOURCE_SHA="$(sed -n 's/^source_sha=//p' evidence/source.txt)"
RELEASE_DIGEST="$(awk '/^Digest:/ {print $2; exit}' evidence/release-imagetools.txt)"
SUBJECT_DIGEST="${SUBJECT##*@}"

test "$(git rev-parse HEAD)" = "$SOURCE_SHA"
test -z "$(git status --porcelain)"
test "$RELEASE_DIGEST" = "$SUBJECT_DIGEST"

docker buildx imagetools inspect "$SUBJECT" > /tmp/ch42-verify-imagetools.txt
grep -q 'linux/amd64' /tmp/ch42-verify-imagetools.txt
grep -q 'linux/arm64' /tmp/ch42-verify-imagetools.txt

cosign verify --key cosign.pub --allow-insecure-registry "$SUBJECT" > /tmp/ch42-signature.json
APP_ID="$(APP_REF="$SUBJECT" docker compose -p ch42cap ps -q app)"
test -n "$APP_ID"
docker inspect "$APP_ID" --format '{{.Image}} {{.Config.User}} {{.HostConfig.ReadonlyRootfs}}'
curl -fsS http://127.0.0.1:18080/health
sha256sum -c evidence/backups/state.tgz.sha256
printf 'independent_verification=PASS
' | tee evidence/independent-verification.txt

This checklist proves identity and selected controls from a clean shell. It deliberately does not infer “secure production” from one pass; it verifies the evidence claims this capstone actually makes.

3. Compare original and recovered state

cat evidence/backups/original-after-backup.json
cat evidence/incidents/recovered-state.json
cat evidence/incidents/recovered-runtime.txt
cat evidence/incidents/recovery-time.txt

Record whether the counter matches the backup point and whether any post-backup write is absent as expected. That observation closes the RPO/RTO exercise.

4. Final operational review questions

Review question Required answer
What is deployed? Exact image index digest, platform used by current host, source SHA
How was it built? Builder driver/version, BuildKit evidence, pinned base, no secret build args
What is inside? SBOM + time-bounded vulnerability scan
Who/what approved identity? Cosign verification identity/key plus local-lab limitation
Where is state? Named volume, ownership expectations, backup archive/checksum
Where are config/secrets? Config file and runtime secret mount; secret absent from image/env evidence
How is it exposed? Loopback-only published port and two scoped networks
How does it fail/recover? Health/process/network/storage drill evidence + restore
How is it bounded? Read-only rootfs, non-root, caps, NNP, CPU/memory/PIDs, bounded logs
How do we rollback? Select earlier verified digest; consider data/schema compatibility independently
What is not solved? HA, external TLS, central observability, enterprise secrets/signing, distributed data

5. Upgrade and patch process

1. Read Engine/Compose/Buildx/BuildKit/scanner/signer release notes and advisories.
2. Capture current production digests, versions, daemon/context, backups, and rollback subject.
3. Update reviewed base/tool references in a branch; never mutate the running container in place.
4. Build a new immutable candidate from an exact source revision.
5. Test, scan, generate/inspect attestations, sign, and review exceptions.
6. Promote the same digest; deploy by digest in a staging/controlled environment.
7. Verify health, data compatibility, logs/resources, and external request path.
8. Roll forward or roll back by verified digest; handle database migration rollback separately.
9. Archive evidence and update the accepted-risk/readiness record.

6. Retention and backup policy template

Release evidence retention: <organization policy>
Image digests retained: current + rollback window
SBOM/provenance/signature/scan: retain with release record
Application logs: bounded local buffer + central retention in production
Backups: frequency based on RPO; immutable/off-host copy in production
Restore drills: scheduled and measured; archive checksum + application validation required
Secret rotation: owner + cadence + revocation evidence
Vulnerability exceptions: owner + reason + expiry + compensating control
Incident evidence: preserve IDs/digests/timestamps/logs before destructive recovery

7. Incident entry points

docker context show
docker version
docker info
APP_REF="<release@sha256:...>" docker compose -p ch42cap ps
docker inspect <exact-container-id>
docker logs --timestamps --since 15m <exact-container-id>
docker events --since 15m --filter container=<exact-container-id>
docker network inspect <exact-network>
docker volume inspect <exact-volume>
docker stats --no-stream <exact-container-id>
docker buildx imagetools inspect <release@sha256:...>

These are evidence entry points, not a substitute for a runbook. The next action depends on which layer owns the symptom.

8. Final cleanup preflight

Before deleting anything, inventory only expected lab identities and make sure the final evidence packet is copied wherever you intend to retain it.

docker ps -a --filter label=devops.academy.lab=ch42
docker ps -a --filter name=ch42
docker volume ls --filter name=ch42
docker network ls --filter name=ch42
docker buildx ls | grep ch42 || true
ls -lh evidence/backups/state.tgz evidence/backups/state.tgz.sha256 cosign.pub

9. Bounded cleanup — recovery project first

SUBJECT="$(sed -n 's/^subject=//p' evidence/subject.txt)"
STATE_VOLUME=ch42_state_restore APP_REF="$SUBJECT"   docker compose -p ch42restore -f compose.yaml -f compose.recovery.yaml down

docker volume rm ch42_state_restore 2>/dev/null || true

10. Bounded cleanup — primary runtime and persistent lab data

APP_REF="$SUBJECT" docker compose -p ch42cap down
# Explicitly remove only the capstone volume after backup/restore evidence has been accepted.
docker volume rm ch42cap_state 2>/dev/null || true

docker rm -f ch42-registry 2>/dev/null || true
docker volume rm ch42_registry_data 2>/dev/null || true
docker buildx rm ch42-builder 2>/dev/null || true

docker compose down intentionally does not use --volumes; persistent data is removed in a separate, named step after the recovery review. No Docker-wide prune is needed.

11. Bounded cleanup — temporary credentials and local objects

rm -f cosign.key
# Keep cosign.pub and evidence if retaining the review packet.
docker image rm "$SUBJECT" 2>/dev/null || true
# Verify that the intended lab resources are gone; do not delete anything unexpected.
docker ps -a --filter name=ch42
docker volume ls --filter name=ch42
docker network ls --filter name=ch42
docker buildx ls | grep ch42 || true

12. Production handoff

Area Handoff obligation
Release Digest-first deployment, signed evidence, rollback subject retained
Patching Version/advisory review, rebuild from source, no in-place container patching
Secrets Move from host-file lab secret to managed secret infrastructure; define rotation/revocation
Registry TLS/auth/retention/replication and immutable-digest policy
Data Production database/volume ownership, backups, off-host retention, restore drills
Observability Central logs/metrics/traces, alert ownership, retention and privacy policy
Runtime Least privilege, resource envelope, health/shutdown contracts, context/API access controls
Incidents Evidence-first runbook, escalation, backup restore and digest rollback
Platform boundary Kubernetes/Helm/OpenShift or other orchestrator for fleet-level scheduling/policy/HA

13. What the complete Docker course now gives you

You can reason from Docker client/context and daemon architecture through images, BuildKit, Compose, networking, storage, resource governance, observability, security, rootless/user namespaces, secrets, vulnerability management, SBOM/provenance/signatures, containerd internals, daemon/API automation, CI isolation, release promotion, production contracts, Swarm estates, performance, and incident response. The capstone connects those topics through one requirement-to-evidence chain.

The next platform courses should not erase these Docker fundamentals. Kubernetes, Helm, and OpenShift add scheduling, reconciliation, policy, and cluster abstractions, but immutable image identity, least privilege, persistent-data semantics, supply-chain evidence, observability, and evidence-first troubleshooting remain the underlying operating discipline.

14. Course completion criterion

The Docker course is complete when you can hand the packet to another engineer and they can independently verify the release subject, source/build lineage, security and runtime controls, state and backup/restore behavior, observed incident evidence, accepted limitations, and cleanup boundary without relying on undocumented facts in your head or mutable-only tags.

Knowledge check

What is the strongest proof that no release rebuild occurred during promotion?

Why is docker compose down --volumes deliberately avoided in final cleanup?

What should an independent verifier reconstruct first in a clean shell?

Why does the handoff still point to Kubernetes/Helm/OpenShift after a successful Compose capstone?

What is the final capstone’s core operating principle?

Official references and version notes

Baseline checked:

2026-09-22. The capstone records the learner’s actual versions before execution. Reference baselines used for compatibility discussion are Docker Engine/CLI 29.8.1, BuildKit 0.33.0, Buildx 0.37.1, Docker Compose 5.5.1, Trivy 0.74.0, and Cosign 3.1.3. Packaged Docker Desktop/Engine installations may expose different bundled containerd/runc versions, so the evidence packet records what the active daemon actually reports.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.