098
LVL 04 — SENIOR-IN-TRAININGSESSION 098DAY 98

DOCKER CONTAINERS

🎫 PIXELCRAFT-084
🔧DevOps | 🔴 Expert | Priority: 🟠 High

New developers spend 2 hours setting up the environment. "It works on my machine" bugs are common. Containerize PixelCraft so the entire stack runs with one command: docker-compose up.
CONCEPTS.UNLOCKED
📦
Containers vs VMs
Lightweight isolation. VMs virtualize hardware (full OS per VM, GBs of overhead). Containers share the host OS kernel — just isolated processes. Start in seconds, use MBs, run identically everywhere.
🐳
Docker Concepts
Image → Container → Registry. An image is a blueprint (recipe). A container is a running instance (the dish). A registry stores images (Docker Hub). One image → many containers.
📄
Dockerfile
Recipe for building an image. FROM (base image), COPY (add files), RUN (execute commands), CMD (start command). Each instruction creates an immutable layer — like a Git commit for your environment.
🎼
docker-compose
Orchestrate multiple containers. App + database + Redis in one YAML file. docker-compose up starts everything. Containers talk to each other by service name. The entire stack in one command.
💾
Volumes
Persistent data across restarts. Containers are ephemeral — data inside is lost when they stop. Volumes mount host directories into containers. Database data survives container restarts.
🏗️
Multi-Stage Builds
Separate build from runtime. Stage 1: install devDependencies, compile TypeScript. Stage 2: copy only compiled output + production deps. Image shrinks from 1.2GB to 150MB.
HANDS-ON.TASKS
01
Dockerfile: Multi-Stage Build
# Build stage FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . RUN npm run build # Runtime stage FROM node:20-alpine WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder \ /app/node_modules ./node_modules COPY --from=builder \ /app/package.json ./ ENV NODE_ENV=production EXPOSE 3001 CMD ["node", "dist/server.js"]
The builder stage has TypeScript, dev tools, source code — 1.2GB. The runtime stage has only compiled JS and production deps — 150MB. Users only download the slim runtime image.
02
docker-compose.yml
version: '3.8' services: frontend: build: ./frontend ports: - "5173:5173" environment: - VITE_API_URL= http://localhost:3001 backend: build: ./backend ports: - "3001:3001" environment: - DATABASE_URL= mongodb://mongo:27017/pixelcraft - REDIS_URL=redis://redis:6379 - JWT_SECRET= dev-secret-change-in-prod depends_on: - mongo - redis mongo: image: mongo:7 ports: - "27017:27017" volumes: - mongo-data:/data/db redis: image: redis:7-alpine ports: - "6379:6379" volumes: mongo-data:
03
One Command to Rule Them All
docker-compose up --build # → Building frontend... ✅ # → Building backend... ✅ # → Pulling mongo:7... ✅ # → Pulling redis:7... ✅ # → Starting mongo... ✅ # → Starting redis... ✅ # → Starting backend... ✅ # → Starting frontend... ✅ # Open localhost:5173 # Everything is running.
04
Add .dockerignore
# .dockerignore node_modules dist .git .env .env.local *.md playwright-report coverage # Same idea as .gitignore: # don't COPY unnecessary files # into the Docker build context. # node_modules alone saves 500MB+ # of build time.
05
Test: Fresh Machine Setup
# On a COMPLETELY fresh machine: git clone git@github.com:you/pixelcraft.git cd pixelcraft docker-compose up --build # That's it. # No "install Node 20" # No "install MongoDB" # No "install Redis" # No "configure environment" # Just: clone → compose up → done.
06
Close the Ticket
git switch -c devops/PIXELCRAFT-084-docker git add Dockerfile docker-compose.yml .dockerignore git commit -m "Containerize PixelCraft with Docker (PIXELCRAFT-084)" git push origin devops/PIXELCRAFT-084-docker # PR → Review → Merge → Close ticket ✅
CS.DEEP-DIVE

Containerization solves the environment problem.

A container packages code + runtime + dependencies + configuration into a single artifact that runs identically everywhere.

// The same principle, everywhere:

Docker
  Standardized application packaging
  Runs the same on any machine

JVM
  "Write once, run anywhere"
  JVM abstracts the OS

Shipping containers
  Standardized box fits any
  truck, ship, or train

// Docker images are layers:
FROM node:20-alpine   (base)
COPY package.json    (+layer)
RUN npm ci           (+layer)
COPY . .             (+layer)

// Each layer is an immutable diff —
// like Git commits for your env.
// Unchanged layers are cached.

// At scale: Kubernetes orchestrates
// thousands of containers across
// hundreds of machines.
"Docker Lab"
[A]Add a dev mode docker-compose.dev.yml: mount source code as a volume, enable hot-reload (nodemon for backend, Vite HMR for frontend). Changes reflect instantly without rebuilding the container.
[B]Optimize layer caching: copy package.json and run npm ci BEFORE copying source code. Node_modules layer is cached unless dependencies change. Rebuild goes from 3 minutes to 15 seconds.
[C]Research: what is Kubernetes (K8s)? How does it differ from docker-compose? When does a project need K8s vs. a simple PaaS like Railway? Write a decision framework: "Use Docker Compose when..., Use K8s when..."
REF.MATERIAL
ARTICLE
Docker
Official Docker tutorial: images, containers, Dockerfile, volumes, networking, and compose. The canonical starting point.
DOCKEROFFICIALESSENTIAL
VIDEO
Fireship
Ultra-fast Docker overview: containers vs VMs, Dockerfile, images, and why it changed how software is deployed.
DOCKERQUICK
ARTICLE
Docker
Build optimized images: separate build from runtime, reduce image size, keep secrets out of final images.
DOCKEROPTIMIZATION
VIDEO
TechWorld with Nana
Comprehensive Docker course: concepts, Dockerfile, compose, volumes, networking, and real-world deployment patterns.
DOCKERTUTORIAL
ARTICLE
Docker
Official Compose guide: multi-container applications, service networking, volumes, environment variables, and orchestration.
COMPOSEOFFICIAL
// LEAVE EXCITED BECAUSE
docker-compose upentire PixelCraft stack running. New developer setup: clone → compose up → done. No "install this, configure that, pray it works." This is DevOps.