Dash0 Raises $110M Series B at $1B Valuation

  • 7 min read

How to Update a Running Docker Container

Docker containers are immutable at runtime, you can't patch a running container the way you'd apt upgrade a server. The image layer is read-only, so "updating" a container always means pulling a newer image and recreating the container from it. Once you understand that, the rest is just knowing which command to use.

This article covers the pull-recreate pattern for standalone containers and Docker Compose, explains the separate docker update command (which does something much narrower than you might expect), and flags a few things that trip up newcomers.

Why you can't update a container in-place

When Docker starts a container, it layers a thin writable layer on top of a read-only image. Any changes you make inside a running container, installing packages, editing files, live in that writable layer, not in the image. Stop the container and recreate it, and that writable layer is gone.

This is intentional. Immutability makes containers reproducible and predictable. The trade-off is that updating software means replacing the container entirely, not patching it while it runs. The image is the unit of change.

The pull-recreate pattern

For a standalone container, updating means three steps: pull the new image, stop the old container, start a new one from the updated image.

Pull the latest version of an image:

bash
1
docker pull nginx:latest

Expected output:

1234
latest: Pulling from library/nginx
Digest: sha256:...
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

If the digest on the last line shows Status: Image is up to date, there's nothing new to deploy.

Now stop and remove the old container, then start a fresh one:

bash
123
docker stop my-nginx
docker rm my-nginx
docker run -d --name my-nginx -p 80:80 nginx:latest

The new container uses the updated image. Your volumes are unaffected because they exist independently of the container lifecycle, as long as you mounted them with -v or --mount, they'll reattach when the new container starts.

Updating with Docker Compose

Docker Compose makes this easier. Pull updated images for all services in your compose.yaml:

bash
1
docker compose pull

Then recreate any containers whose image changed:

bash
1
docker compose up -d

Compose compares the image digest of the running container against the local image. If they differ, it recreates the container. If nothing changed, it leaves it alone.

To combine both steps and always pull before starting, useful in CI/CD pipelines or when you want to guarantee you're running the latest image:

bash
1
docker compose up -d --pull always

The --pull always flag tells Compose to pull the image from the registry before starting each service, regardless of whether a local copy exists. Without it, Compose uses whatever image is already cached locally, which might be stale if someone else pushed a new version since you last pulled.

Note: docker compose (no hyphen) is the current Compose plugin, available since Docker Engine 20.10. If you're on an older setup and docker compose isn't recognized, you may still have the legacy docker-compose standalone binary, but upgrading is worth it.

For more on working with logs across multi-container Compose setups, see Docker Compose Logs: A Complete Guide.

What docker update actually does

Here's the common source of confusion: docker update does not update the container's image. It updates runtime resource constraints on a running container, things like CPU and memory limits.

bash
1
docker update --memory 512m --cpus 1.5 my-nginx

This is useful when you need to adjust resource limits without stopping a container. You can change memory limits (--memory, --memory-swap), CPU limits (--cpus, --cpu-shares, --cpu-period, --cpu-quota), restart policy (--restart), and block I/O weight (--blkio-weight).

What docker update cannot do: change the image, environment variables, port bindings, volume mounts, or network configuration. For any of those, you need the full pull-recreate cycle.

If you want to observe how these resource constraints affect your containers in practice, Monitoring Container Resource Usage with Docker Stats walks through how to track CPU and memory consumption over time.

Common pitfalls

The latest tag is just a convention, some images update it frequently, others rarely. Always check docker pull output for Status: Downloaded newer image vs Status: Image is up to date before assuming you got something new. For production deployments, pinning to a specific digest (nginx@sha256:...) is more reliable than relying on a tag.

If you pull a new image but don't remove the old container, docker run with the same name fails. Use docker rm first, or use docker run --rm for containers you don't need to keep around after they stop.

Files written inside a container and not in a mounted volume are gone when the container is removed. If your container writes state to /app/data without a volume mount, that data disappears on every update. Mount a volume for anything you care about before you start relying on container restarts.

Finally, if your pipeline runs docker compose up -d without pulling first, it'll start containers from the locally cached image, which may be hours or days old. Add --pull always or a separate docker compose pull step before up in any automated workflow.

Final thoughts

Updating a Docker container is always a replace operation, not a patch operation. The pull-recreate pattern, docker pull, stop, remove, start, applies whether you're managing containers directly or through Compose. Use docker compose up --pull always to keep it a one-liner in automation. Reserve docker update for the narrower job it's designed for: adjusting CPU and memory limits on a running container without restarting it.

Once you're deploying containers regularly, you need to know what actually happened after the restart. Dash0 gives you container metrics, logs, and traces in a single view, so you can confirm the new image is healthy and catch regressions early. For a deeper look at what's available from your containers out of the box, see Mastering Docker Logs: A Comprehensive Tutorial.

Start a free trial to see your container metrics, logs, and traces in one view.