Docker / Compose and reliable runtime contracts / Lesson 12
Release identity, replacement, and rollback
Plan a reviewable transition between known artifacts without assuming Compose provides automatic zero-downtime orchestration.
On this page
Lesson goals
- Separate artifact creation, runtime replacement, readiness, and rollback.
- Preserve data compatibility and bounded shutdown during a release.
A release needs more than a friendly tag
A release record connects source revision, resolved base inputs, built image identity, configuration revision, and target environment. The label parcel-api:release-a is only a readable example and can be moved; approve actual content identity before deployment. Runtime replacement should use the reviewed artifact rather than rebuilding from an operator's changing workspace. Separate who creates the artifact from who authorizes adoption, especially when the same daemon hosts several projects.
Document the intended lifecycle policy
The following model refers to an existing reviewed image and a bounded shutdown grace period. Restart policy addresses process exits; it does not validate application readiness or repair invalid configuration. A grace period must cover measured draining behavior and fit any outer platform deadline. The synthetic service has no durable state, so a real stateful application would additionally require explicit mounts, backup evidence, and compatibility rules.
name: parcel-lab
services:
api:
image: parcel-api:release-a
restart: unless-stopped
stop_grace_period: 20s
ports:
- "127.0.0.1:18080:8080"
release-a must already identify the intended local or registry artifact before an authorized replacement. This file neither builds nor deploys by being displayed. The 20-second grace period is illustrative and needs workload evidence; it does not guarantee the application drains successfully. A manually stopped service also has policy-specific behavior distinct from a crash.
Compare intended and current identities
Before a change, inspect the resolved image references and current service containers using the same project and file set. An image tag in configuration does not prove a running container has already adopted its latest content. After an approved replacement, compare the new container's image identity and required behavior with the release record. Preserve evidence from the previous instance when diagnosing a failed transition rather than overwriting it with repeated restarts.
docker compose -f compose.yaml config --images
docker compose -f compose.yaml ps --all
docker image inspect parcel-api:release-a --format '{{json .Id}}'
config --images reads the model; ps and image inspect query the authorized engine. Actual ids and state are not fabricated. A locally built image can lack registry RepoDigests until distribution, so choose identity evidence appropriate to the artifact rather than requiring a field that may legitimately be empty.
Replacement is not automatically a rolling deployment
A single Compose service replacement can interrupt traffic. depends_on, health checks, and restart settings do not by themselves provide a load balancer, traffic draining, replica scheduling, or a zero-downtime guarantee. Define the acceptable maintenance window or use an architecture that supports controlled traffic switching. Verify from the real consumer path, including startup, TLS, and required application behavior, before declaring the new version available.
Application rollback must respect data evolution
Restoring an older image can fail if the new version changed persisted data incompatibly. Prefer staged schema evolution where old and new application versions can overlap safely, and define when rollback is no longer possible. A backup is useful only when restore has been rehearsed within recovery objectives. Keep forward recovery, configuration reversal, traffic switching, and data restoration distinct; they carry different risk and should not be combined into an improvised cleanup command.
Common errors and fixes
The tag changed but requests still reach the old version.
- Why it happens
- The existing container retains its prior image identity or traffic still targets another instance.
- How to fix it
- Compare release identity, container image id, and consumer routing before another change.
- Prevent it next time
- Record adoption evidence separately from image publication.
Rollback starts but cannot read persisted data.
- Why it happens
- A newer release changed the data format beyond the older application's compatibility.
- How to fix it
- Follow the reviewed forward-recovery or restore plan for that data boundary.
- Prevent it next time
- Rehearse compatibility and state rollback limits before release.
A single-service replacement causes unexpected downtime.
- Why it happens
- Compose lifecycle settings were mistaken for a complete rolling traffic architecture.
- How to fix it
- Set an explicit maintenance or traffic-switching strategy and verify it.
- Prevent it next time
- State availability goals and test transitions under realistic traffic.
Check your understanding
1. What evidence distinguishes publication from adoption?
Show worked solution
Publication identifies the artifact available in a registry or local store. Adoption requires a running instance using that approved identity and passing the intended consumer checks. A release dashboard should record both stages so an available new image is not confused with the version currently serving users.
2. Why should a database migration be considered before image rollback?
Show worked solution
The old executable may not understand the new persisted schema or values. Determine whether the change was backward compatible, whether writes can safely continue, and which recovery path preserves business data. Replacing containers cannot itself reverse an incompatible data transformation or create a tested backup.
Key takeaways
- A release connects content identity, configuration, process state, and consumer behavior.
- Plan rollback around persistent data and availability requirements.