577

There are scope of services which are defined in docker-compose.yml. These services have been started. I need to rebuild only one of these and start it without up other services. I run the following commands:

docker-compose up -d # run all services
docker-compose stop nginx # stop only one. but it is still running !!!
docker-compose build --no-cache nginx 
docker-compose up -d --no-deps # link nginx to other services

At the end I get the old nginx container. Docker-compose doesn't kill all running containers!

bschlueter
  • 3,817
  • 1
  • 30
  • 48
yuklia
  • 6,733
  • 5
  • 20
  • 26
  • 75
    `docker-compose up --build` – Jinna Balu Apr 22 '19 at 14:53
  • 29
    Just to clarify upper comment: `docker-compose up --build` rebuild all containers. Use `docker-compose up --build ` as stated in @denov comment. – Jsowa Sep 20 '20 at 22:22
  • 1
    `docker-compose up --build ` does not work if you have a docker-compose.yml with containers coming from a container-registry – chillwalker Oct 22 '20 at 16:30
  • 7
    `docker-compose build --no-cache` when you want to build from the first level. – hassanzadeh.sd Dec 28 '20 at 10:04
  • Should be easy to get these semantics straight (not you @yuklia - the compose team). Not sure why we still struggle with this in this millennium. – vincent Jan 12 '22 at 15:51
  • --build --force-recreate --no-deps don't rebuild :S on latest version. compare images before and after, are the same! – JRichardsz May 16 '22 at 15:22
  • Pull the image you want to rebuild first. Unless you specify this (using pull_policy: always) in your docker-compose file, docker-compose will just rebuild the existing image. – MDickten Apr 25 '23 at 09:20

13 Answers13

717

docker-compose up

$ docker-compose up -d --no-deps --build <service_name>

or newer versions of docker

$ docker compose up -d --no-deps --build <service_name>

--no-deps - Don't start linked services.

--build - Build images before starting containers.

el.severo
  • 2,202
  • 6
  • 31
  • 62
denov
  • 11,180
  • 2
  • 27
  • 43
459

With docker-compose 1.19 up

docker-compose up --build --force-recreate --no-deps [-d] [<service_name>..]

Without one or more service_name arguments all images will be built if missing and all containers will be recreated.

From the help menu

Options:
    -d, --detach        Detached mode: Run containers in the background,
                        print new container names. Incompatible with
                        --abort-on-container-exit.
    --no-deps           Don't start linked services.
    --force-recreate    Recreate containers even if their configuration
                        and image haven't changed.
    --build             Build images before starting containers.

Without cache

To force a rebuild to ignore cached layers, we have to first build a new image

docker-compose build --no-cache [<service_name>..]

From the help menu

Options:
    --force-rm              Always remove intermediate containers.
    -m, --memory MEM        Set memory limit for the build container.
    --no-cache              Do not use cache when building the image.
    --no-rm                 Do not remove intermediate containers after a successful build.

Then recreate the container

docker-compose up --force-recreate --no-deps [-d] [<service_name>..]
Scott Stafford
  • 43,764
  • 28
  • 129
  • 177
HarlemSquirrel
  • 8,966
  • 5
  • 34
  • 34
  • 7
    I'm confused how this answers the question. How do we rebuild just the one container? – Duncan Jones Feb 08 '19 at 20:58
  • 23
    You can rebuild only one container by appending it's name to the end of the command. `docker-compose up -d --force-recreate --build container_name` – HarlemSquirrel Feb 09 '19 at 02:25
  • 2
    Wait a sec, this *recreates **container***, it is not equivalent to `build --no-cache` option, unless the command description is completely wrong – Slav Mar 28 '20 at 05:58
92

This should fix your problem:

docker-compose ps # lists all services (id, name)
docker-compose stop <id/name> #this will stop only the selected container
docker-compose rm <id/name> # this will remove the docker container permanently 
docker-compose up # builds/rebuilds all not already built container 
tristanbailey
  • 4,427
  • 1
  • 26
  • 30
ArgonQQ
  • 1,917
  • 1
  • 11
  • 12
  • 19
    if you want to `stop` and `rm` all containers then you can use the command `docker-compose down`. Your solution is better if you only want to get rid of some. – hirowatari Oct 01 '16 at 17:43
  • 3
    This solution is a good fit for the setup where you don't want to stop the entire docker application and just recreate one of the services – bluesummers Aug 13 '19 at 13:00
  • 5
    I needed to actually run `docker-compose build ` before `up` to rebuild the changed Dockerfile. – Vajk Hermecz Feb 20 '20 at 22:58
  • but then you are stopping a live container, which isn't really feasible for a live site. – Gogol May 16 '23 at 21:52
72

As @HarlemSquirrel posted, it is the best and I think the correct solution.

But, to answer the OP specific problem, it should be something like the following command, as he doesn't want to recreate ALL services in the docker-compose.yml file, but only the nginx one:

docker-compose up -d --force-recreate --no-deps --build nginx

Options description:

Options:
  -d                  Detached mode: Run containers in the background,
                      print new container names. Incompatible with
                      --abort-on-container-exit.
  --force-recreate    Recreate containers even if their configuration
                      and image haven't changed.
  --build             Build images before starting containers.
  --no-deps           Don't start linked services.
Slavik Meltser
  • 9,712
  • 3
  • 47
  • 48
23

Maybe these steps are not quite correct, but I do like this:

stop docker compose: $ docker-compose down

WARNING: The following prune -a will delete all images, you may not want this as it could effect other projects. you can read more here

remove the container: $ docker system prune -a

start docker compose: $ docker-compose up -d

Sergey Ivchenko
  • 1,497
  • 12
  • 11
11
docker-compose stop nginx # stop if running
docker-compose rm -f nginx # remove without confirmation
docker-compose build nginx # build
docker-compose up -d nginx # create and start in background

Removing container with rm is essential. Without removing, Docker will start old container.

Nex
  • 361
  • 3
  • 10
8

For me it only fetched new dependencies from Docker Hub with both --no-cache and --pull (which are available for docker-compose build.

# other steps before rebuild
docker-compose build --no-cache --pull nginx # rebuild nginx
# other steps after rebuild, e.g. up (see other answers)
kmindi
  • 4,524
  • 4
  • 31
  • 47
6

The problem is:

$ docker-compose stop nginx

didn't work (you said it is still running). If you are going to rebuild it anyway, you can try killing it:

$ docker-compose kill nginx

If it still doesn't work, try to stop it with docker directly:

$ docker stop nginx

or delete it

$ docker rm -f nginx

If that still doesn't work, check your version of docker, you might want to upgrade.

It might be a bug, you could check if one matches your system/version. Here are a couple, for ex: https://github.com/docker/docker/issues/10589

https://github.com/docker/docker/issues/12738

As a workaround, you could try to kill the process.

$ ps aux | grep docker 
$ kill 225654 # example process id
user2707671
  • 1,694
  • 13
  • 12
6

Simply use :

docker-compose build [yml_service_name]

Replace [yml_service_name] with your service name in docker-compose.yml file. You can use docker-compose restart to make sure changes are effected. You can use --no-cache to ignore the cache.

FarhadMohseni
  • 395
  • 5
  • 8
5

You can use:

docker-compose build

And if you are using a docker profile:

docker-compose --profile profile_name build
Chels
  • 111
  • 1
  • 5
2

I suppose the image named nginx is defined in your docker-compose file. In this case, there is a key/value pair like this: image: repo_name. If this is the case, I suggest pulling the newer image first with docker pull repo_name. Then build the service docker-compose build nginx. This will then use the newly pulled image. Then you can docker-compose up -d nginx.

As a matter of fact, you don't need to stop the container at all while doing this.

(And if you do this a lot, take the trouble to clean out old images occasionally: docker image ls, and then docker image rm <id>for all the images where the value for TAG is <none>. If the image should still be in used regardless, Docker will tell you.)

EDIT: docker-compose stop doesn't "kill" (remove) containers, it just stops them. They're still there somehow, sort of suspended. If you want to really kill, i.e. remove containers, use docker-compose down instead; you'll see from the output that this command really gets rid of the containers.

MDickten
  • 105
  • 1
  • 10
1
docker image rm -f nginx

to remove the docker nginx and

docker-compose up -d

to recreate nginx while keeping the other services running

SyLaDe
  • 77
  • 11
-13

Only:

$ docker-compose restart [yml_service_name]
  • 5
    this will not build new changes. from the manual - If you make changes to your docker-compose.yml configuration these changes will not be reflected after running this command. – denov Mar 10 '17 at 22:00