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'sbuildattribute 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 atargetattribute as well.targetis 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!