Kristof Jozsa
Kristof Jozsa

Reputation: 7452

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?

Upvotes: 474

Views: 780468

Answers (11)

Arash Foroughi
Arash Foroughi

Reputation: 187

For me in Gitlab-ci when I deployed the project to the server, it has needed to run docker-compose down, then docker system prune for removing caches and again run docker-compose up -d.

But I've just added docker-compose up --force-recreate and it did all of the above commands together. iI worked for me!

Upvotes: 4

Victor Timoftii
Victor Timoftii

Reputation: 3308

By current official documentation there is a shortcut 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

Upvotes: 164

flgn
flgn

Reputation: 1057

docker-compose up --build  # still use image cache

OR

docker-compose build --no-cache  # never use cache

Upvotes: 88

drizzt13
drizzt13

Reputation: 649

together with --force-recreate, you might want to consider using this flag too:

 -V, --renew-anon-volumes   Recreate anonymous volumes instead of retrieving
                            data from the previous containers.

I'm not sure from which version this flag is available, so check your docker-compose up --help if you have it or not

Upvotes: 7

Pawel
Pawel

Reputation: 18212

docker-compose up --build --force-recreate

Upvotes: 12

davidbonachera
davidbonachera

Reputation: 5640

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.

Upvotes: 485

obotezat
obotezat

Reputation: 1135

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

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

Upvotes: 3

OurangZeb Khan
OurangZeb Khan

Reputation: 1132

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

Upvotes: 8

dnephin
dnephin

Reputation: 28040

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

Upvotes: 476

Mathias Asberg
Mathias Asberg

Reputation: 3840

$docker-compose build

If there is something new it will be rebuilt.

Upvotes: -26

Adrian Mouat
Adrian Mouat

Reputation: 46470

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.

Upvotes: 41

Related Questions