A Comprehensive Guide to Docker and Docker Commands with Examples

A Comprehensive Guide to Docker and Docker Commands with Examples

In the world of containerization, Docker has emerged as a powerful tool that revolutionized how software applications are developed, deployed, and managed. Docker provides a platform for packaging, distributing, and running applications inside lightweight, isolated containers. This blog will introduce you to Docker, its core concepts, and essential Docker commands with real-world examples.

What is Docker?

Docker is an open-source containerization platform that enables developers to package an application and its dependencies into a standardized unit called a container. Containers are isolated, lightweight, and portable, making it easier to develop, test, and deploy applications consistently across different environments.

1. Docker is an open-source containerization platform designed to create, deploy and run applications.

2. We can install docker on any OS however docker engine runs primarily on linux distribution.

3. Docker is a tool that performs OS-level virtualization.

4. It's written in Go language

Here's a breakdown of key Docker concepts:

1. Images:

An image is a read-only template containing the application and its dependencies. Docker images are the building blocks of containers and can be shared and versioned through container registries like Docker Hub.

2. Containers:

A container is a runnable instance of a Docker image. It encapsulates the application and its environment, providing isolation and reproducibility. Containers are ephemeral, meaning they can be started, stopped, and destroyed without affecting the host system.

3. Dockerfile:

A Dockerfile is a text file that defines the instructions to build a Docker image. It specifies the base image, application code, and any required configurations.

Docker architecture

Docker's architecture is fundamental to understanding how Docker works and how it enables containerization. Docker employs a client-server architecture with a combination of components that work together to manage containers efficiently. Let's explore the key components of Docker's architecture:

Docker Architecture diagram

  1. Docker Client:

    • The Docker client is the primary interface through which users interact with Docker. It allows users to issue commands to the Docker daemon to manage containers, images, networks, and other Docker resources.

    • The client communicates with the Docker daemon using the Rest API, which can be accessed via the command-line interface (CLI) or various Docker client libraries.

    • It can communicate with one or more daemons.

      Example:

        docker -H=remotedaemonengineurl:port 
        docker -H=10.23.21.1:2355 run nginx  :- connecting to daemon present 
        at another host and running image nginx
      
  2. Docker Daemon:

    • The Docker daemon, also known as the Docker engine, is a background service that manages Docker containers on a host system. It's responsible for creating, running, and managing containers based on user requests.

    • The daemon listens for Docker API requests and executes them, ensuring that containers are properly orchestrated.

  3. Docker Host:

    A Docker host is a physical or virtual server on which the core component of Docker runs, the Docker engine. The Docker engine encapsulates and runs workloads in Docker containers.

  4. Docker Registry:

    • A Docker registry is a repository for Docker images. It stores Docker images and allows users to push and pull images from it. Docker Hub is a popular public registry, but you can also set up private registries for your organization.

    • When you run a docker pull command, it fetches the image from the registry, and when you run docker push, it uploads the image to the registry.

  5. Docker Images:

    • Docker images are lightweight, read-only templates that contain an application and all its dependencies, including the operating system, libraries, and application code. Images are used to create Docker containers.

    • Images are typically built from a Dockerfile, which defines the instructions for creating the image layer by layer. Once created, images can be tagged, versioned, and shared.

  6. Docker Containers:

    • Containers are runnable instances created from Docker images. They encapsulate the application and its runtime environment.

    • Containers are isolated from each other and from the host system, ensuring that they do not interfere with one another. They have their own filesystem, network, and processes.

  7. Docker Network:

    • Docker provides networking capabilities that allow containers to communicate with each other and with the external world. By default, containers are isolated, but you can create custom networks to enable communication between specific containers.

    • Docker also supports bridge networks, overlay networks for container orchestration, and host networks for maximum network flexibility.

  8. Docker Volumes:

    • Docker volumes are used to persist data generated by containers. They provide a way to store and share data between containers and between the host and containers.

    • Volumes can be used to ensure that data is not lost when a container is stopped or removed, making them crucial for stateful applications.

  9. Docker Compose (Optional):

    • Docker Compose is a tool for defining and running multi-container applications. It uses a YAML file to define the services, networks, and volumes required for an application.

    • With Docker Compose, you can start and stop complex applications with a single command, making it a valuable tool for managing multi-container environments.

Understanding Docker's architecture is crucial for effectively using Docker to build, deploy, and manage containerized applications. By leveraging Docker's client-server model and its various components, developers and operators can harness the power of containerization to simplify application development and deployment workflows.

Now that you have an overview of Docker, let's dive into some essential Docker basic commands and examples.

Docker images:

Docker images are the building blocks of containers. They contain the application code, runtime, libraries, and system tools required to run an application.

There are three ways to create an image

  1. Take an image from docker hub

  2. create an image from DockerFile

    1. Create an image from an existing container

      1. Pulling an Image from a Registry:

      To get started with Docker, you often need to pull images from a registry. Docker Hub is a popular public registry. You can pull images using the docker pull command. For example, to pull the official Ubuntu image:

       docker pull ubuntu :- just download the image
       docker run -d jenkins :- search image in docker hub  download it 
       and also run it
      

      2. Listing Local Images:

      You can view the list of images downloaded on your local system using the docker images or docker image ls command:

       docker images
       docker search jenkins :- to find image on docker hub
      

      3. Tagging an Image:

      You can tag an image to give it a custom name and optionally a version. This is useful when you want to create a custom version of an image. For example:

       docker tag ubuntu my-ubuntu:1.0
      

      4. Building a Custom Image with Dockerfile:

      A Dockerfile is a text file that contains a set of instructions used to build a Docker image. Docker images are the foundation of containers, encapsulating the application code, runtime, libraries, and dependencies. Dockerfile instructions are executed to create layers, and these layers are cached for efficient image building. Let's explore the various parameters and common instructions used in Dockerfiles, along with examples for each.

      Dockerfile Basics:

      A Dockerfile typically starts with specifying a base image using the FROM instruction. This base image serves as the starting point for your custom image.

      Example:

       # Use an official Python image as the base image
       FROM python:3.9
      

      WORKDIR:

      The WORKDIR instruction sets the working directory inside the container. It is where commands will be executed.

      Example:

       WORKDIR /app
      

      COPY and ADD:

      The COPY and ADD instructions copy files or directories from the host system into the image.

      COPY Instruction:

      1. Basic Copying: The primary purpose of the COPY instruction is to copy files and directories from the host into the image. It's straightforward and does not perform any extraction or decompression of files.

      2. No Auto-Extraction: When you use COPY to copy a compressed file (e.g., a tar.gz archive) into the image, it remains compressed within the image. Docker does not automatically decompress such files.

Example:

        # Copy a file from the host to the image
        COPY myfile.txt /app/

ADD Instruction:

  1. Advanced Copying: The ADD instruction has additional features compared to COPY. It can copy files and directories like COPY, but it can also perform automatic extraction of common compression formats (e.g., .tar, .tar.gz, .tar.bz2, .zip) and automatically decompress them into the image.

  2. URL Support: ADD can fetch files and archives from URLs and automatically place them in the image. This can be useful when you want to download files during the image build process.

  3. Checksum Validation: ADD performs checksum validation on files downloaded from URLs to ensure data integrity.

Example:

        # Copy a compressed file and automatically extract it
        ADD myarchive.tar.gz /app/

Example with URL:

        # Download a file from a URL and place it in the image
        ADD https://example.com/myfile.txt /app/

Example:

        # Copy the current directory's contents into the container's working directory
        COPY . .

RUN:

The RUN instruction executes commands during the image build process. It is used for installing packages, updating the system, or performing other setup tasks.

Example:

        # Install required packages
        RUN apt-get update && apt-get install -y package-name

EXPOSE:

The EXPOSE instruction specifies which port(s) should be exposed by the container. It does not actually publish the ports, but it serves as documentation for the container's expected network behavior.

Example:

        # Expose port 80 for HTTP traffic
        EXPOSE 80

CMD and ENTRYPOINT:

Both CMD and ENTRYPOINT specify the command to be run when a container is started.

  • CMD provides default arguments to the command specified, and these arguments can be overridden when running the container.

    Example:

      CMD ["python", "app.py"]
    
  • ENTRYPOINT sets the primary command and its arguments, and any additional arguments provided when running the container are treated as arguments to this command.

    Example:

      ENTRYPOINT ["python", "app.py"]
      ENTRYPOINT ["sleep"]
      CMD ["5"]
      we can use entry point and cmd together it means we dont pass any value
      during docker run then cmd passed will be sleep 5 and suppose we pass
      docker run -d imgname 10 then cmd passed will be sleep 10
    

ENV:

The ENV instruction sets environment variables inside the container. These can be useful for configuration and runtime settings.

Example:

        ENV DB_HOST=localhost DB_PORT=5432

ARG:

The ARG instruction defines build-time variables in a Dockerfile. These variables can be used during the image build process and are typically set using the --build-arg flag when you build the image with the docker build command. These variables are not accessible in the running container.

Syntax:

        ARG variable_name[=default_value]
  • variable_name: The name of the build-time variable.

  • default_value (optional): An optional default value for the variable.

Usage:

        # Define a build-time variable with a default value
        ARG APP_VERSION=1.0
        # Use the build-time variable in the Dockerfile
        LABEL version=$APP_VERSION

When you build an image with this Dockerfile, you can pass a value for APP_VERSION using the --build-arg flag:

        docker build --build-arg APP_VERSION=2.0 -t my-image .

USER:

The USER instruction sets the user or UID (user identifier) that should run the subsequent instructions.

Example:

        USER myuser

VOLUME:

The VOLUME instruction creates a mount point within the container at which you can attach volumes.

Syntax:

        VOLUME /path/to/volume/directory

Example:

        # Create a volume at /app/data
        VOLUME /app/data

In the above example, a volume is created at the /app/data directory in the image. When a container is created from this image, you can use the -v or --volume option to map a host directory to the volume created in the image:

        docker run -v /host/data:/app/data my-image

This allows data to be shared between the container and the host system.

Dockerfile Example:

Here's an example of a complete Dockerfile for a simple Node.js application:

        # Use an official Node.js runtime as the base image
        FROM node:14

        # Set the working directory inside the container
        WORKDIR /app

        # Copy package.json and package-lock.json to the working directory
        COPY package*.json ./

        # Install app dependencies
        RUN npm install

        # Copy the rest of the application code
        COPY . .

        # Expose port 3000 for HTTP traffic
        EXPOSE 3000

        # Define the command to run the application
        CMD ["node", "app.js"]

This Dockerfile starts with a Node.js base image, sets up the working directory, installs dependencies, exposes a port, and specifies how to run the Node.js application.

Dockerfiles are a critical part of Docker's ecosystem, enabling you to create custom images tailored to your specific application requirements. By understanding and using Dockerfile instructions effectively, you can build efficient and reproducible Docker images for your containers.

Build the image using:

        docker build -t my-node-app .

5. Running a Container from an Image:

To create and run a container from an image, use the docker run command. For example, to run a container from the custom Node.js image created earlier:

        docker run -d -p 3000:3000 my-node-app

6. creating image from and container:-

To create image from an container, use the docker commit command. For example,

        docker commit  containername imagename
        containername :- the existing container from which you want to create image
        image name :- name which you want to keep for image.

7. Removing an Image:

You can remove an image using the docker rmi command followed by the image name or ID. Be cautious when removing images, as they can't be recovered. For example:

        docker rmi my-node-app
        to delete all image :-
        docker rmi -f $(docker images -q)
        docker  image prune :- to delete all unused image
        docker sytem prune :- removes everything which is unused

7. Exporting and Importing Images:

You can export an image to a tarball file and import it back into Docker. This can be useful for sharing images. To export an image:

        docker save -o my-node-app.tar my-node-app

To import the image from the tarball:

        docker load -i my-node-app.tar

8. Copying Files to/from Containers:

Sometimes you may need to copy files between your local system and a container. You can use the docker cp command to achieve this. For example, copying a file from a container to your local system:

        docker cp container_id:/path/to/file/on/container /path/on/local/machine

9. Multi-stage Builds:

Multi-stage builds allow you to create smaller and more efficient images by using multiple build stages. You can copy files from one stage to another. Here's an example Dockerfile for a Go application using multi-stage builds:

        # Build stage
        FROM golang:1.16 AS builder
        WORKDIR /app
        COPY . .
        RUN go build -o myapp

        # Final stage
        FROM alpine:latest
        COPY --from=builder /app/myapp /usr/local/bin/myapp
        CMD ["myapp"]

These examples cover various scenarios related to Docker images. Docker images are a powerful tool for packaging and distributing applications, and understanding how to work with them is essential for effective containerization and application deployment.

Containers:

Containers are lightweight, isolated, and portable environments that encapsulate an application and its dependencies, making it easier to develop, test, and deploy software consistently across different systems. Containers are a fundamental concept in Docker, and they offer numerous benefits for software development and deployment. Let's dive into containers with some examples.

Example 1: Running a Basic Container

Let's start with a simple example of running a container. We'll use the official Nginx image from Docker Hub.

        docker run -d -p 8080:80 nginx
  • docker run: This command is used to create and run containers from images.

  • -d: It runs the container in detached mode, meaning it runs in the background.

  • -p 8080:80: This option maps port 8080 on your host to port 80 in the container.

  • nginx: This is the name of the image to use.

This command will download the Nginx image if it's not already present on your system and then start a container based on that image. You can access the Nginx welcome page by opening a web browser and navigating to http://localhost:8080.

Example 2: Running an Interactive Container

You can run interactive containers to execute commands directly inside them. Here's an example using a basic Alpine Linux image:

        docker run -it --rm alpine sh
        docker run -it alpine sh :- will not remove conatiner while exit
        Exit Docker Container without Stopping It:-
        If you want to exit the container's interactive shell session, 
        but do not want to interrupt the processes running in it, 
        press Ctrl+P followed by Ctrl+Q. This operation detaches the 
        container and allows you to return to your system's shell
  • -it: This option makes the container interactive and allocates a pseudo-TTY for your terminal.

  • --rm: This option removes the container when you exit it.

  • alpine: The image name.

  • sh: The shell to run inside the container.

This command starts an Alpine Linux container and opens a shell session within it. You can interact with the container, run commands, and explore the Alpine Linux environment. When you exit the shell, the container is removed because of the --rm flag.

Example 3: Building a Custom Docker Image

To build a custom Docker image, you need a Dockerfile. Here's a simple example Dockerfile for a Node.js application:

        # Use an official Node.js runtime as a base image
        FROM node:14

        # Set the working directory
        WORKDIR /app

        # Copy package.json and package-lock.json to the working directory
        COPY package*.json ./

        # Install app dependencies
        RUN npm install

        # Copy the rest of the application code
        COPY . .

        # Expose a port
        EXPOSE 3000

        # Define the command to run your app
        CMD ["node", "app.js"]

You can build the Docker image using the docker build command:

        docker build -t my-node-app .

This command tells Docker to build an image based on the instructions in the Dockerfile and name it my-node-app.

Example 4: Running a Container from a Custom Image

Once you've built a custom image, you can run containers from it. Using the previously built my-node-app image:

        docker run -d -p 3000:3000 my-node-app

This command creates a container from the my-node-app image, running a Node.js application that listens on port 3000. You can access the application by opening a web browser and navigating to http://localhost:3000.

Example of docker run cmd:

        docker run --cpus=.5 ubuntu :- limits cpu usage to 50% of the system
        docker run --memory-100m ubuntu :- how much space it should occupy
        docker run -d --name test1 ubuntu  :---name is for naming a container
        docker start containername :- to start a container
        docker attach containername :- to go inside a container
        docker ps -a :- to see all running containers
        docker ps :- to see all containers
        docker stop containername  :- to stop a container
        docker rm containername :- to delete a container
        systemctl status docker :- to check status of docker engine
        systemctl start docker :- to start docker engine
        systemctl enable docker :- to enable docker 
        sudo usermod -aG docker ubuntu :- to execute command from ubuntu user (this
        is done by adding ubuntu in docker group ) this requires reboot sometimes.
        docker run -td ubuntu sleep 5 :- passing arguments while running 
        docker inspect containername or
         docker container inspect containername :- full details about container 
        docker logs containername  :-it shows log 
        docker exec conatinername cat etc/os-release :- to execute command on 
        docker container .
        docker exec -it containername /bin/bash :- to go inside a running container
        and excute shell commands
        docker run -v /opt/data:var/lib/mysql :- mapping the direction on host 
        container ( left is the host and right is container)
        docker run redis:4.0 ( 4.0 is version which one can specify)
        docker diff containername :- show diff between base image 
        used and container
        docker run -p 8080:8080 -v /root/myuser:/var/lib/jenkins -u root jenkins :-
        this will make sure the command will run using root user.
        docker run -e appcolor=blue imagename :- to pass an env variable
        docker exec -it conatinername env :- to know env values passed
        docker history image name :- to check the layered scenarios
        docker kill containerid :- to kill a docker container
        docker rm container :- to rm container
        docker container prune :- to remove all stopped containers

Example to run a MySQL image or any db which has env variable:-

        docker pull mysql:latest
        docker run -d \
          --name mysql-container \
          -e MYSQL_ROOT_PASSWORD=my-secret-pw \
          -p 3306:3306 \
          mysql:latest

Docker volumes:

Docker volumes are a way to persist data generated or used by containers. They provide a means to store and share data between containers, between the host system and containers, and to ensure data persists across container restarts and removals. this is a decoupled storageLet's explore Docker volumes with examples.

Example 1: Basic Volume Usage

In this example, we'll create a named volume and use it to persist data from a container. We'll use a simple Nginx container to demonstrate volume usage.

  1. Create a named volume:
        docker volume create mydata
  1. Run a container and mount the named volume:
        docker run -d -p 8080:80 -v mydata:/usr/share/nginx/html --name nginx-container nginx
  • -d: Run the container in detached mode.

  • -p 8080:80: Map port 8080 on the host to port 80 in the container.

  • -v mydata:/usr/share/nginx/html: Mount the mydata volume into the container at the /usr/share/nginx/html directory. This directory is the default location where Nginx serves web content.

  1. Create a file in the volume:
        docker exec -it nginx-container sh -c 'echo "Hello, Docker Volumes!" > /usr/share/nginx/html/index.html'
  1. Access the content through your web browser at http://localhost:8080.

When you stop and remove the nginx-container, the data in the volume (mydata) will persist, and you can easily reuse it with another container.

Example 2: Using Bind Mounts

Docker also allows you to use bind mounts to directly mount a directory from your host into a container. This is useful for development or when you want to share host files with a container.

  1. Create a directory on your host with some content:
        mkdir ~/myapp
        echo "This is my app's data" > ~/myapp/data.txt
  1. Run a container and mount the host directory:
        docker run -d -v ~/myapp:/app my-image
        some more docker volume commands:-
        docker run -d --name container2 --privileged=true --volumes-from container1
        ubuntu  :- container to container volume shared
        docker volume ls :- to list volumes
        docker volume rm volumename :- to delete volume
        docker volume inspect volumename:- to inspect volume
        docker volume prune :- to remove unused volumes

In this example, we're mounting the ~/myapp directory from the host into the /app directory in the container. Any changes made to data.txt on the host will be reflected inside the container, and vice versa.

Example 3: Docker Compose with Volumes

Docker Compose is a tool for defining and running multi-container applications. It's often used to manage volumes along with containers. Here's a simple docker-compose.yml file:

        yamlCopy codeversion: '3'
        services:
          web:
            image: nginx
            volumes:
              - mydata:/usr/share/nginx/html
        volumes:
          mydata:

This docker-compose.yml defines a named volume called mydata and mounts it into an Nginx container. Run the following command in the same directory as the docker-compose.yml file:

        docker-compose up -d

The Nginx container will serve content from the mydata volume. You can place files in the host directory mapped to mydata, and they will be accessible through the container.

These examples illustrate various ways to use Docker volumes for data persistence and sharing, which is crucial for managing stateful applications and ensuring that data remains available and consistent in containerized environments.

Docker Compose:

Docker Compose is a tool for defining and running multi-container applications. It uses a docker-compose.yml file to define the services, networks, and volumes that make up your application's containers and their configurations. Below, I'll explain various parameters and concepts used in a docker-compose.yml file, along with examples for each.

1. Version:

The version parameter specifies the version of the Docker Compose file format. Different versions may support different features and syntax. The version is specified at the top of the docker-compose.yml file.

Example:

        version: '3'

2. Services:

The services section defines the containers that make up your application. Each service has a name and a set of parameters, including the image to use, environment variables, ports, volumes, and more.

Example:

        services:
          web:
            image: nginx:latest
            ports:
              - "8080:80"
          app:
            image: my-app:latest
            environment:
              - DATABASE_URL=postgres://dbuser:dbpassword@db:5432/mydb

3. Networks:

The networks section defines custom networks for connecting services. It allows containers to communicate with each other. By default, Docker Compose creates a default network for your application.

Example:

        networks:
            mynetwork:
               driver: bridge

4. Volumes:

The volumes section defines named volumes or bind mounts. Named volumes are a way to persist data between container runs. Bind mounts map a host directory into a container.

Example:

        volumes:
          mydata:
            driver: local
          myappdata:
            driver: local
            driver_opts:
              type: none
              o: bind
              device: /path/on/host

5. Ports:

The ports parameter maps container ports to host ports. It allows you to expose container services to the host system.

Example:

        services:
          web:
            image: nginx:latest
            ports:
              - "8080:80"

6. Environment Variables:

The environment parameter sets environment variables within the container. It's used for configuring containerized applications.

Example:

        services:
          app:
            image: my-app:latest
            environment:
              - DEBUG=true
              - DATABASE_URL=postgres://dbuser:dbpassword@db:5432/mydb

7. Depends On:

The depends_on parameter defines dependencies between services. It ensures that one service starts only after another service has started.

Example:

        services:
          app:
            image: my-app:latest
            depends_on:
              - database
          database:
            image: postgres:latest

8. Command:

The command parameter allows you to override the default command defined in the container image. It's useful for specifying startup commands.

Example:

        services:
          app:
            image: my-app:latest
            command: npm start

9. Build:

The build parameter specifies a build context and Dockerfile to build a custom image for the service.

Example:

        services:
          app:
            build:
              context: ./my-app
              dockerfile: Dockerfile.prod

These are some of the key parameters and concepts used in a docker-compose.yml file. Docker Compose provides a flexible and convenient way to define and manage multi-container applications, making it easier to work with complex application architectures.

Example of docker compose file

A complete Docker Compose file can vary greatly depending on your specific application's requirements and components. However, I can provide you with a simple example of a Docker Compose file that defines a basic web application consisting of a web server and a database. In this example, we'll use an Nginx web server and a PostgreSQL database.

        version: '3'

        services:
          web:
            image: nginx:latest
            ports:
              - "80:80"
            volumes:
              - ./web-content:/usr/share/nginx/html
            networks:
              - mynetwork
            depends_on:
              - db

          db:
            image: postgres:latest
            environment:
              POSTGRES_DB: mydb
              POSTGRES_USER: dbuser
              POSTGRES_PASSWORD: dbpassword
            volumes:
              - postgres-data:/var/lib/postgresql/data
            networks:
              - mynetwork

        networks:
          mynetwork:
            driver: bridge

        volumes:
          postgres-data:
               driver: local
               driver_opts:
                 type: none
                 o: bind
                 device: /path/on/host

In this example:

  • We define two services: web and db.

  • The web service uses the official Nginx image, exposes port 80, and mounts a local directory (./web-content) as the Nginx web root.

  • The db service uses the official PostgreSQL image, sets environment variables for the database name, user, and password, and mounts a named volume (postgres-data) for database storage.

  • Both services are connected to a custom bridge network named mynetwork to allow communication between them.

  • The depends_on parameter ensures that the db service starts before the web service.

To use this Docker Compose file:

  1. Create a directory with the docker-compose.yml file and a subdirectory named web-content.

  2. Place your web application files in the web-content directory.

  3. Run the following command in the directory containing the docker-compose.yml file:

     docker-compose up -d
     docker-compose config : Validate the docker-compose file.
    

This will start the defined services in detached mode. You can then access your web application at http://localhost.

Please note that this is a simplified example, and real-world applications may have more complex configurations and additional services. You should adapt the Docker Compose file to meet your specific application's needs.

some docker-compose commands:
1. docker-compose up:

The docker-compose up command is used to start all the services defined in your docker-compose.yml file.

Example:

        docker-compose up
        docker-compose up -d :- Use the -d flag to run containers in detached mode

2. docker-compose down:

The docker-compose down command is used to stop and remove all containers defined in your docker-compose.yml file.

Example:

        docker-compose down
        docker-compose down --volumes

This command stops and removes containers, networks, and volumes created by docker-compose up. Use the --volumes option to remove volumes as well:

3. docker-compose ps:

The docker-compose ps command displays the status of containers defined in your docker-compose.yml file.

Example:

        docker-compose ps

This command shows the status (running, exited, etc.) of each service's container.

4. docker-compose logs:

The docker-compose logs command displays the logs for all containers or a specific service.

Example:

        docker-compose logs
        docker-compose down --volumes

To view logs for a specific service (e.g., web):

5. docker-compose build:

The docker-compose build command builds Docker images for services defined in your docker-compose.yml file.

Example:

        docker-compose build

This command rebuilds images for all services. You can specify a specific service to rebuild:

        docker-compose build web

6. docker-compose exec:

The docker-compose exec command allows you to run commands inside a running container.

Example:

        docker-compose exec web ls /app

This command runs ls /app inside the web service's container.

7. docker-compose up --scale:

The docker-compose up --scale command lets you specify the number of containers to run for a service.

Example:

        docker-compose up --scale web=3

This starts three instances of the web service, effectively running three containers for that service.

8. docker-compose down -v:

The docker-compose down -v command stops and removes containers, networks, and volumes, including named volumes.

Example:

        docker-compose down -v

Use this command when you want to completely remove all resources created by Docker Compose.

These are some of the most commonly used Docker Compose commands. Docker Compose provides a flexible and efficient way to manage complex multi-container applications, making it easier to work with Docker in development and production environments.

Dockerhub:

Docker Hub is a cloud-based registry service for storing and sharing Docker container images. It provides a centralized location where you can find, distribute, and manage Docker images. Here, I'll provide you with some examples of how to use Docker Hub for various tasks.

1. Search for Docker Images on Docker Hub:

You can search for Docker images available on Docker Hub using the docker search command:

        docker search <image-name>
        docker search ubuntu

For example, to search for Ubuntu images:

This command will display a list of Ubuntu images available on Docker Hub along with their names, descriptions, and star ratings.

2. Pull Docker Images from Docker Hub:

You can pull Docker images from Docker Hub to your local machine using the docker pull command:

        docker pull <image-name>:<tag>
        docker pull nginx:latest :-to pull the official Nginx image:

This command downloads the latest Nginx image from Docker Hub to your local Docker image repository.

3. Push Docker Images to Docker Hub:

If you have custom Docker images that you want to share with others, you can push them to Docker Hub. To push an image, you first need to tag it with your Docker Hub username or organization name:

        docker tag <image-name>:<tag> <username>/<image-name>:<tag>

For example, if you have a custom image named my-app:

        docker tag my-app:latest myusername/my-app:latest

Next, log in to Docker Hub using the docker login command:

        docker login

Provide your Docker Hub username and password when prompted.

Finally, push the image to Docker Hub:

        docker push <username>/<image-name>:<tag>
        docker push myusername/my-app:latest

4. Run Containers from Images on Docker Hub:

You can run containers from Docker images hosted on Docker Hub using the docker run command. Specify the image name to run a container from that image:

        docker run -d <username>/<image-name>:<tag>

For example, to run a container from the official one image:

        docker run -d nileshops/node-app:latest

These examples demonstrate various ways to interact with Docker Hub, including searching for images, pulling images, pushing your own images, running containers from images, and building custom images using base images from Docker Hub. Docker Hub is a valuable resource for sharing and discovering Docker images for a wide range of applications and use cases.

docker registry setup at local machine with exampls

Setting up a local Docker:

Setting up a local Docker registry allows you to store and manage Docker images on your own infrastructure. You can use tools like Docker Registry (v2), Harbor, or other registry software for this purpose. Here, I'll provide an example of setting up a basic Docker Registry using Docker's official registry image.

Step 1: Install Docker (if not already installed)

If you haven't already installed Docker on your local machine, you can download and install it from the official website

Step 2: Pull the Docker Registry Image

You can use the official Docker Registry image to set up a local registry. Pull the image using the following command:

        docker pull registry:2

Step 3: Run the Docker Registry Container

Run a Docker container based on the registry image with the following command:

        docker run -d -p 5000:5000 --name my-registry registry:2
  • -d: Runs the container in detached mode (in the background).

  • -p 5000:5000: Maps port 5000 from the host to port 5000 in the container.

  • --name my-registry: Specifies a name for the container.

  • registry:2: Specifies the image to use (Docker Registry version 2).

Step 4: Push and Pull Images to/from the Local Registry

Now that you have your local Docker registry running, you can push and pull Docker images to/from it.

Pushing an Image to the Local Registry:

To push a Docker image to your local registry, you need to tag it with the address of your registry and the image name. Here's an example with an image named "my-app":

        # Tag the image
        docker tag my-app:latest localhost:5000/my-app:latest

        # Push the tagged image to the local registry
        docker push localhost:5000/my-app:latest

Pulling an Image from the Local Registry:

To pull an image from your local registry, you need to specify the registry address along with the image name and tag:

        docker pull localhost:5000/my-app:latest

Step 5: Accessing the Local Registry

You can access your local registry through a web browser or other Docker clients. By default, the local registry is available at http://localhost:5000.

Step 6: Clean Up

To stop and remove the local Docker registry container when you're done, you can use the following commands:

        docker stop my-registry
        docker rm my-registry

Please note that this example demonstrates setting up a basic Docker Registry for local development and testing purposes. In a production environment, consider using more secure configurations, including authentication and SSL/TLS encryption, to protect your Docker registry and images. Additionally, you may explore more advanced registry solutions like Harbor for additional features and security.

Docker Networking:

Docker provides various networking options to facilitate communication between containers, between containers and the host system, and across multiple Docker hosts in a swarm. Let's explore the different types of Docker networking with examples for each.

When docker is installed then we have a docker network created i.e. docker0

This is used to connect to the outside world.

  1.    docker network ls
       docker inspect bridge
    

1. Default Bridge Network:

Docker creates a default bridge network named bridge when you install Docker. Containers attached to this network can communicate with each other but are isolated from the host network by default.

Example:

        # Run two containers on the default bridge network
        docker run -d --name container1 nginx
        docker run -d --name container2 nginx

Containers container1 and container2 can communicate with each other using their container names as hostnames.

  1.    docker inspect bridge :-with this command we can find 
       above two container running on that network also
        ip assigned to that conatiner
    

2. User-Defined Bridge Networks:

User-defined bridge networks allow you to create custom networks with more control over container communication. Containers on the same user-defined network can resolve each other's names, and you can specify IP addresses and subnet ranges.

Example:

        # Create a user-defined bridge network
        docker network create mynetwork

        # Run containers on the custom network
        docker run -d --name container3 --network mynetwork nginx
        docker run -d --name container4 --network mynetwork nginx
        docker inspect mynetwork :- u can see container3 and container4 
        running on custom network.

Containers container3 and container4 can communicate with each other using their container names, and you can control their IP addresses within the network.

3. Host Network:

Containers on the host network share the host's network namespace. They have the same network interfaces and IP addresses as the host, which can be useful for certain scenarios but may raise security concerns.

Example:

        bashCopy code# Run a container on the host network
        docker run -d --name container5 --network host nginx

container5 shares the host's network and can communicate directly with services running on the host.

Here we have not exposed the port but still it runs on port no 80(it means it directly runs on your host so no need to publish, when it uses docker0 network then we need to publish port because then it communicates using bridge)

    1.       docker inspect host :-with this command we can find 
            above two container running on that network also
             ip assigned to that conatiner
      

Note:- no IP address is assigned when we run a container on the host because it directly runs on host ip

4. Overlay Networks:

Overlay networks are used for container communication across multiple Docker hosts in a swarm. They provide a secure way for containers on different hosts to communicate.

Example:

        # Create an overlay network on a Docker swarm
        docker network create --driver overlay myoverlay

        # Run services in a swarm using the overlay network
        docker service create --name my-service --network myoverlay nginx

In a Docker swarm, overlay networks allow containers in different nodes to communicate seamlessly.

5. Macvlan Networks:

Macvlan networks allow you to assign a MAC address to each container, making them appear as separate physical devices on the network. This can be useful when containers need to be on the same network as other physical devices.

Example:

        # Create a Macvlan network
        docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 mymacvlan

        # Run a container on the Macvlan network
        docker run -d --name container6 --network mymacvlan nginx

container6 will have its own MAC address and can communicate directly with devices on the physical network.

6. Bridge to External Network (Port Mapping):

You can map container ports to host ports to allow external access to containerized services.

Example:

        # Run a container and map port 8080 on the host to port 80 in the container
        docker run -d -p 8080:80 --name container7 nginx

This allows you to access the Nginx web server in container7 from the host's port 8080.

7. None Network:

Containers on the none network have no network access, making them completely isolated.

Example:

        # Run a container with no network access
        docker run -d --network none --name container8 nginx

container8 cannot communicate with the network or other containers.

Understanding these Docker networking options is crucial for designing and deploying containerized applications. The choice of network type depends on your specific use case, ranging from simple container communication to complex multi-host swarm deployments.

IPvlan network:

IPvlan is a Docker network driver that allows containers to be attached to a network in such a way that they appear as individual devices on a physical network. Each container has its own MAC address and IP address, enabling direct communication with other devices on the physical network. IPvlan can be useful when you need to integrate containers into an existing network infrastructure.

Here's how to create and use an IPvlan network in Docker:

1. Create an IPvlan Network:

You can create an IPvlan network using the docker network create command, specifying the --driver ipvlan option and additional parameters like the parent interface (physical network interface) and subnet details.

        docker network create -d ipvlan \
          --subnet=192.168.1.0/24 \
          --gateway=192.168.1.1 \
          -o parent=eth0 \
          myipvlan

In this example:

  • -d ipvlan: Specifies the network driver as IPvlan.

  • --subnet=192.168.1.0/24: Defines the subnet for the IPvlan network.

  • --gateway=192.168.1.1: Sets the gateway IP address for the network.

  • -o parent=eth0: Specifies the parent network interface (eth0) to attach the IPvlan network to.

  • myipvlan: The name of the created IPvlan network.

2. Run Containers on the IPvlan Network:

Once the IPvlan network is created, you can run containers on it by specifying the network when using docker run.

        docker run -d --name container1 --network myipvlan nginx
        docker run -d --name container2 --network myipvlan nginx

In this example, container1 and container2 are attached to the myipvlan network and can communicate directly with devices on the physical network as if they were separate physical devices.

3. Verify Connectivity:

You can verify that containers on the IPvlan network can communicate with other devices on the physical network by running commands within the containers.

        # Access container1
        docker exec -it container1 bash

        # From within the container, you can test connectivity to a device on the physical network
        ping 192.168.1.2   # Replace with the IP address of a physical device

Containers on the IPvlan network have their IP addresses and can communicate directly with devices on the physical network without Network Address Translation (NAT).

Please note that setting up IPvlan networks requires administrative privileges and access to the physical network's configuration, so it's typically used in scenarios where you have control over the network infrastructure. Additionally, IPvlan is only available on certain Linux kernel versions and may not be available on all systems.

Conclusion

These examples illustrate some of the fundamental concepts of containers in Docker, including running pre-built images, interacting with containers, building custom images, and running containers from custom images. Containers are a powerful tool for packaging, distributing, and running applications in a consistent and isolated environment.