Till now we have learned how to create docker-compose.yml file and pushed it to the Repository. Let's move forward and dig more on other Docker-compose.yml concepts. Aaj thodi padhai krte hai on Docker Volume & Docker Network ๐
"Welcome to a comprehensive guide on leveraging Docker Volumes and Named Volumes to facilitate seamless data sharing among containers. In this article, we delve into the intricacies of utilizing docker run --mount
commands to create interconnected containers capable of reading and writing data to a shared volume. Through practical examples, we explore the significance of data consistency verification using docker exec
commands, offering insights into efficient volume management with docker volume ls
and docker volume rm
commands. on this journey to enhance our understanding and mastery of data handling within Docker environments."
Docker-Volume
Docker allows you to create something called volumes. Volumes are like separate storage areas that can be accessed by containers. They allow you to store data, like a database, outside the container, so it doesn't get deleted when the container is deleted. You can also mount from the same volume and create more containers having same data.
Docker Network
Docker allows you to create virtual spaces called networks, where you can connect multiple containers (small packages that hold all the necessary files for a specific application to run) together. This way, the containers can communicate with each other and with the host machine (the computer on which the Docker is installed). When we run a container, it has its own storage space that is only accessible by that specific container. If we want to share that storage space with other containers, we can't do that.
Task-1: Create a multi-container docker-compose file
Step-1 Create a Dockerfile: Create a Dockerfile for the application:
ubuntu@ip-172-31-32-129:~/projects$ vim Dockerfile
# Use an official Node.js runtime as a parent image
FROM node:14
# Set the working directory in the container
WORKDIR /usr/src/app
# Copy package.json and package-lock.json to the working directory
COPY package*.json ./
# Install app dependencies
RUN npm install
# Bundle app source
COPY . .
# Expose port 80
EXPOSE 80
# Define the command to run your app
CMD [ "node", "app.js" ]
:wq
Step-2 Build the Docker image:
ubuntu@ip-172-31-32-129:~/projects$ sudo docker build -t node-app .
Successfully built f4db57af0eb9
Successfully tagged node-app:latest
ubuntu@ip-172-31-32-129:~/projects$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
node-app latest f4db57af0eb9 5 minutes ago 938MB
node 14 1d12470fa662 8 months ago 912MB
ubuntu@ip-172-31-32-129:~/projects$
Step-3 Create a Dockerfile for the database:
ubuntu@ip-172-31-32-129:~/projects$ vim Dockerfile.db
# Use an official MySQL image as a parent image
FROM mysql:8
# Environment variables
ENV MYSQL_ROOT_PASSWORD=root_password
ENV MYSQL_DATABASE=app_database
# Expose the MySQL port
EXPOSE 3306
:wq
Step-4 Build the Docker image for the database:
ubuntu@ip-172-31-32-129:~/projects$ docker build -t my-database -f dockerfile
Successfully built d8d495768c8f
Successfully tagged my-database:latest
ubuntu@ip-172-31-32-129:~/projects$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-database latest d8d495768c8f 56 seconds ago 619MB
node-app latest f4db57af0eb9 13 minutes ago 938MB
mysql 8 73246731c4b0 2 days ago 619MB
node 14 1d12470fa662 8 months ago 912MB
ubuntu@ip-172-31-32-129:~/projects$
Step-5 Create docker-compose.yml:
Let's Create a multi-container docker-compose file which will bring UP and bring DOWN containers in a single shot
example of a docker-compose.yml file that creates two containers, one for the application and one for the database.
ubuntu@ip-172-31-32-129:~/projects$ vim docker-compose.yml
yamlCopy codeversion: '3'
services:
app:
image: node-app
ports:
- "8080:80"
depends_on:
- db
networks:
- my_network
volumes:
- app_data:/app/data
db:
image: my-database
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: app_database
networks:
- my_network
volumes:
- db_data:/var/lib/mysql
networks:
my_network:
driver: bridge
volumes:
app_data:
db_data:
app
service uses an application image node-app, maps port 8080 on the host to port 80 on the container, and depends on thedb
service.db
service uses a database image my-database, sets environment variables for MySQL, and creates a named volume (db_data
) to persist database data.Both services are connected to a custom bridge network my-network, allowing them to communicate with each other.
Step-6 To bring up the containers, run:
ubuntu@ip-172-31-32-129:~/projects$ docker-compose up -d
Creating network "projects_default" with the default driver
Pulling web (jatin7011/node-todo:latest)...
latest: Pulling from jatin7011/node-todo
e7c96db7181b: Pull complete
748a7823a585: Pull complete
Digest: sha256:4995a80c850d9f8910b8561039a633b11b9b11d44b320de71120c4c5948083a8
Status: Downloaded newer image for jatin7011/node-todo:latest
Creating projects_web_1 ... done
ubuntu@ip-172-31-32-129:~/projects$
Step-7 To bring down the containers:
ubuntu@ip-172-31-32-129:~/projects$ docker-compose down
Stopping projects_web_1 ... done
Removing projects_web_1 ... done
Removing network projects_default
ubuntu@ip-172-31-32-129:~/projects$
Task-2: Volumes and Named Volumes to Synchronize Files Across Multiple Containers.
- Create a named volume:
ubuntu@ip-172-31-32-129:~$ docker volume create my_shared_volume
my_shared_volume
ubuntu@ip-172-31-32-129:~$ docker volume ls
DRIVER VOLUME NAME
local my_shared_volume
ubuntu@ip-172-31-32-129:~$
- Run containers using the named volume:
ubuntu@ip-172-31-32-129:~$ docker run -d --name container1 --mount source=my_shared_volume,target=/app/data node-app
d034f1af9f7ac01f539096c828bebd52323ee78df6600b9e8cda9ec36e2fe558
ubuntu@ip-172-31-32-129:~$ docker run -d --name container2 --mount source=my_shared_volume,target=/app/data my-database
baa8ac3ac6f3d88e25a9606513c580d7a5a793847a7f1406a26ae45932656346
ubuntu@ip-172-31-32-129:~$
- Clean up:
ubuntu@ip-172-31-32-129:~$ docker rm -f container1 container2
container1
container2
ubuntu@ip-172-31-32-129:~$ docker volume rm my_shared_volume
my_shared_volume
ubuntu@ip-172-31-32-129:~$
"In summary, this article explores the robust capabilities of Docker Volumes and Named Volumes for seamless file sharing among containers. Demonstrating the use of docker run --mount
commands, we established interconnected containers with data consistency verification through docker exec
. Additionally, easy volume management with commands like docker volume ls
and docker volume rm
enhances efficiency in Dockerized environments, offering a comprehensive guide to streamlined data handling."