706

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!

8
  • 106
    docker-compose up --build Commented Apr 22, 2019 at 14:53
  • 39
    Just to clarify upper comment: docker-compose up --build rebuild all containers. Use docker-compose up --build <service_name> as stated in @denov comment. Commented Sep 20, 2020 at 22:22
  • 1
    docker-compose up --build <service_name> does not work if you have a docker-compose.yml with containers coming from a container-registry Commented Oct 22, 2020 at 16:30
  • 9
    docker-compose build --no-cache when you want to build from the first level. Commented Dec 28, 2020 at 10:04
  • 2
    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. Commented Jan 12, 2022 at 15:51

15 Answers 15

850

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.

Sign up to request clarification or add additional context in comments.

3 Comments

@evgpisarchik The orders a bit out, it should be docker-compose build --no-cache service1 service2
why y'all talking about service? the question was to rebuild container not service
@temirbek container inside compose is defined under services block
553

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>..]

4 Comments

I'm confused how this answers the question. How do we rebuild just the one container?
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
Wait a sec, this recreates container, it is not equivalent to build --no-cache option, unless the command description is completely wrong
what exactly does 'Dont start lined services' mean?
95

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 

4 Comments

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.
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
I needed to actually run docker-compose build <id/name> before up to rebuild the changed Dockerfile.
but then you are stopping a live container, which isn't really feasible for a live site.
77

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.

Comments

24

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

3 Comments

aL_eX, flag -a (means all) you can select only the one you need by specifying its id
@aL_eX I agree this method is somewhat dangerous. But this is working for sure. Other answers do not remove images.
Brandon Bertelsen, ok, but to remove all images use -a (--all) - "Remove all unused images not just dangling ones"
12
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.

Comments

12

You can use:

docker-compose build

And if you are using a docker profile:

docker-compose --profile profile_name build

Comments

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)

Comments

7

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.

Comments

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

Comments

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.

Comments

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

Comments

0

It appears you're aiming to rebuild and restart only the nginx service in your Docker Compose setup without affecting other services.I proposed bash script accomplishes this task efficiently. Here's your proposed script:

#!/bin/bash

# Check if the service name is provided
if [ -z "$1" ]; then
    echo "Usage: $0 <service_name>"
    exit 1
fi

# Stop the existing container of the specified service
docker-compose stop "$1"

# Rebuild the specified service
docker-compose build --no-cache "$1"

# Start only the specified service without starting linked services
docker-compose up -d --no-deps "$1"

You can save this script to a file, for example, rebuild_service.sh, make it executable using chmod +x rebuild_service.sh, and then use it to rebuild and restart a specific service in your Docker Compose setup by passing the service name as an argument, like so:

./rebuild_service.sh nginx

Just replace Nginx with the name of the service you want to rebuild and restart. This script ensures that only the specified service is affected, saving time and avoiding unnecessary restarts of other services.

Comments

0

all of the services in my docker-compose.yml file were defined with container labels such as some-container:latest. None of the solutions here worked in order to update my docker compose services to the latest versions available publicly. Instead I had to do

docker compose pull
docker compose up -d --force-recreate

After this, all of my running docker compose services were updated to the latest available versions.

Comments

-13

Only:

$ docker-compose restart [yml_service_name]

1 Comment

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.