In my previous blog, we delved into types of docker volumes, discussed the importance of docker volumes, and how data persistence is achieved in the container world. Now, In this blog, we are going to deep dive into one of its types i.e., Host bind mount.
What is Host Bind Mount?
Host bind mount as the name suggests, allows us to mount ( attach ) a folder of our host operating system directly to the container. Now you may ask why. why do I use host bind mount when I am good to go with named volumes? The simple answer is - that host bind mount can be helpful while developing your application and running it inside a container.
Development Example
Suppose, You are developing a basic node app, You write a docker file, create a docker image and start a container from it.
Now that your application is live and running inside a container, You want to make some changes to the source code of the application and after doing it, you expect that change should reflect in the container as well.
To achieve this, There are two ways -
Old School Way - You rebuild the entire image from scratch whenever any change is made to the application code and restart the container with new image. but this approach is not efficient and quite repetitive.
Efficient way - Instead of rebuilding again and again, Just attach the project folder ( where our application code resides ) to the container working directory ( where our application code is stored inside the container ). This way any change that is done to the host folder will also reflect to the container's folder. It's like our host directory is now synced with the container directory. Any change we make in our file at the host will also get reflected in the container directory.
Host bind mount in Action
Project Directory Structure - use npm init
to initialize a node project. ( make sure you have node and npm installed in your operating system)
webapp/
βββ app.js
βββ public/
β βββ index.html
βββ Dockerfile
βββ docker-compose.yml
βββ package.json
Step 1: Create an HTML File
In your project directory (webapp
), create an HTML file called index.html
with some initial content:
<!DOCTYPE html>
<html>
<head>
<title>Real-Time Update Demo</title>
</head>
<body>
<h1>Hello, Docker Bind Mounts!</h1>
<p>This content is from the initial HTML file.</p>
</body>
</html>
Step 2: Create a Node.js Server
In your Node.js application (e.g., app.js
), set up a simple HTTP server using the express
framework to serve the HTML file:
NOTE: To use express js you first need to install it using the command npm install express
const express = require('express');
const app = express();
const port = 8080;
app.use(express.static('public'));
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Step 4: Create a Dockerfile
In the webapp
directory, create a Dockerfile
to define your container:
# Use an official Node.js runtime as the base image
FROM node:14
# Set the working directory in the container
WORKDIR /app
# Copy package.json and package-lock.json to the container
COPY package*.json ./
# Install application dependencies
RUN npm install
# Copy the entire project directory into the container
COPY . .
# Expose a port for the web application
EXPOSE 8080
# Start the application
CMD ["node", "app.js"]
Step 4: Create a Docker Compose File
In the webapp
directory, create a docker-compose.yml
file to specify the container and the bind mount:
version: '3'
services:
web:
build: .
ports:
- "8080:8080"
volumes:
- ./index.html:/app/public/index.html # here we are mounting the html file only, you can also mount the entire directory here.
Now just run docker-compose up --build
Step 5: Observe Real-Time Changes
With the container running, open a web browser and navigate to http://localhost:8080
to see the initial content from the index.html
file.
Now, let's demonstrate real-time changes:
Open the
index.html
file on your host system using a text editor.Modify the content inside the HTML file, for example, change the
<h1>
text or add new elements.Save the changes.
As soon as you save the changes to the index.html
file on your host system, the web page displayed in your browser will automatically update to reflect the changes. This happens in real time, without needing to restart the container.
Conclusion
In the above example, we demonstrated how Docker's host bind mounts enable real-time updates for web content, but you can apply a similar approach to any files or directories in your container, making it a valuable tool for various development and testing scenarios.
By using host bind mounts, you can instantly see the impact of changes made to your application's assets, configurations, or code, making the development and testing process much more efficient and convenient.