ChatGPT解决这个技术问题 Extra ChatGPT

How to get docker-compose to always re-create containers from fresh images?

My docker images are built on a Jenkins CI server and are pushed to our private Docker Registry. My goal is to provision environments with docker-compose which always start the originally built state of the images.

I am currently using docker-compose 1.3.2 as well as 1.4.0 on different machines but we also used older versions previously.

I always used the docker-compose pull && docker-compose up -d commands to fetch the fresh images from the registry and start them up. I believe my preferred behaviour was working as expected up to a certain point in time, but since then docker-compose up started to re-run previously stopped containers instead of starting the originally built images every time.

Is there a way to get rid of this behaviour? Could that way be one which is wired in the docker-compose.yml configuration file to not depend "not forgetting" something on the command line upon every invocation?

ps. Besides finding a way to achieve my goal, I would also love to know a bit more about the background of this behaviour. I think the basic idea of Docker is to build an immutable infrastructure. The current behaviour of docker-compose just seem to plain clash with this approach.. or do I miss some points here?


S
Stefan Hanke

docker-compose up --force-recreate is one option, but if you're using it for CI, I would start the build with docker-compose rm -f to stop and remove the containers and volumes (then follow it with pull and up).

This is what I use:

docker-compose rm -f
docker-compose pull
docker-compose up --build -d
# Run some tests
./tests
docker-compose stop -t 1

The reason containers are recreated is to preserve any data volumes that might be used (and it also happens to make up a lot faster).

If you're doing CI you don't want that, so just removing everything should get you want you want.

Update: use up --build which was added in docker-compose 1.7


Yeah, actually this is what I do in CI as well. Not sure why I didn't mention that...
@dnephin docker-compose run -d doesn't exists ? You want to say docker-compose up -d no ?
if you run docker-compose pull before docker-compose rm -f you can save even more time
What is the the -d flag at the end do?
"-d Detached mode: Run containers in the background,"
J
Jens Habegger

The only solution that worked for me was the --no-cache flag:

docker-compose build --no-cache

This will automatically pull a fresh image from the repo. It also won't use the cached version that is prebuilt with any parameters you've been using before.


In addition, under Windows 10 it can help to set the DNS server in the settings from Automatic to Fixed or from Fixed to Automatic.
Worked for me on OS X building with docker-comopse version 2.
Worked on OS X docker.
This worked for me in Mac OS as well. The accepted answer did not.
This does not work in docker-compose 1.29.2.
s
snrlx

By current official documentation there is a short cut that stops and removes containers, networks, volumes, and images created by up, if they are already stopped or partially removed and so on, then it will do the trick too:

docker-compose down

Then if you have new changes on your images or Dockerfiles use:

docker-compose build --no-cache

Finally:docker-compose up

In one command: docker-compose down && docker-compose build --no-cache && docker-compose up


docker-compose build --no-cache is needed only if there are changes on Dockerfiles.
Indeed, Victor. Thanks! I thought that it was also necessary after updating a module/application that is executed when the container starts up. For these cases, before running docker-compose up, is necessary to rebuild the services with docker-compose build.
M
Muhammad Dyas Yaskur
docker-compose up --build

OR

docker-compose build --no-cache

When possible, please make an effort to provide additional explanation instead of just code. Such answers tend to be more useful as they help members of the community and especially new developers better understand the reasoning of the solution, and can help prevent the need to address follow-up questions.
Actually this answer was the most clean and clear to me.
My understanding is that the --build command rebuilds, but uses cached parts, and thus not fully "recreates" the containers. Only the second does what I want.
Doesnt work on docker on centos 7, had to rm -rf /var/lib/docker
Two commands are completely different! docker-compose up --build uses cache images if it is exist. docker-compose build --no-cache never uses cache.
A
Adrian Mouat

You can pass --force-recreate to docker compose up, which should use fresh containers.

I think the reasoning behind reusing containers is to preserve any changes during development. Note that Compose does something similar with volumes, which will also persist between container recreation (a recreated container will attach to its predecessor's volumes). This can be helpful, for example, if you have a Redis container used as a cache and you don't want to lose the cache each time you make a small change. At other times it's just confusing.

I don't believe there is any way you can force this from the Compose file.

Arguably it does clash with immutable infrastructure principles. The counter-argument is probably that you don't use Compose in production (yet). Also, I'm not sure I agree that immutable infra is the basic idea of Docker, although it's certainly a good use case/selling point.


Thanks for the answer. I think it would be really useful to force it at the configuration level, eg. to enforce it for a database container and disable recreation by default for the app containers..
--force-recreate doesn't work for me ... Image is not pulled even though a newer version is out there...
@lisak I never said it pulled new images. It doesn't. It just starts new containers using whatever image is locally available. You'll need to run docker pull manually.
O
OurangZeb Khan

I claimed 3.5gb space in ubuntu AWS through this.

clean docker

docker stop $(docker ps -qa) && docker system prune -af --volumes

build again

docker build . docker-compose build docker-compose up


P
Pawel
docker-compose up --build --force-recreate

o
obotezat

Also if the compose has several services and we only want to force build one of those:

docker-compose build --no-cache <service>

This does not work in docker-compose 1.29.2.
M
Mathias Asberg
$docker-compose build

If there is something new it will be rebuilt.