We all love Docker, it makes deployment a lot easier. However, when it comes to test small changes, it can be cumbersome to rebuild and rerun the containers manually. Luckily Docker already addressed this issue for us.
Prerequisites
- Installed Docker Compose version 2.22.0 or greater
If you already have Docker on your machine, please verify it's version:
docker compose version
Otherwise follow the official installation instructions.
Getting started
For hot container replacement, we have to modify the project's compose.yml
(or docker-compose.yml
). Apply the following syntax to the container you want to update frequently:
<your-custom-service>:
image: <your-custom-image-name>
build: <relative-path-to-your-service>
# hot container replacement
develop:
watch:
- path: <relative-path-to-your-service>
action: <your-action>
And run the project in develop mode:
docker compose watch
As it can be seen, the develop
attribute does the magic, but let me explain it's parts. It has a watch
attribute taking a list of attributes. For each sub attribute, we have to define the path
and the action
. The idea is what should happen when a file changed under the path
.
Docker Compose comes with the following actions:
rebuild
- stops the service, triggers it'sbuild
attribute and restarts it with the newly created image.sync
- it keeps the service running, but copies the changed files into the container. Hence the container's file system usually differs from the host machine's, we must provide atarget
attribute as well.target
is the destination path of the changed files.sync+restart
- likesync
, but it restarts the container. Note that it's available with Docker Compose version 2.23.0 and later
Wait for a second! What if there are files under path
, but we don't want the action
executed in their case? If the build
directory contains .dockerignore
, then that files are already excluded.
Alternatively, one can use the ignore
attribute. It takes a list of .dockerignore
like patterns. Like bellow:
develop:
watch:
- path: <relative-path-to-your-service>
action: <your-action>
ignore:
- <your-files-to-be-ignored>
compose.yml
is correct with a tool like YAMLlintUse case examples
sync action
You can watch an example here.
sync+restart action
You can read about it here.
rebuild action
You can read about it here.
Limitations
When you run Docker in develop mode, there is no detached mode. If you want to use the terminal further, you have to open another terminal session.
Furthermore when you terminate the process, Docker keeps running the services. So make sure you run docker compose down
after you done.
Known issues
If one uses Docker on a virtual machine or on WSL, while developing on host machine, his changes won't get detected. He must work directly on the VM or Docker has to be installed locally.
References
Thank you for reading! Keep coding!