Docker containers are a popular way to deploy applications because they provide a consistent runtime environment regardless of the host system. However, when you need to update a file inside a container, it's often necessary to rebuild the entire container, which can be time-consuming and disruptive to your deployment process.
Docker solves our problem of running an application anywhere we want without relying on external dependencies. All our dependencies are pre-packaged into the docker image, so running a container of the image without issues is easy.
Though, a limitation that we may hit as we go on is a hot-reload feature in a local environment. Normally when we save a file and open it, the latest updates can be viewed. But once an image is built in a docker system, the contents cannot be changed, and we can't view the latest update without creating a new image. This is actually the original principle of Docker. We'll circumvent this by using docker volumes, which will help us update files inside the container while it runs.
Pre-Requisites
- Docker
- NodeJS (
V18
preferred)
New to Docker? Check out Docker for Beginners
Implementation
Using the docker command
- For single-container workloads
Using a Docker volume is one way to update files inside a container without rebuilding it. A volume is a separate storage area mounted into a container, allowing you to share files between the host system and the container.
To use a volume, first, create a volume using the following command.
docker volume create myvolume
Then, start a container and mount the volume using the command below.
docker run -v myvolume:/path/to/mount myimage
Now, any changes you make to the files inside the mounted directory on the host system will be reflected in the container. For example, you could edit a file on the host system, and the changes would be visible inside the container.
Using the docker-compose command
- For multi-container workloads
Another way to update files inside a container without rebuilding it is to use Docker Compose. Docker Compose is an extension of Docker itself, which is used for creating multi-container Docker applications and running them in any Docker-supported systems.
To use Docker Compose, first define your application in a YAML file. Also, specify the containers needed and any volumes or other configuration options.
For example:
Then, start the containers using the following command.
docker-compose up
The Unorthodox Method - Rebuilding a Container
Another rarely used way is by rebuilding a container. The volume workaround is perfectly sufficient for our uses. Rebuilding our container is also an option if, by chance, the volume method does not work.
The COPY
command can be used to copy files from the host system into the container. To use the COPY
command, add the following line to your Dockerfile
:
COPY /path/on/host /path/in/container
When you build the container, the files from the host system will be copied into the container. If you need to update the files, you can simply rebuild the container, and the new files will be copied.
Also read: Using Traefik Reverse Proxy for Docker Containers
Hot Reload in Docker Container - Demo
For this demo, let's set up an express-based nodejs application.
Creating the app
Create a project directory where we will store our files.
mkdir -p projects/docker-reload
npm init -y
Let's install our dependencies using the command below.
npm i express nodemon
Create a file called hello.js
and paste the following.
Running the app
Run the following command to start the app.
npm start
If you go to http://localhost:3000
, it should look something like this:
Implementing live reload
Let's add a script in package.json
, so that hello.js
is constantly monitored for changes, and any new changes are reflected immediately.
Open the package.json
file and the following into the scripts section.
After you add it, the file should look something like this:
At this point, if we make any changes, they won't be reflected in the app. So, execute the following command.
npm run dev
Now, make a change to the hello.js
file. I'll change the response message to something more reflective of the current demo.
[nodemon] restarting due to changes...
[nodemon] starting `node hello.js`
Example app listening on port 3000
Dockerizing
Now that our application is prepared, we can simply dockerize it, and it will be ready for deployment.
Create a Dockerfile
and paste the following.
Run the following commands to build the image and run it.
- To build
docker build -t hello-world-node:v1 . -f Dockerfile
- To run
docker run -v `pwd`:/src/app/ -p 3001:3000 hello-world-node:v1
Run the above command in the project directory. The pwd
command will extract our current directory path, and the -v
argument will bind our project directory with the app directory inside the container.
In this article,
we learned to create a nodejs express application, implemented live reloading and subsequently deployed a docker image
for it.
Dynamically updating files inside docker containers without rebuilding them is important for containerized application development and deployment. There are a few techniques you can use to accomplish this, including using volumes, Docker Compose, and the COPY
command in your Dockerfile
. Each technique has advantages and disadvantages, so choose the one that works best for your particular use case.
Thank you for reading! Subscribe using either of the buttons below or leave a comment if you face any difficulties in the process.