Docker for DevOps Engineers Part-3

Docker-Volume

A Docker Volume is a storage mechanism to persist data generated by containers, ensuring it is not lost when containers stop or are deleted.

Key Points:

  • Purpose: Data persistence, sharing between containers, and better performance.

  • Creation: docker volume create my_volume

  • Usage: Attach to a container:

      docker run -d -v my_volume:/app/data my_image
    
  • Management:

    • List: docker volume ls

    • Inspect: docker volume inspect my_volume

    • Remove: docker volume rm my_volume

    • Clean up: docker volume prune

Use volumes to separate data from containers for easier management and durability.

Docker Network

A Docker Network allows containers to communicate with each other or external systems. It provides connectivity and isolation for containers.

Key Points:

  • Types of Networks:

    1. Bridge: Default network type for standalone containers. Containers can communicate within the same network.

    2. Host: Shares the host's network namespace, removing network isolation.

    3. None: Disables networking for the container.

    4. Overlay: Used for communication between containers across multiple hosts in a swarm.

    5. Macvlan: Assigns a MAC address to containers, allowing them to appear as physical devices on the network.

Common Commands:

  1. List Networks:

     docker network ls
    
  2. Create a Network:

     docker network create my_network
    
  3. Run a Container in a Network:

     docker run --network my_network my_image
    
  4. Connect a Container to a Network:

     docker network connect my_network my_container
    
  5. Inspect a Network:

     docker network inspect my_network
    
  6. Remove a Network:

     docker network rm my_network
    

Use Cases:

  • Isolate services for security.

  • Enable communication between multi-container applications.

  • Facilitate communication across hosts in a swarm.

Task-1

  • Create a multi-container docker-compose file that will bring UP and bring DOWN containers in a single shot ( Example - Create application and database container )

1. Create a docker-compose.yml File

Below is an example docker-compose.yml file:

version: '3.8'

services:
  app:
    image: node:16    # Replace with your application's image or build context
    container_name: app_container
    ports:
      - "3000:3000"    # Map port 3000 of the container to port 3000 of the host
    volumes:
      - ./app:/usr/src/app   # Mount the local 'app' directory
    command: sh -c "npm install && npm start"   # Example app command
    depends_on:
      - db             # Ensure the database starts before the app
    networks:
      - app_network

  db:
    image: mysql:8.0
    container_name: db_container
    environment:
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: app_db
      MYSQL_USER: user
      MYSQL_PASSWORD: user_password
    volumes:
      - db_data:/var/lib/mysql   # Persist database data
    ports:
      - "3306:3306"   # Expose MySQL
    networks:
      - app_network

networks:
  app_network:       # Define a custom network
    driver: bridge

volumes:
  db_data:           # Named volume for database persistence

2. Commands to Bring the Application Up and Down

  1. Start the Application in Detached Mode:

     docker-compose up -d
    
  2. Scale the App Service (e.g., 3 replicas):

     docker-compose up -d --scale app=3
    
  3. View the Status of Containers:

     docker-compose ps
    
  4. View Logs for a Specific Service (e.g., app):

     docker-compose logs app
    
  5. Stop and Remove All Resources:

     docker-compose down
    

    This will remove containers, networks, and volumes associated with the application.


Directory Structure Example

Ensure your directory looks like this for the app service:

project-folder/
├── app/
│   ├── package.json       # Your Node.js application setup
│   ├── server.js          # Example Node.js server file
├── docker-compose.yml

Notes:

  • Replace node:16 and mysql:8.0 with appropriate images if using a different application or database.

  • Modify environment variables for security.

  • Use volumes to persist database data (db_data) and application code (./app).

Task-2

  • Learn how to use Docker Volumes and Named Volumes to share files and directories between multiple containers.

  • Create two or more containers that read and write data to the same volume using the docker run --mount command.

  • Verify that the data is the same in all containers by using the docker exec command to run commands inside each container.

  • Use the docker volume ls command to list all volumes and the docker volume rm command to remove the volume when you're done.

Step 1: Create a Named Docker Volume

Create a volume called shared_volume:

docker volume create shared_volume

Step 2: Run Two Containers Sharing the Same Volume

Run two containers (e.g., Alpine Linux) with the shared volume mounted.

Container 1:

docker run -dit --name container1 --mount source=shared_volume,target=/data alpine

Container 2:

docker run -dit --name container2 --mount source=shared_volume,target=/data alpine

Step 3: Write Data into the Volume

Write a file into the shared volume using container1:

docker exec container1 sh -c "echo 'Hello from Container 1!' > /data/shared_file.txt"

Step 4: Verify Data in Both Containers

Check the data inside the shared volume in container2:

docker exec container2 sh -c "cat /data/shared_file.txt"

You should see:

Hello from Container 1!

Now, write additional data from container2:

docker exec container2 sh -c "echo 'Hello from Container 2!' >> /data/shared_file.txt"

Verify the updated data in container1:

docker exec container1 sh -c "cat /data/shared_file.txt"

You should see:

Copy codeHello from Container 1!
Hello from Container 2!

Step 5: Manage Volumes

  1. List all Volumes:

     docker volume ls
    
  2. Remove the Volume (after stopping the containers):

     docker rm -f container1 container2  # Stop and remove containers
     docker volume rm shared_volume      # Remove the shared volume
    

Explanation

  • Named Volumes (shared_volume) are managed by Docker and allow multiple containers to share persistent data.

  • The --mount option ensures both containers access the same data directory (/data).

  • The docker exec command lets you run commands inside containers to verify the data.