๐Ÿš€ Day 19 Task: Docker for DevOps Engineers

๐Ÿš€ Day 19 Task: Docker for DevOps Engineers

ยท

4 min read

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 the db 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.

  1. 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:~$
  1. 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:~$
  1. 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."

ย