Docker Compose Update Image: Pull and Recreate (2026)
To update a Docker Compose stack to new images, run docker compose pull and then docker compose up -d. pull downloads the newest image for each tag in your compose file. up -d recreates only the containers whose image changed and leaves the rest running. docker compose restart does not do this: it restarts the old container on the old image.
Named volumes and bind mounts are kept, so your data survives the update.
Quick reference
| Goal | Command |
|---|---|
| Update every service | docker compose pull && docker compose up -d |
| Same thing in one command | docker compose up -d --pull always |
| Update one service | docker compose pull web && docker compose up -d --no-deps web |
Rebuild services that use build: | docker compose up -d --build --pull always |
| Recreate containers without a new image | docker compose up -d --force-recreate |
| Remove old, unused images | docker image prune -f |
| See which image each container runs | docker compose images |
Update all services
1. Pull the new images
docker compose pull
This downloads the current image for every tag in docker-compose.yml. It does not touch running containers.
A pull only finds something new when the tag moves. nginx:latest or postgres:17 move with each release. A pinned tag such as postgres:17.6 never changes. To upgrade a pinned service, edit the tag in the file first. docker compose up -d then pulls the new tag by itself.
2. Recreate the containers
docker compose up -d
Compose compares each running container with the current image and configuration. If the image ID changed, it stops the old container, removes it and starts a new one from the new image. Containers that did not change keep running, and Compose prints Running for them.
3. Remove the old images (optional)
The previous image versions stay on disk as dangling images. Remove them:
docker image prune -f
Do this after you have checked that the new version works. The old image is your fastest rollback until you prune it.
All in one line
docker compose pull && docker compose up -d && docker image prune -f
docker compose up -d --pull always also pulls and recreates in one step.
Update a single service
docker compose pull web
docker compose up -d --no-deps web
--no-deps stops Compose from also recreating the services that web depends on, for example the database.
Why docker compose restart does not update
docker compose restart stops and starts the existing container. A container is tied to the image it was created from, so it comes back on the old version even after a pull. The same is true for docker compose stop and start. Only docker compose up creates new containers, and only new containers use the new image.
Force recreate
docker compose up -d --force-recreate
This recreates every container even when the image and the configuration did not change. Use it to reset a container to a clean filesystem, or when an environment file changed in a way Compose did not detect. It does not pull. Combine it with --pull always if you also want new images.
Services that build their image
A service with only build: and no image: has nothing to pull, so pull skips it. Rebuild instead, and pull a fresh base image while you do:
docker compose up -d --build --pull always
To rebuild without the build cache, run docker compose build --pull --no-cache and then docker compose up -d.
Set a pull policy in the compose file
pull_policy decides when docker compose up pulls:
services:
web:
image: nginx:1.29
pull_policy: daily # always | missing (default) | never | build | daily | weekly | every_12h
missing(the default) only pulls when the image is not on the machine. This is why a plainup -dnever updates alatesttag.alwayspulls on everyup.daily,weeklyandevery_<duration>pull when the last pull is older than that.
Roll back to the previous image
Note the exact image digest before you update:
docker image inspect --format '{{index .RepoDigests 0}}' nginx:latest
# nginx@sha256:3f1c...
If the new version breaks, pin that digest in the compose file and recreate:
services:
web:
image: nginx@sha256:3f1c...
docker compose up -d
If you have not run docker image prune yet, the old image is still local, so the rollback needs no download. Database images are the exception: a new major version often changes the data format on disk, and you cannot roll back without a backup. Back up the volume before you move a database to a new major version.
Is there downtime?
Yes, a few seconds per container. Compose stops the old container before the new one is ready. Compose has no rolling update for a single host. deploy.update_config only works in Docker Swarm.
To keep the gap short:
- Pull first, so the restart does not wait for a download.
- Add a
healthcheckand rundocker compose up -d --wait. The command returns when the new containers are healthy, so a script knows when the update is done.
Automatic updates
- Cron job. The simplest option. Run
cd /srv/app && docker compose pull -q && docker compose up -d && docker image prune -fat night. It updates moving tags only. - Renovate or Dependabot. Pin exact tags in git and let the bot open a pull request for each new version. You review and roll out the change like code. This is the safest option for databases.
- Watchtower. The original
containrrr/watchtowerrepository is archived on GitHub and gets no more updates. Do not use it for new setups.
Avoid automatic updates for databases and anything with a database migration. Update those by hand, after a backup.
Frequently asked questions
How do I update a Docker Compose image to the latest version?
Run docker compose pull to download the newest image for each tag, then docker compose up -d to recreate the containers whose image changed. docker compose up -d --pull always does both in one command. Volumes and bind mounts are kept.
Does docker compose up -d pull new images?
Not by default. The default pull policy is 'missing', so up only pulls an image that is not on the machine. Run docker compose pull first, or use docker compose up -d --pull always, or set pull_policy: always in the compose file.
Why is my container still on the old version after docker compose pull?
pull only downloads the image. The running container was created from the old image and keeps using it, and docker compose restart does not change that. Run docker compose up -d to recreate the container from the new image.
How do I update only one service in Docker Compose?
Run docker compose pull <service> and then docker compose up -d --no-deps <service>. --no-deps keeps Compose from recreating the services it depends on.
Will updating the image delete my data?
No. Named volumes and bind mounts survive container recreation, and Compose also carries over anonymous volumes unless you pass -V (--renew-anon-volumes). Data written inside the container filesystem but outside any volume is lost.
How do I roll back a Docker Compose update?
Pin the previous version in the compose file, by tag or by digest (image: nginx@sha256:...), and run docker compose up -d. Note the digest with docker image inspect before you update, and do not prune old images until the new version works.
Related
- Install Docker Compose: install and update Compose itself
- Docker Compose restart: restart commands and restart policies
- Docker Compose volumes: where your data lives during an update
- Start Docker containers on boot
Automated updates on Hostim.dev
Hostim.dev pulls and redeploys your containers when you push to your Git branch or Docker registry. No cron job, no Watchtower.