DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

Part 2: Dockerfile, Layers, Caching, Storage, Networking, and Docker Compose

What Is a Dockerfile?

A Dockerfile is simply a text file that contains instructions on how to build a Docker image.

Think of it like a recipe.

If you want to bake a cake, you need instructions:

1. Get flour
2. Add sugar
3. Add eggs
4. Bake
Enter fullscreen mode Exit fullscreen mode

Docker works the same way.

Example:

FROM node:20

WORKDIR /app

COPY . .

RUN npm install

EXPOSE 3000

CMD ["npm","start"]
Enter fullscreen mode Exit fullscreen mode

Docker reads these instructions from top to bottom.


Understanding Each Dockerfile Instruction

FROM

Example:

FROM ubuntu:22.04
Enter fullscreen mode Exit fullscreen mode

or

FROM node:20
Enter fullscreen mode Exit fullscreen mode

This is the base image.

Think of it as the foundation of a house.

Without a foundation:

No house
Enter fullscreen mode Exit fullscreen mode

Without FROM:

No image
Enter fullscreen mode Exit fullscreen mode

Interview Question:

What is the first instruction in most Dockerfiles?

Answer:

FROM
Enter fullscreen mode Exit fullscreen mode

WORKDIR

Example:

WORKDIR /app
Enter fullscreen mode Exit fullscreen mode

Creates a working directory.

Equivalent Linux command:

mkdir /app
cd /app
Enter fullscreen mode Exit fullscreen mode

Every following instruction executes inside:

/app
Enter fullscreen mode Exit fullscreen mode

COPY

Example:

COPY . .
Enter fullscreen mode Exit fullscreen mode

Meaning:

Copy current project
into container
Enter fullscreen mode Exit fullscreen mode

Host:

project/
  app.js
  package.json
Enter fullscreen mode Exit fullscreen mode

Container:

/app
  app.js
  package.json
Enter fullscreen mode Exit fullscreen mode

RUN

Executes commands during image build.

Example:

RUN npm install
Enter fullscreen mode Exit fullscreen mode

Docker executes:

npm install
Enter fullscreen mode Exit fullscreen mode

while building the image.

This creates dependencies inside the image.


CMD

Example:

CMD ["npm","start"]
Enter fullscreen mode Exit fullscreen mode

Defines what runs when the container starts.

Without CMD:

Container starts and exits immediately.

CMD acts like:

npm start
Enter fullscreen mode Exit fullscreen mode

inside the container.


EXPOSE

Example:

EXPOSE 3000
Enter fullscreen mode Exit fullscreen mode

Documents which port application uses.

Important:

Many beginners think:

EXPOSE 3000
Enter fullscreen mode Exit fullscreen mode

opens the port.

It does NOT.

It simply informs Docker.

Real port publishing happens using:

docker run -p 3000:3000 image
Enter fullscreen mode Exit fullscreen mode

Building an Image

Dockerfile:

FROM nginx
Enter fullscreen mode Exit fullscreen mode

Build:

docker build -t my-nginx .
Enter fullscreen mode Exit fullscreen mode

Output:

my-nginx
Enter fullscreen mode Exit fullscreen mode

now becomes a local image.

Verify:

docker images
Enter fullscreen mode Exit fullscreen mode

What Happens During docker build?

This is where many DevOps interviews become difficult.

Docker does not create one giant file.

Docker creates layers.


Understanding Layers

Example:

FROM ubuntu

RUN apt update

RUN apt install nginx

COPY . .
Enter fullscreen mode Exit fullscreen mode

Docker creates:

Layer 1 → Ubuntu
Layer 2 → apt update
Layer 3 → nginx install
Layer 4 → copied files
Enter fullscreen mode Exit fullscreen mode

Visual:

Layer 4
Layer 3
Layer 2
Layer 1
Enter fullscreen mode Exit fullscreen mode

Every instruction creates another layer.


Why Layers Matter

Imagine image size:

5 GB
Enter fullscreen mode Exit fullscreen mode

Without layers:

Every build:

Download entire 5 GB
Enter fullscreen mode Exit fullscreen mode

With layers:

Docker only downloads changed layers.

Huge performance improvement.


Docker Cache

One of the most important concepts for senior engineers.

Example:

FROM node:20

COPY package.json .

RUN npm install

COPY . .

CMD ["npm","start"]
Enter fullscreen mode Exit fullscreen mode

First build:

docker build .
Enter fullscreen mode Exit fullscreen mode

May take:

2 minutes
Enter fullscreen mode Exit fullscreen mode

Second build:

10 seconds
Enter fullscreen mode Exit fullscreen mode

Why?

Docker reuses cached layers.


Bad Dockerfile Design

Example:

FROM node:20

COPY . .

RUN npm install
Enter fullscreen mode Exit fullscreen mode

Any code change:

npm install runs again
Enter fullscreen mode Exit fullscreen mode

Very slow.


Better Dockerfile Design

Example:

FROM node:20

COPY package.json .

RUN npm install

COPY . .
Enter fullscreen mode Exit fullscreen mode

Now Docker only reruns:

COPY . .
Enter fullscreen mode Exit fullscreen mode

Much faster.

Senior DevOps engineers always optimize caching.


Multi-Stage Builds

Used in production almost everywhere.

Problem:

Building React app:

FROM node:20
Enter fullscreen mode Exit fullscreen mode

Contains:

Node
NPM
Build Tools
Source Code
Enter fullscreen mode Exit fullscreen mode

Huge image.


Solution:

Multi-stage build.

FROM node:20 AS builder

WORKDIR /app

COPY . .

RUN npm install

RUN npm run build

FROM nginx

COPY --from=builder /app/dist /usr/share/nginx/html
Enter fullscreen mode Exit fullscreen mode

Result:

Production image contains only:

Built website
Nginx
Enter fullscreen mode Exit fullscreen mode

Not:

Node
NPM
Source code
Enter fullscreen mode Exit fullscreen mode

Much smaller.

More secure.

Faster deployment.


Container Storage Problem

Suppose MySQL runs in container.

docker run mysql
Enter fullscreen mode Exit fullscreen mode

Database contains:

Customers
Orders
Invoices
Enter fullscreen mode Exit fullscreen mode

Container crashes.

Container deleted.

Everything disappears.

Why?

Containers are ephemeral.

Ephemeral means temporary.


Volumes

Docker volumes persist data.

Example:

docker volume create mysql-data
Enter fullscreen mode Exit fullscreen mode

Use:

docker run \
-v mysql-data:/var/lib/mysql \
mysql
Enter fullscreen mode Exit fullscreen mode

Now:

Container Deleted
Enter fullscreen mode Exit fullscreen mode

Data survives.


Real Production Example

Company database:

5 TB
Enter fullscreen mode Exit fullscreen mode

Container restarts.

Without volume:

5 TB lost
Enter fullscreen mode Exit fullscreen mode

Business destroyed.

With volume:

Data remains
Enter fullscreen mode Exit fullscreen mode

Volumes are mandatory for databases.


Bind Mounts

Different from volumes.

Example:

docker run \
-v $(pwd):/app
Enter fullscreen mode Exit fullscreen mode

Meaning:

Host Directory
     ↔
Container Directory
Enter fullscreen mode Exit fullscreen mode

Changes on host instantly appear inside container.

Mostly used:

Development
Testing
Enter fullscreen mode Exit fullscreen mode

Not usually production.


Docker Networking

One of the most important topics for senior DevOps engineers.


Why Networking Exists

Suppose:

Frontend Container
Backend Container
Database Container
Enter fullscreen mode Exit fullscreen mode

Need communication.

Docker creates networks.


Bridge Network

Default network.

Create:

docker network create app-network
Enter fullscreen mode Exit fullscreen mode

Run:

docker run --network app-network
Enter fullscreen mode Exit fullscreen mode

All containers can communicate.


Example

Backend:

backend-container
Enter fullscreen mode Exit fullscreen mode

Database:

postgres-container
Enter fullscreen mode Exit fullscreen mode

Backend can connect:

postgres-container:5432
Enter fullscreen mode Exit fullscreen mode

No IP needed.

Docker provides internal DNS.


Port Publishing

Container:

80
Enter fullscreen mode Exit fullscreen mode

Host:

8080
Enter fullscreen mode Exit fullscreen mode

Mapping:

docker run -p 8080:80 nginx
Enter fullscreen mode Exit fullscreen mode

Visual:

Browser
   |
Host 8080
   |
Container 80
Enter fullscreen mode Exit fullscreen mode

Host Network

Container uses host network directly.

docker run --network host nginx
Enter fullscreen mode Exit fullscreen mode

No isolation.

Higher performance.

Used occasionally.


Overlay Networks

Used across servers.

Example:

Server A
Server B
Server C
Enter fullscreen mode Exit fullscreen mode

Containers communicate as one network.

Used in:

  • Docker Swarm
  • Kubernetes concepts

Docker Compose

Real applications rarely use one container.

Example application:

Frontend
Backend
PostgreSQL
Redis
Enter fullscreen mode Exit fullscreen mode

Starting individually is painful.


Without Compose

docker run frontend
docker run backend
docker run postgres
docker run redis
Enter fullscreen mode Exit fullscreen mode

Difficult.


With Compose

services:

  frontend:
    image: frontend

  backend:
    image: backend

  postgres:
    image: postgres

  redis:
    image: redis
Enter fullscreen mode Exit fullscreen mode

Start:

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Everything starts.


Enterprise Example

Application:

React Frontend
Node Backend
PostgreSQL
Redis
Enter fullscreen mode Exit fullscreen mode

Compose file defines:

Networks
Volumes
Ports
Containers
Dependencies
Enter fullscreen mode Exit fullscreen mode

Entire environment built with:

docker compose up
Enter fullscreen mode Exit fullscreen mode

Very common in development environments.


What a Senior DevOps Engineer Must Understand from Part 2

You should be able to explain:

Dockerfile

  • FROM
  • COPY
  • RUN
  • CMD
  • EXPOSE
  • WORKDIR

Layers

  • How layers are created
  • How caching works
  • How layer optimization works

Multi-Stage Builds

  • Why used
  • How they reduce image size
  • Security benefits

Storage

  • Volumes
  • Bind mounts
  • Persistent data

Networking

  • Bridge
  • Host
  • Overlay
  • Port publishing
  • Container DNS

Docker Compose

  • Multi-container applications
  • Networks
  • Volumes
  • Environment creation

These are the concepts that separate someone who can "run a container" from someone who can design and support Docker environments in production.

Top comments (0)