I have a docker-compose.yml
file that contains 4 containers: redis
, postgres
, api
and worker
.
During the development of the worker
container, I often need to restart it in order to apply changes. Is there any good way to restart a single container (e.g. worker
) without restarting the others?
It is very simple: Use the command:
docker-compose restart worker
You can set the time to wait for stop before killing the container (in seconds)
docker-compose restart -t 30 worker
Note that this will restart the container but without rebuilding it. If you want to apply your changes and then restart, take a look at the other answers.
The other answers to restarting a single node are on target, docker-compose restart worker
. That will bounce that container, but not include any changes, even if you rebuilt it separately. You can manually stop
, rm
, create
, and start
, but there are much easier methods.
If you've updated your code, you can do the build and reload in a single step with:
docker-compose up --detach --build
That will first rebuild your images from any changed code, which is fast if there are no changes since the cache is reused. And then it only replaces the changed containers. If your downloaded images are stale, you can precede the above command with:
docker-compose pull
To download any changed images first (the containers won't be restarted until you run a command like the up
above). Doing an initial stop is unnecessary.
And to only do this for a single service, follow the up or pull command with the services you want to specify, e.g.:
docker-compose up --detach --build worker
Here's a quick example of the first option, the Dockerfile is structured to keep the frequently changing parts of the code near the end. In fact the requirements are pulled in separately for the pip install
since that file rarely changes. And since the nginx and redis containers were up-to-date, they weren't restarted. Total time for the entire process was under 6 seconds:
$ time docker-compose -f docker-compose.nginx-proxy.yml up --detach --build
Building counter
Step 1 : FROM python:2.7-alpine
---> fc479af56697
Step 2 : WORKDIR /app
---> Using cache
---> d04d0d6d98f1
Step 3 : ADD requirements.txt /app/requirements.txt
---> Using cache
---> 9c4e311f3f0c
Step 4 : RUN pip install -r requirements.txt
---> Using cache
---> 85b878795479
Step 5 : ADD . /app
---> 63e3d4e6b539
Removing intermediate container 9af53c35d8fe
Step 6 : EXPOSE 80
---> Running in a5b3d3f80cd4
---> 4ce3750610a9
Removing intermediate container a5b3d3f80cd4
Step 7 : CMD gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0
---> Running in 0d69957bda4c
---> d41ff1635cb7
Removing intermediate container 0d69957bda4c
Successfully built d41ff1635cb7
counter_nginx_1 is up-to-date
counter_redis_1 is up-to-date
Recreating counter_counter_1
real 0m5.959s
user 0m0.508s
sys 0m0.076s
-no-cache
option? Say I added something into my package.json
and need to reRUN npm install
but the Dockerfile
itself hasn't changed
COPY
command, that will break the cache automatically.
COPY
command in your Dockerfile. The git pull
will update the package.json file and the build cache will break when docker sees you copy in a different file.
ADD
instead of COPY
but apparently the latter is a best practice so I'll go for it!
ADD
will have the same result as COPY
on the cache bust, but (as suggested in the best practices link) most don't need the extra capabilities so I don't even bother mentioning it.
To restart a service with changes here are the steps that I performed:
docker-compose stop -t 1 worker
docker-compose build worker
docker-compose up --no-start worker
docker-compose start worker
docker-compose up -d --build
and it will rebuild everything and restart any changed containers. No need for the stop first, with downtime, and separate create and start commands.
up
will only recreated the container that had been changed and therefore needed a restart.
docker-compose up -d --build
will often re-compile the project.
Following command
docker-compose restart worker
will just STOP and START the container. i.e without loading any changes from the docker-compose.xml
STOP is similar to hibernating in PC . Hence stop/start will not look for any changes made in configuration file . To reload from the recipe of container (docker-compose.xml) we need to remove and create the container (Similar analogy to rebooting the PC )
So commands will be as following
docker-compose stop worker // go to hibernate
docker-compose rm worker // shutdown the PC
docker-compose create worker // create the container from image and put it in hibernate
docker-compose start worker //bring container to life from hibernation
rm
line option -f
comes handy (no prompt) and with current docker create
and start
is merged as up
(so in total we have 3 commands not 4), and for up
option -d
is useful (execution is in the background).
Since some of the other answers include info on rebuilding, and my use case also required a rebuild, I had a better solution (compared to those).
There's still a way to easily target just the one single worker
container that both rebuilds + restarts it in a single line, albeit it's not actually a single command. The best solution for me was simply rebuild and restart:
docker-compose build worker && docker-compose restart worker
This accomplishes both major goals at once for me:
Targets the single worker container Rebuilds and restarts it in a single line
Hope this helps anyone else getting here.
Restart Service with docker-compose file
docker-compose -f [COMPOSE_FILE_NAME].yml restart [SERVICE_NAME]
Use Case #1: If the COMPOSE_FILE_NAME is docker-compose.yml
and service is worker
docker-compose restart worker
Use Case #2: If the file name is sample.yml
and service is worker
docker-compose -f sample.yml restart worker
By default docker-compose looks for the docker-compose.yml
if we run the docker-compose
command, else we have flag to give specific file name with -f [FILE_NAME].yml
The answer's here are talking about the reflection of the change on the docker-compose.yml file.
But what if I want to incorporate the changes I have done in my code, and I believe that will be only possible by rebuilding the image and that I do with following commands
1. docker container stop
docker stop container-id
2. docker container removal
docker rm container-id
3. docker image removal
docker rmi image-id
4. compose the container again
docker-compose up container-name
docker-compose up [service key]
Simple 'docker' command knows nothing about 'worker' container. Use command like this
docker-compose -f docker-compose.yml restart worker
Restart container
If you want to just restart your container:
docker-compose restart servicename
Think of this command as "just restart the container by its name", which is equivalent to docker restart
command.
Note caveats:
If you changed ENV variables they won't updated in container. You need to stop it and start again. Or, using single command docker-compose up will detect changes and recreate container. As many others mentioned, if you changed docker-compose.yml file itself, simple restart won't apply those changes. If you copy your code inside container at the build stage (in Dockerfile using ADD or COPY commands), every time the code changes you have to rebuild the container (docker-compose build).
Correlation to your code
docker-compose restart
should work perfectly fine, if your code gets path mapped into the container by volume directive in docker-compose.yml
like so:
services:
servicename:
volumes:
- .:/code
But I'd recommend to use live code reloading, which is probably provided by your framework of choice in DEBUG mode (alternatively, you can search for auto-reload packages in your language of choice). Adding this should eliminate the need to restart container every time after your code changes, instead reloading the process inside.
After making changes, you need to pull the changes into the server and then reacreate the container. So as the documentation shows:
docker-compose pull worker && docker-compose up -d --no-deps worker
pull worker
will make only this project to be pulled to the server, and --no-deps
will prevent from restart containers the worker
container depends on.
Success story sharing
docker-compose restart
commands will NOT apply any changes. "If you make changes to yourdocker-compose.yml
configuration these changes are not reflected after running this command." Therefore usedocker-compose up -d --build
. docs.docker.com/compose/reference/restartdocker ps -a
restart
doesn't apply changes even if you already ran adocker-compose build <container name>
and this is a non-working/incorrect answer.