From Architecture to Commands: Your Guide to Docker Engine

From Architecture to Commands: Your Guide to Docker Engine

Docker Engine Architecture Under the Hood

Let's understand the Docker Engine architecture, uncovering its core components and understanding how they work together to enable containerization.

  • dockerCLI:

    The Docker Command Line Interface (CLI) serves as the primary interface for users to interact with Docker. It allows users to issue commands to manage containers, images, networks, and volumes. The CLI translates user commands into API requests that are then sent to the Docker daemon for execution.

Example: You use the dockerCLI to run the command docker run -d nginx to start a new container based on the NGINX image. The CLI sends this command to the Docker daemon, which pulls the NGINX image, creates a container, and starts the NGINX server in detached mode.

  • dockerd:

    The Docker daemon, dockerd, is a persistent process that runs in the background on the host system. It is responsible for managing Docker objects such as containers, images, volumes, and networks. The daemon listens for Docker API requests from the dockerCLI and handles container lifecycle events.

Let's see how this works:

When you issue a command like docker pull ubuntu to pull the Ubuntu image, the dockerCLI sends this request to the Docker daemon. The daemon then contacts the Docker registry, pulls the Ubuntu image, and stores it locally on the host system.

  • contained:

    Containerd is an industry-standard container runtime that provides an interface for managing container lifecycle operations. It handles low-level container management tasks such as container creation, execution, and deletion. Containerd communicates with the Docker daemon to perform these operations.

Here's an example scenario:

When you run a container using the dockerCLI, the Docker daemon interacts with containerd to create and manage the container. Containerd leverages the underlying container runtime, such as runc, to execute the container's processes in an isolated environment.

  • containerd-shim:

    Containerd-shim acts as a bridge between containerd and the container runtime (e.g., runc). It serves as a lightweight intermediary process responsible for managing the lifecycle of containers. Containerd-shim ensures proper communication between containerd and the container runtime, facilitating container execution and resource management.

Example: When you start a container using the dockerCLI, containerd-shim is invoked by containerd to launch the container runtime (e.g., runc). Containerd-shim then coordinates with the runtime to create the container's execution environment, including namespaces, cgroups, and filesystem mounts.

  • runc:

    Runc is a lightweight container runtime responsible for spawning and managing container processes. It implements the Open Container Initiative (OCI) runtime specification, ensuring compatibility with various container formats and specifications. Runc leverages Linux kernel features such as namespaces and cgroups to provide secure and isolated container environments.

Here's an example scenario:

When you start a container using the dockerCLI, the Docker daemon communicates with containerd, which in turn invokes runc to create the container's execution environment. Runc sets up the container's namespaces, cgroups, and filesystem mounts, isolating it from other processes running on the host system.

Introduction:

In recent years, Docker has revolutionized the way we develop, deploy, and manage applications. With its ability to package software into standardized units called containers, Docker offers a consistent environment across different platforms, making it easier to build and ship applications. In this blog post, we will delve into the basics of Docker, focusing on managing images and containers effectively.

Understanding Docker Images: Docker images serve as the building blocks for containers. They contain everything needed to run a piece of software, including the code, runtime, libraries, and dependencies. Here's a rundown of some essential Docker commands related to images:


A Complete Guide to Essential Commands

  1. Running an Interactive Ubuntu Container:

    When launching a container, you may encounter an error related to TTY. To resolve this, you can use the winpty command as an alias for Docker, ensuring compatibility with Windows terminals.

Example:

alias docker="winpty docker"
  1. Managing Container Data:

    To create and view data within a container, you can use basic Linux commands like echo to add content to a file and cat to display its contents.

Example:

echo "hey Anurag Here" >> name.txt
cat name.txt
  1. Creating Images from Containers:

    You can create custom images from containers by committing the changes made within the container to a new image using the docker commit command.

Example:

docker commit -m "added Name.txt" containerID ImageName

Replace containerID with the ID of the container and ImageName with the desired name for the new image.

  1. Viewing Docker Images:

    When you're working with Docker, it's essential to have visibility into the images stored on your system. The docker images command provides a snapshot of all Docker images available locally.

    These images serve as the building blocks for containers, containing everything needed to run an application.

Example:

docker images

This command will display a list of Docker images along with their tags and sizes, allowing you to quickly identify the images available on your system.

  1. Running Docker Images:

    To launch an instance of a Docker image and create a container, you use the docker run command followed by the image name. This command initializes a container based on the specified image and starts the application within it.

Example:

docker run ubuntu

Here, we're starting a new container based on the Ubuntu image. This creates an isolated environment running Ubuntu, ready for us to interact with.

Error while running container

When you run Docker commands that require a TTY (teletypewriter, a terminal interface) in a terminal emulator that does not provide a proper TTY interface, you might see the error:

the input device is not a TTY. If you are using mintty, try prefixing the command with 'winpty'

This happens because Docker expects a TTY to be available, which is not provided by some terminal emulators on Windows by default.

Solution

To resolve this issue, you can use winpty to create a TTY for Docker commands. Here’s how you can do it:

Step-by-Step Guide

  1. Identify the Terminal Emulator: Ensure you are using a terminal emulator like mintty (included with Git Bash or Cygwin).

  2. Install winpty: If you don't already have winpty, you can install it. It's usually included with Git for Windows, but you can also find it separately.

  3. Prefix Docker Commands with winpty: To run Docker commands that require a TTY, prefix them with winpty.

Example Commands

winpty docker run -it ubuntu bash

Shell Alias

For convenience, you can create an alias in your shell configuration file (e.g., ~/.bashrc or ~/.bash_profile) to automatically use winpty with Docker:

alias docker="winpty docker"

Docker with winpty Example

Here's an example of running an interactive Docker container with winpty:

bashCopy codedocker="winpty docker"
$docker run -it ubuntu bash

This approach ensures that Docker commands requiring a TTY will work seamlessly in your terminal emulator.

  1. Understanding Containers:

    Containers are the runtime instances of Docker images. They provide an isolated environment where applications can run without interference from the host system or other containers. The docker ps command allows you to view the containers currently running on your system.

Example:

docker ps

By executing this command, you'll see a list of active containers, including details such as their container ID, status, and the image they're based on.

  1. Interacting with Containers:

    The docker run -it command enables interactive mode when starting a container. This means you can interact directly with the container's command line, similar to SSHing into a remote server.

Example:

docker run -it ubuntu

By adding the -it flags, we're instructing Docker to open an interactive shell within the Ubuntu container. This allows us to execute commands and perform tasks within the container environment.

  1. Stopping Containers:

    To halt the execution of a running container, you use the docker stop command followed by the container ID. This gracefully stops the container, allowing it to clean up resources before shutting down.

Example:

docker stop abc123

Replace abc123 with the actual container ID you want to stop. This command initiates the shutdown process for the specified container.

  1. Listing Containers:

    In addition to viewing running containers, you may also want to see all containers, including those that have stopped. The docker container ls command provides a comprehensive list of containers on your system.

Example:

docker container ls

This command displays both running and stopped containers, along with relevant information such as their status, container ID, and image name.

  1. Removing Containers

    When you're finished with a container and no longer need it, you can remove it from your system using the docker rm command followed by the container ID.

Example:

docker rm abc123

Be cautious when using this command, as it permanently deletes the specified container and its associated filesystem. Make sure you won't need the container or any data it contains before proceeding.

  1. Inspecting Containers:

    The docker inspect command provides detailed information about a specific container, including its configuration, network settings, and environment variables.

Example:

docker inspect abc123

Executing this command will output a JSON-formatted representation of the container's attributes, allowing you to examine its internals in detail.

  1. Exiting Interactive Mode:

    When you're done working within an interactive container session, you can exit back to the host environment by typing exit at the command prompt.

Example:

exit

This command terminates the interactive session and returns you to the shell prompt of your host system.

  1. Cleaning Up Containers:

Over time, your system may accumulate stopped containers that are no longer needed. The docker container prune -f command removes all stopped containers from your system, freeing up disk space and decluttering your Docker environment.

Example:

docker container prune -f

Use this command with caution, as it permanently deletes all stopped containers. Ensure you won't lose any important data before proceeding.

  1. Running Commands in Detached Mode:

    By default, Docker containers run in the foreground, meaning they occupy the terminal session from which they were launched. However, you can run containers in detached mode using the -d flag, which allows them to run in the background.

Example:

docker run -d nginx

This command starts a new container based on the Nginx image and runs it in detached mode. You'll receive the container ID as output, indicating that the container is running in the background.

  1. Mapping Ports:

    Many applications hosted within Docker containers expose services on specific ports. To make these services accessible from outside the container, you can map host ports to container ports using the -p flag when starting a container.

Example:

docker run -d -p 8080:80 nginx

Here, we're mapping port 8080 on the host system to port 80 within the Nginx container. This allows us to access the Nginx web server running inside the container via port 8080 on the host.

  1. Using Alpine Images:

    Alpine Linux is a lightweight Linux distribution commonly used as a base image for Docker containers due to its small footprint and security features.

Example:

docker run alpine ping www.example.com

This command starts a new container based on the Alpine Linux image and executes the ping command to ping the specified domain.

  1. Viewing Logs:

    Containers generate log output as they run, providing valuable insights into their behavior and performance. You can view these logs using the docker logs a command followed by the container ID.

Example:

docker logs abc123

Replace abc123 with the ID of the container whose logs you want to view. This command displays the log output generated by the specified container.

  1. Viewing Logs Since a Specific Time:

    In some cases, you may only be interested in viewing log entries generated after a certain point in time. The docker logs --since flag allows you to filter log output based on a specific time threshold.

Example:

docker logs --since 5s abc123

This command displays log entries generated by the container with the ID abc123 within the last 5 seconds.


In conclusion, understanding Docker Engine's architecture and mastering its essential commands are crucial steps for anyone looking to leverage containerization effectively.

The modular design of Docker Engine, with its components like Docker Daemon, REST API, and CLI, provides a robust and flexible framework for managing containers.

By familiarizing yourself with important commands, you can streamline your workflow, automate deployments, and enhance scalability and reliability in your applications. Whether you're a developer, system administrator, or IT professional, gaining a solid grasp of Docker Engine will empower you to harness the full potential of container technology, paving the way for more efficient and innovative software development practices.
If you like this blog, please do like it.

Check out my Portfolio website for connecting with me or just to say Hi !!.
Happy Dockering!

Did you find this article valuable?

Support Anurag's blog by becoming a sponsor. Any amount is appreciated!