Skip to main content

🐳 Docker

Shipping containers for your code

The Lunchbox Analogy

Planning lunch:

ApproachOutcome
Without lunchboxLoose rice, sandwich, soup... messy, might spill
With lunchboxEverything neatly packaged, easy to transport

Docker is a lunchbox for your application. It packages everything your app needs into one portable unit.


What Is Docker?

Docker is a platform for working with containers:

CapabilityTool
Building containersDockerfile
Running containersdocker run
Sharing containersDocker Hub
Managing multi-container appsDocker Compose

Docker is one of the most popular tools for working with containers.


Core Concepts

Dockerfile

A recipe for building an image:

InstructionPurpose
FROM node:ltsStart with a Node.js base image
WORKDIR /appSet working directory
COPY package*.json .Copy dependency list
RUN npm installInstall dependencies
COPY . .Copy application code
EXPOSE 3000Document the port
CMD ["npm", "start"]Command to run

Build an image: docker build -t my-app:dev .

Image

A packaged snapshot:

ContainsExample
Base OSAlpine Linux (minimal)
RuntimeNode.js, Python, Java
Dependenciesnpm packages, pip modules
Your codeapp.js, main.py
ConfigurationEnvironment setup

Images are treated as immutable — you typically rebuild a new image when something changes.

Container

A running instance of an image:

AnalogyMeaning
Image : ContainerClass : Object
Recipe : DishBlueprint : Building

Containers are isolated processes with their own filesystem and network.

Registry

Storage for images (like GitHub for code):

RegistryType
Docker HubPublic
AWS ECRPrivate
Google GCRPrivate
Azure ACRPrivate

Common Docker Commands

Building

CommandPurpose
docker build -t my-app:dev .Build image from Dockerfile
-tTag (name:version)
.Build context (current directory)

Running

CommandPurpose
docker run my-app:devRun a container
docker run -p 8080:3000 my-appMap host:container port
docker run -d my-appRun detached (background)
docker run -e API_KEY=xxx my-appSet environment variable

Managing

CommandPurpose
docker psList running containers
docker ps -aList all containers
docker stop [id]Stop a container
docker rm [id]Remove a container
docker logs [id]View container logs

Images

CommandPurpose
docker imagesList local images
docker pull nginx:stableDownload from registry
docker push my-repo/my-app:devUpload to registry
docker rmi [id]Remove an image

Docker Compose

For multi-container applications:

Problem: Application needs: web server + database + cache = 3 containers that work together.

Solution: Define everything in docker-compose.yaml:

services:
  web:
    build: .
    ports:
      - "3000:3000"
  db:
    image: postgres:stable
    environment:
      - POSTGRES_PASSWORD=secret
  cache:
    image: redis:stable
CommandPurpose
docker compose upStart all services
docker compose downStop all services
docker compose logsView all logs

Volumes: Persistent Data

The Problem

Container deleted → Data gone!

Without VolumeWith Volume
Database in containerMount volume to host
Container crashesData persists
All data lost!Data survives

Solution

Volume TypeUsage
Named volumedocker volume create mydata
Bind mount-v /host/path:/container/path
Anonymous volumeAuto-created, harder to manage

Named volumes are the recommended approach for production data.


Multi-Stage Builds

Reduce image size by separating build from runtime:

# Stage 1: Build
FROM node:lts AS builder
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:lts-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]
StageContentsSize
BuilderSource, dev deps, build toolsLarge
ProductionMostly compiled outputMinimal

Common Mistakes

1. Not Using .dockerignore

❌ Include✅ Exclude
node_modulesnode_modules/
.git.git/
temp files*.log

Smaller build context = faster builds.

2. Using "latest" Tag

❌ Bad✅ Better
FROM node:latestFROM node:<pinned-tag>
Unknown tagPredictable, traceable

3. Running as Root

Container process as root = security risk. Use non-root user:

USER node
CMD ["node", "app.js"]

4. Too Many Layers

Each RUN, COPY, ADD creates a layer. Combine when possible:

❌ Bad✅ Good
Multiple RUN commandsCombine with &&
Many small layersFewer, logical layers

Networking

Container Networks

ModeDescription
BridgeDefault, containers on same network
HostContainer uses host's network
NoneNo network

Connecting Containers

Containers on the same network can reach each other by name:

FromToAddress
web containerdb containerdb:5432
apprediscache:6379

Docker Compose creates a network automatically.


FAQ

Q: Docker vs container?

Docker is the platform. Container is the running unit. Docker builds and runs containers.

Q: Docker vs virtual machines?

VMsDocker
Full guest OSShares host kernel
GBs in sizeMBs in size
Minutes to startSeconds to start
Stronger isolationProcess-level isolation

Q: Do I need Docker Compose?

For single containers, no. For multi-container apps, highly recommended.

Q: How do I choose a base image?

Alpine for smallest size. Official language images for compatibility. Check security scans.


Summary

Docker is the platform that builds, runs, and manages containers, making application deployment consistent and portable.

Key Takeaways:

  • Dockerfile defines how to build an image
  • Images are immutable snapshots
  • Containers are running instances
  • Docker Compose handles multi-container apps
  • Volumes persist data beyond container lifecycle
  • Use specific version tags, not latest
  • Run as non-root for security
  • Multi-stage builds reduce image size

Docker helped make containers much more accessible.

Related Concepts

Leave a Comment

Comments (0)

Be the first to comment on this concept.

Comments are approved automatically.