Docker Introduction

July 21, 2024

What is Docker?

  • A platform that makes sure our code runs smoothly in any environment.
  • A platform that enables development, packaging, and execution.
  • By clearly specifying our application requirements, such as Node.js version and necessary packages, Docker generates a self-contained box that includes its own operating system and all the components essential for running our application.
  • It acts like a separate computer virtually providing the operating system, run times, and everything required for our application to run smoothly.

The reasons for using Docker

Big companies such as eBay, Spotify, Yelp, Uber etc. noticed that using docker made their apps better and faster in terms of both dev and deployment. Uber accelerates developers onboarding from weeks to minutes with Docker.

Consistency across environments

Docker ensures that our app runs the same on everyone’s computer. Everyone uses the same commands to run the app.

For example, Node.js isn’t the same on Linux, macOS, and Windows. Developers usually have to deal with different operating systems. Docker takes care of all of that for us.

Isolation

Docker maintains a clear boundary between our app and its dependencies. The isolation:

  • improves security
  • simplifies debugging
  • makes development process smoother

Portability

Docker allows us easily move our app between different stages like from development to testing or testing to production.

Docker containers are also lightweight and share the host system resources, making them more efficient than any traditional virtual machines. This efficiency translates to faster application start times and reduced resource usage.

Version Controls

Docker helps us track versions of our app. It lets us easily return to a previous version if something is wrong.

Scalability

Docker makes it easy to scale our app. We can easily add more containers to handle increased load.

DevOps Integration

Docker integrates well with DevOps practices. It helps us automate our deployment process and makes it easier to manage our app in production.

This integration ensures that the software is

  • developed
  • tested
  • deployed efficiently

with continuous feedback and collaboration.

How does Docker work?

There are two most important concepts in Docker: images and containers. The entire workflow revolves around them.

Images

A Docker image is a lightweight, standalone, executable package that includes everything needed to run a piece of software, including the code, a runtime, libraries, environment variables, and config files.

We want to run images somewhere so there is container.

Containers

A Docker container is a runnable instance of a Docker image. It represents the execution environment for a specific app, including everything included into Docker image.

The container follows the instructions of the image by executing necessary commands, downloading packages and setting things up to run our app.

We could create on image and get as many instances as we want from it.

Volume

A Docker volume is a persistent data storage mechanism that allows the data to be shared between a Docker container and the host machine which is usually a computer or a server or even among multiple containers.

It ensures data durability and persistence even if the container is stopped or removed. Think of it as a shared folder that exists outside the container.

Network

It’s a communication channel that enable different Docker containers to talk to each other or with the external world.

It creates connectivity, allowing containers to share information and services while maintaining isolation.

Docker Workflow

The Docker client is the command center where we issue instructions.

The Docker host then executes these instructions and manage containers.

The Docker registry serves as a centralized storage.

Docker Client

  • the UI for interacting with Docker
  • the tool we use to give Docker commands

Docker Host (Docker Daemon)

  • the background process responsible for managing containers on the host system
  • listens for Docker client commands
  • creates and manages containers
  • builds images
  • handles other Docker-related tasks

Docker Registry (Docker Hub)

  • a centralized repo of Docker images
  • hosts both public and private registries or packages
  • Docker → Docker Hub = Git → GitHub
  • images are stored in these registries

How to use Docker?

Create a Docker image

It starts from a special file: Dockerfile.

FROM

Specifies the base image, it's the first instruction in a Dockerfile.

FROM image[:tag] [AS name]

# example
FROM ubuntu:20.04

WORKDIR

Sets the working directory for subsequent RUN, CMD, ENTRYPOINT instructions.

WORKDIR /path/to/dir

# example
WORKDIR /app

COPY

Copies local files into the container.

COPY [--chown=<user>:<group>] <src>... <dest>

# example
COPY . /app

RUN

Executes commands during the build process.

RUN <command>

# example
RUN npm run dev

EXPOSE

Declares the ports the container listens on at runtime.

EXPOSE <port> [<port>/<protocol>...]

# example
EXPOSE 3000

ENV

Sets environment variables.

ENV KEY=VALUE

# example
ENV NODE_ENV=production

ARG

Defines build-time variables that can be passed via --build-arg during build

ARG <name>[=<default value>]

# example
ARG NODE_VERSION=20

VOLUME

Creates a mount point.

VOLUME ["/data"]

# example
VOLUME /myvol

CMD

Specifies the command to run when the container starts.

CMD ["executable","param1","param2"]

# example
CMD ["param1","param2"]

ENTRYPOINT

Also used to specify the command to run when the container starts.

ENTRYPOINT ["executable", "param1", "param2"]

# example
ENTRYPOINT ["nginx", "-g", "daemon off;"]

Differences between CMD and ENTRYPOINT

Differences between CMD and ENTRYPOINT

Purpose

  • CMD is mainly used to provide default commands when starting the container.
  • ENTRYPOINT is used to set the main command to be executed when the container starts.

Overridability

  • CMD can be easily overridden by docker run command-line arguments.
  • ENTRYPOINT is not easily overridden, requiring the --entrypoint option to do so.

Combined usage

  • When CMD and ENTRYPOINT coexist, CMD acts as arguments passed to ENTRYPOINT.
  • For scenarios where the startup command needs to change frequently, using CMD is more flexible.
  • For fixed main commands, using ENTRYPOINT is more appropriate.