← Field Notes
Published 9 min read

The Checklist I Use Before Updating a Container

A practical change process for protecting state, controlling scope, validating outcomes, and rolling back Docker Compose services deliberately.

In this article
  1. 1. Define exactly what is changing
  2. 2. Read the application upgrade path
  3. 3. Record what is running now
  4. 4. Protect the service state
  5. 5. Identify the rollback boundary
  6. Image-only rollback
  7. Data rollback
  8. 6. Confirm the environment is healthy first
  9. 7. Pull deliberately
  10. 8. Recreate the smallest useful unit
  11. 9. Watch the first startup closely
  12. 10. Validate the outcome by layer
  13. 11. Keep the old path until confidence is earned
  14. The condensed checklist
  15. What changed my approach
  16. Related articles
  17. Official references
  18. Security note
  19. AI transparency

Pulling an image is easy. Proving the service survived the change is the real update.

docker compose pull is easy to type.

The update becomes real when the new image changes a database, removes an option, expects a different configuration, or interrupts a service that someone else relies on.

I used to treat container updates like package downloads followed by restarts. That worked until an update crossed a migration boundary and the old image was no longer a complete rollback plan.

Now I use a short change checklist. It is intentionally smaller than an enterprise change-management process, but it forces me to answer the questions that matter before the service is unavailable.

1. Define exactly what is changing

I start with one sentence:

Update one named service from the currently running image to the reviewed target release.

That sentence prevents a routine application update from quietly becoming four changes at once.

Before the maintenance window, I record:

  • the service being changed;
  • the current image tag or digest;
  • the intended target version;
  • the Compose project involved;
  • dependencies that may restart;
  • the expected user-visible interruption;
  • the workflow that must work afterward.

This matters because a Compose project is a connected application model. Services can share networks, volumes, configuration, and dependencies. A broad command or an unrelated configuration edit can recreate more than the container I intended to touch.

Docker documents that docker compose pull downloads images without starting containers. The actual replacement occurs when Compose creates or recreates the service, such as through docker compose up. Keeping those steps conceptually separate makes the maintenance easier to reason about.

2. Read the application upgrade path

The image registry tells me that a new image exists. It does not tell me whether my current deployment can move to it safely.

I review the application’s official release notes and upgrade documentation for:

  • breaking configuration changes;
  • database or schema migrations;
  • removed environment variables;
  • renamed paths or settings;
  • new permissions, capabilities, or device requirements;
  • supported source versions;
  • known regressions;
  • required intermediate releases;
  • rollback restrictions.

I am especially cautious with moving tags such as latest and with major-version jumps. A tag is convenient for selecting an image, but it is not a substitute for reviewing what changed.

Pinning a version does not eliminate maintenance. It makes the decision visible and gives the deployment a known reference point.

3. Record what is running now

A rollback should not depend on memory.

Before pulling anything, I capture the current state using commands appropriate to the environment:

docker compose ps
docker compose images
docker compose config --images

I also save the current deployment configuration in version control or another protected record.

docker compose config is useful because Docker describes it as the command that parses, resolves, merges, and renders the effective Compose model. That means it can expose results that are easy to miss when several Compose files, environment substitutions, profiles, or shorthand declarations are involved.

For a quick validation without printing the full resolved configuration:

docker compose config --quiet

I treat rendered configuration carefully. It may contain resolved values that should not be copied into tickets, screenshots, public notes, or unsecured logs.

4. Protect the service state

The image is often the most replaceable part of a stateful container.

The valuable parts may include:

  • a database;
  • application configuration;
  • uploaded or user-created data;
  • encryption material;
  • authentication state;
  • integration settings;
  • metadata that would be expensive to rebuild.

I identify which locations are authoritative and how the application expects them to be backed up.

A filesystem copy of a live database directory is not automatically a consistent recovery point. Some applications require an export, snapshot procedure, quiesced service, or database-native backup. The backup method has to match the data format and the application’s consistency requirements.

I also verify that the recovery material is accessible without relying on the container I am about to replace.

The question is not merely, “Do I have another copy?”

It is, “Can I use this copy to restore the service after the new version changes its data?”

5. Identify the rollback boundary

There are two very different rollback situations.

Image-only rollback

The container is replaced, but persistent data remains compatible with the prior release. Returning to the previous image and configuration may be enough.

Data rollback

The application migrates or rewrites persistent state. Returning to the old image may fail because the old application cannot interpret the new data.

That distinction changes the plan.

Before updating, I write down:

  • the previous image reference;
  • whether the application supports downgrade;
  • whether a migration is reversible;
  • which backup or snapshot corresponds to the old version;
  • how much new activity could be lost during a restore;
  • the condition that will trigger rollback instead of continued troubleshooting.

“Use the old image” is not a rollback plan after an irreversible migration.

6. Confirm the environment is healthy first

An update is a poor time to discover that a storage mount was already failing.

Before the change, I confirm:

  • required filesystems and network storage are mounted;
  • the host has enough free space for new image layers and temporary data;
  • dependent databases and upstream services are healthy;
  • required networks, secrets, devices, and sockets are present;
  • the current service is stable enough to provide a meaningful baseline;
  • monitoring is working before I rely on it to judge the update.

Updating on top of an existing fault makes every symptom ambiguous.

7. Pull deliberately

When the review is complete, I pull the intended service rather than refreshing the entire host without distinction:

docker compose pull service-name

Docker’s current Compose documentation confirms that a service name can be supplied to limit the pull. Dependencies are not automatically included unless the chosen command and options request them.

After the pull, I confirm what image was resolved and compare it with the target I intended to deploy.

For higher assurance, image digests can provide a more exact identity than a mutable tag. Docker Compose also exposes configuration options related to resolving or locking image digests. Whether that level of pinning is worthwhile depends on the service and how the environment is maintained.

8. Recreate the smallest useful unit

Where the application permits it, I update one service or one tightly coupled stack at a time.

A typical targeted recreation may look like:

docker compose up -d service-name

Docker documents that compose up recreates an existing service when its image or configuration has changed while preserving mounted volumes. That preservation is useful, but it is not the same as proving the persistent data remains application-compatible.

I avoid mixing unrelated changes into the same window:

  • no casual host upgrade;
  • no simultaneous storage migration;
  • no firewall redesign;
  • no unrelated Compose cleanup;
  • no mass image pruning before validation.

Small scope gives every result more meaning.

I also avoid using docker compose restart when I actually changed the image or Compose configuration. Docker explicitly notes that configuration changes are not applied by a simple restart.

9. Watch the first startup closely

The first startup after an update is where migrations, permission changes, and dependency failures usually announce themselves.

I watch logs immediately:

docker compose logs --follow service-name

I look for:

  • migration start and completion messages;
  • repeated restarts;
  • permission or ownership errors;
  • missing configuration;
  • failure to connect to storage or a database;
  • unsupported-version warnings;
  • authentication or certificate failures;
  • a service that appears healthy only because the failing feature has not been used yet.

A quiet log is encouraging, not conclusive.

10. Validate the outcome by layer

A running container is not the same as a working service.

My post-update validation crosses several layers:

LayerValidation
RuntimeContainer remains running and reports the expected health state
LogsNo unresolved migration, permission, storage, or dependency errors
StorageRequired mounts and persistent data are present
ApplicationAuthentication and the primary workflow succeed
ClientA real client completes the task the service exists to provide
IntegrationDependent services can still exchange data or requests
MonitoringMetrics, checks, and alerts still behave as intended

The test should match the service.

For a media application, opening the dashboard is weaker evidence than starting playback from a normal client. For a monitoring platform, viewing the interface is weaker than confirming new data arrives and an expected test condition is detected.

I define that validation before the update so I do not lower the standard after something looks mostly functional.

11. Keep the old path until confidence is earned

I do not immediately prune old images, delete the recovery copy, or remove compatibility notes.

First I allow enough time for delayed problems to appear:

  • scheduled jobs;
  • background indexing;
  • certificate renewal;
  • remote clients;
  • integrations that run periodically;
  • database maintenance;
  • notifications and alerts.

The appropriate observation period depends on the service. The principle is simple: cleanup should follow confidence, not create it.

The condensed checklist

Before updating:

  • Define the exact service and target version.
  • Review official release notes and the supported upgrade path.
  • Record the current image and effective Compose configuration.
  • Protect application state with an appropriate recovery method.
  • Identify the downgrade and data-rollback boundary.
  • Confirm storage, dependencies, monitoring, and free space are healthy.

During the update:

  • Pull only the intended image or stack.
  • Confirm the resolved target.
  • Recreate the smallest useful unit.
  • Watch first-start logs and migrations.

After the update:

  • Validate runtime, logs, storage, application, client, and integrations.
  • Confirm monitoring still observes the service.
  • Preserve rollback material through the observation period.
  • Record the result and any new recovery limitation.

What changed my approach

Container updates became calmer once I stopped treating them as downloads followed by restarts.

A stateful container update is a small migration. The image changes, but the real risk lives in configuration, persistent data, dependencies, and assumptions about rollback.

The checklist does not prevent every failure. It makes the failure easier to understand and the recovery less improvised.

Official references

Security note

All commands use generic service names and omit real registry locations, credentials, hostnames, project names, backup destinations, filesystem paths, and application identities. Effective Compose output and operational records should be treated as potentially sensitive.

AI transparency

AI assisted with research, structure, and copy editing. The update sequence, rollback concerns, and validation checks are based on maintaining containerized services in my own homelab. Docker command behavior was reviewed against the official Docker documentation on July 24, 2026.

JO

Written by

Jessie Owens

I run Eldritch IT and write about the systems, repairs, infrastructure decisions, and business lessons behind the work.