Skip to main content

Command Palette

Search for a command to run...

Understanding Docker and Containers

Updated
8 min readView as Markdown
E

I am a software developer with over four years of experience and a passion for building innovative solutions that address real-world problems, having worked on various projects in various sectors. I am the founder of Sahil, an app that connects small businesses with suppliers and customers in low-income areas. Sahil is a comprehensive platform that simplifies procurement processes, connects businesses with reliable suppliers, and ensures swift, efficient deliveries.

In addition to Sahil, I am actively involved in two open-source initiatives: "Planet of the Bugs", an open-source platform that curates unique, curated issues and bugs from popular open-source projects on GitHub, and "VibeCheck", which explores innovative social networking to establish more authentic connections.

I am committed to advancing technology for the benefit of all, and my commitment to efficiency and problem-solving is evident in my work.

My technical proficiency lies in TypeScript, Next.js, GraphQL, Redis, PostgreSQL, Node.js, and Rust.

Introduction

If you are new to Docker, it can feel like a daunting task: figuring out where to start, which concepts are essential, and how they all fit together. This article will help you gain a practical understanding of Docker's most commonly used features. A solid grasp of these concepts will help you avoid common mistakes and use Docker more efficiently.

Containerization

Containerization is the process of packaging an application and its dependencies (such as system libraries, config files, etc.) into a single unit known as a container.

The main benefit of containerizing your applications is that you can run them anywhere (on a server, PC, microcontroller, etc.), regardless of the underlying operating system.

The other benefit of containerizing your applications is that they allow you to build them quickly without worrying about configuring the operating system. Docker and containerization are two ways of providing isolated environments for your applications.

Containers

A container is a small independent program that runs in its environment. Containers are lightweight and easy to create, modify and run. With containers, you can move applications between environments more quickly and flexibly than traditional virtual machines allow.

Containers are self-contained, they have their filesystem, processes, and network interfaces, and they can run on any machine with access to a Docker container's filesystem. Containers are nothing more than a combination of a few Linux kernel features at their core.

Why Containers?

Predicitibiliy

Containers are predictable. They prevent a very common problem which is the incompatibility of dependencies. Imagine working on a distributed team where each developer uses a different operating system to run an application.

But it works on my machine!

Containers fix this problem by allowing you to define all your dependencies in one place and then use them regardless of which machine they are running on. This means you do not need additional knowledge about how things are installed or managed on other machines — everything works!

Isolation

Docker containers are versatile and self-contained. They run inside their own filesystem, and the process running inside a container is not allowed to access the host system.

Portability

Docker allows you to easily create reproducible images to deploy your application with minimal manual effort and setup quickly.

Security

Docker gives each container an environment with different sets of namespaces so they can't see each others' processes. Docker assigns different process PIDs or process IDs.

For example, if you have a web server and a database server in the same container, the web server would not be able to access the database because their process IDs would not match.

Sharability

You can share containers with others and pull official or custom images from a hosted repository. Several cloud services, such as GCP or AWS, offer registries to help deploy and manage containers on their platforms.

What is Docker?

Docker is an open-source project that provides tools for creating and managing application containers. It also enables users to package their applications into containers, which are then run in a virtual machine like an operating system. Docker also provides an API for interacting with the images to create these containers.

Docker provides an open-source platform for building, running, and deploying containers. managing application deployments. It's useful for deploying applications efficiently and securely in the cloud.

Images

Docker images act as a set of instructions to build a Docker container, like a blueprint.

Tags

Docker tags are just an alias for an image ID. The tag's name must be an ASCII character string and may include lowercase and uppercase letters, digits, underscores, periods, and dashes. In addition, the tag names must not begin with a period or a dash, and they can only contain 128 characters.

  • api:alpha.
  • api:latest.

Installation

Visit Docker Desktop to install Docker on your machine.

Dockerfile

The Dockerfile provides the instructions for creating a container that runs your program and includes all of the build dependencies needed by your application. This allows you to use one set of tools for building and testing your applications instead of multiple tools for each operating system or language.

Building Images

COPY vs. ADD

FROM node:12-stretch

USER node

WORKDIR /home/node/code

COPY --chown=node:node index.js .

CMD ["node", "index.js"]

This is something very powerful about Docker: you can use images to build other images and build on the work of others.

Layers

Docker images are built on top of layers. Each layer is a separate instruction to the Docker daemon, telling it what instructions to execute when building the final image.

Multi Stage Builds.

Docker allows you to have what is called multistage builds, where it uses one container to build your app and another to run it. This can be useful if you have big dependencies to build your app, but you don't need those dependencies actually to run the app.

# For dependencies
FROM node:12-stretch AS deps 

USER node

WORKDIR /home/node/code

COPY --chown=node:node index.js .

CMD ["node", "index.js"]

# For building
FROM node:12-stretch AS builder

USER node

WORKDIR /home/node/code

COPY --chown=node:node index.js .

Docker Hub

Docker hub is a web service to find and share images, as well as to monitor and search the Docker Engine API. It's like GitHub but for containers. You can find and share containers on Docker Hub.

Pushing Images

docker push [OPTIONS] NAME[:TAG|@DIGEST]

Pulling Images

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Networking

The Docker networking architecture is a key component of Docker’s containerization platform. It allows cross-container communication and external services such as the host's operating system. Containers that run on different hosts can communicate through the network, allowing them to share resources such as files and ports.

Networking in Docker provides several benefits:

  • It enables a more straightforward way of provisioning applications on top of existing infrastructure rather than creating a new one from scratch.

  • It helps simplify your development workflows by removing the need for setting up networks manually every time you deploy changes through CI/CD pipelines or via manual deployment processes.

Data Persistence

Docker containers are stateless and ephemeral, but you can make them stateful by adding a volume to the container.

If you want to run WordPress in a Docker container, you can mount an existing WordPress installation on your computer into the container. This way, you don't have to install WordPress manually whenever you want to use it in a new Docker container.

Bind Mounts

Bind mounts are great for when you need to share data between your host and your container, as we just learned.

Volumes

A volume is a file system that resides inside your Docker container. It's like an external drive or network share. It's how you mount an existing folder into your container so it can be accessed from inside the container.

Volumes, on the other hand, are so that your containers can maintain state between runs. Volumes can not only be shared by the same container type between runs but also between different containers. Maybe if you have two containers and you want to log to consolidate your logs into one place, volumes could help with that.

We can create volumes on a host system with different namespaces than the client applications running within them. For example, suppose you have an application running inside a container with access to some directory via a volume mounted from within the container. In that case, you can also use that same volume for external access without needing to change any files inside or outside the container itself. This makes it possible for many applications to share a single set of files without compromising security or performance due to conflicting paths between containers (e.g., one container having access to another container's volumes).

  • Volumes can be resized as needed.
  • Volumes support snapshotting to create backups of your data at any time.

  • Containers can be started from a volume, allowing for easy debugging and testing of code without starting containers from scratch.

Volumes are more efficient than bind mounts regarding memory footprint and disk usage. Bind mounts require a directory entry in each container to access files outside the container's path. This adds complexity to your application's underlying codebase, which may introduce bugs or cause other undesirable behavior due to issues with file permissions.

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts depend on the host machine's directory structure and OS, volumes are completely managed by Docker. Volumes have several advantages over bind mounts:

  1. Volumes allow you to create a temporary file system independent of your host filesystem, which means you can persist data even when your host machine crashes or reboots.

  2. Volumes provide easy access to files from within a container. You can mount a volume directly into your container, allowing you to pull in files from outside of your container (e.g., from S3). This makes it easier to build robust applications that scale based on their runtime requirements.

  3. Volumes allow quick removal of data once it's no longer needed so that resources aren't wasted when they aren't being used anymore (e.g., persistent volumes delete older versions of files).

Dockerize a Simple Node.js application

Explain the steps in the Dockerfile!

The Docker command-line client is a tool that allows you to interact with your running container. The docker-compose command line client is similar in functionality and works with the same syntax as docker run, but it also provides support for creating and managing multi-container applications (called a stack).

Development Tips

Conclusion

Whether you're considering using containers for your next project or simply want to get a deeper understanding of them, having this information at your disposal will help you make the right decisions regarding containerization. Thank you for reading this article, and good luck with your project!

200 views