Tutorials

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.

Chisato Chisato · · 2 min read
Stacked cargo shipping containers at a port

“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.

Tutorial · 1 min read

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.

#DevOps #CI/CD #GitHub Actions
Tutorial · 3 min read

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.

#TypeScript #JavaScript #Web Development
Tutorial · 1 min read

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.

#JavaScript #Web Development #Async