Docker for Beginners: Containerize Your First App
Docker packages your app and everything it needs into one portable container. Learn the core concepts and ship your first containerized app in minutes.
“It works on my machine” is the oldest problem in software. Docker fixes it by bundling your app with its exact runtime, libraries, and config into a container that runs the same everywhere.
The three concepts
- Image — a read-only template: your app plus its environment. Built once, run anywhere.
- Container — a running instance of an image.
- Dockerfile — the recipe that defines an image.
If an image is a class, a container is an object created from it.
Your first Dockerfile
Say you have a small Node app. Create a Dockerfile:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Each line is a layer. Copying package*.json and installing before copying the rest means Docker caches your dependencies and only reinstalls them when they actually change — a big speedup.
Build and run
docker build -t my-app .
docker run -p 3000:3000 my-app
-p 3000:3000 maps the container’s port to your machine. Open http://localhost:3000 and you’re talking to code running inside the container.
Useful everyday commands
docker ps # running containers
docker images # local images
docker logs <id> # view a container's output
docker stop <id> # stop a container
Don’t ship junk: .dockerignore
Add a .dockerignore so you don’t copy node_modules and local cruft into the image:
node_modules
.git
.env
Running multiple services with Compose
Real apps are rarely one container. Docker Compose describes several services in one docker-compose.yml and starts them together:
services:
app:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: example
volumes:
- dbdata:/var/lib/postgresql/data
volumes:
dbdata:
docker compose up builds your app, starts Postgres, wires them on a shared network, and persists the database in a named volume so your data survives restarts. One command, whole stack.
Frequently asked questions
What’s the difference between an image and a container? An image is the immutable template; a container is a running instance of it. One image can spawn many containers.
Do containers keep my data? Not by default — a container’s filesystem is ephemeral. Use volumes (as above) to persist anything you want to keep.
Is Docker the same as a virtual machine? No. A VM virtualizes a whole operating system; a container shares the host kernel and isolates just your app. Containers are far lighter and start in milliseconds.
Where to go next
Once Compose feels comfortable, look at multi-stage builds to shrink images and at container registries for sharing them. But the mental model never changes: an image is the recipe, a container is the meal.
Tagged
Keep reading
CI/CD Basics: Automate Deploys with GitHub Actions
Stop deploying by hand. Learn how to set up continuous integration and deployment with GitHub Actions — tests on every push, deploys on every merge.
Getting Started with TypeScript: A Practical Guide
TypeScript adds a safety net to JavaScript without slowing you down. Here's how to set it up, the handful of concepts that matter, and how to adopt it gradually.
Understanding the JavaScript Event Loop
Why does JavaScript feel single-threaded yet handle so much at once? The event loop is the answer. Here's a clear mental model with examples you can run.