Docker in 20 Minutes: Everything You Need to Start Containerizing Stop saying "it works on my machine." Here's Docker, explained simply. What Problem Does Docker Solve? WITHOUT Docker: Your app: "Works on my laptop! π" Server: "Doesn work. Node version wrong. Library missing. OS different." π WITH Docker: Your app: "Here's a box with everything inside. Run this box." π¦ Server: "Running the box. Works perfectly." β Enter fullscreen mode Exit fullscreen mode Docker packages your app + dependencies into a container that runs identically everywhere. Docker vs VM (Quick) Virtual Machine: βββββββββββββββββββββββββββββββββββββββ β Host Operating System β β βββββββββββββββββββββββββββββββββ β β β Guest OS (full Linux) β β β β βββββββββββββββββββββββββββ β β β β β Your App β β β β β β + Dependencies β β β β β βββββββββββββββββββββββββββ β β β βββββββββββββββββββββββββββββββββ β βββββββββββββββββββββββββββββββββββββββ Heavy: Full OS per VM = GBs of space, minutes to boot Docker Container: βββββββββββββββββββββββββββββββββββββββ β Host Operating System β β βββββββββββββββββββββββββββββββββ β β β Docker Engine β β β β βββββββ βββββββ βββββββ β β β β β App1β β App2β β App3β β β β β βββββββ βββββββ βββββββ β β β βββββββββββββββββββββββββββββββββ β βββββββββββββββββββββββββββββββββββββββ Light: Shared kernel = MBs, seconds to start Enter fullscreen mode Exit fullscreen mode The 3 Core Concepts 1. Dockerfile = Recipe # Dockerfile β instructions to build your container image # Base image (start from something that already exists) FROM node:22-alpine # Set working directory WORKDIR /app # Copy package files first (layer caching!) COPY package*.json ./ # Install dependencies RUN npm ci --only=production # Copy source code COPY . . # Expose port EXPOSE 3000 # Command to run CMD ["node", "server.js"] Enter fullscreen mode Exit fullscreen mode 2. Image = Built snapshot (the recipe cooked) # Build an image from Dockerfile docker build -t myapp:v1 . # List images docker images # Remove image docker rmi myapp:v1 Enter fullscreen mode Exit fullscreen mode 3. Container = Running instance (image brought to life) # Run a container from an image docker run -d -p 3000:3000 --name myapp myapp:v1 # List running containers docker ps # Stop container docker stop myapp # Start stopped container docker start myapp # Remove container docker rm myapp Enter fullscreen mode Exit fullscreen mode Your First Dockerized App Step 1: Create the files // server.js const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ message: 'Hello from Docker!', time: new Date().toISOString(), hostname: require('os').hostname() })); }); server.listen(3000, () => console.log('Running on :3000')); Enter fullscreen mode Exit fullscreen mode // package.json { "name": "docker-demo", "version": "1.0.0", "main": "server.js" } Enter fullscreen mode Exit fullscreen mode # Dockerfile FROM node:22-alpine WORKDIR /app COPY package*.json . RUN npm install COPY . . EXPOSE 3000 CMD ["node", "server.js"] Enter fullscreen mode Exit fullscreen mode # .dockerignore (like .gitignore for Docker) node_modules Dockerfile .git .env npm-debug.log Enter fullscreen mode Exit fullscreen mode Step 2: Build and Run # Build the image docker build -t docker-demo . # Run it! docker run -d -p 3000:3000 docker-demo # Test it curl http://localhost:3000 # {"message":"Hello from Docker!","time":"...","hostname":"abc123"} # It's running in a container! π Enter fullscreen mode Exit fullscreen mode Essential Docker Commands Cheat Sheet Command Description docker build -t name . Build image from Dockerfile docker run -d -p 8080:80 name Run container in background docker ps List running containers docker ps -a All containers (including stopped) docker logs View container logs docker exec -it sh Enter running container docker stop Stop container docker rm Remove container docker images List images docker rmi Remove image docker system prune Remove all unused data Multi-Container Apps: Docker Compose When you need multiple services (app + database + redis): # docker-compose.yml version: '3.8' services: app: build: . ports: - "3000:3000" environment: - DATABASE_URL=postgres://user:pass@db:5432/mydb - REDIS_URL=redis://redis:6379 depends_on: - db - redis restart: unless-stopped db: image: postgres:16-alpine volumes: - postgres_data:/var/lib/postgresql/data environment: POSTGRES_USER: user POSTGRES_PASSWORD: pass POSTGRES_DB: mydb restart: unless-stopped redis: image: redis:7-alpine volumes: - redis_data:/data restart: unless-stopped volumes: postgres_data: redis_data: Enter fullscreen mode Exit fullscreen mode # Start all services docker compose up -d # View logs of all services docker compose logs -f # Logs of one service docker compose logs -f app # Stop everything docker compose down # Stop + remove volumes (fresh start) docker compose down -v # Rebuild after code changes docker compose up -d --build Enter fullscreen mode Exit fullscreen mode Production Dockerfile Tips 1. Multi-stage Builds (Smaller Images) # Stage 1: Build FROM node:22 AS builder WORKDIR /app COPY package*.json . RUN npm ci COPY . . RUN npm run build # Stage 2: Production (much smaller!) FROM node:22-alpine AS production WORKDIR /app COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist COPY --from=builder /app/package.json ./ EXPOSE 3000 CMD ["node", "dist/server.js"] Enter fullscreen mode Exit fullscreen mode Result: ~1GB β ~150MB image size! 2. Use .dockerignore Properly # Always exclude these node_modules dist build .git .gitignore *.md .env.env.* !.env.example Dockerfile docker-compose.yml .npmrc coverage .vscode .idea Enter fullscreen mode Exit fullscreen mode 3. Non-Root User (Security!) FROM node:22-alpine # Create non-root user RUN addgroup -g 1001 appgroup && \ adduser -u 1001 -G appgroup -s /bin/sh -D appuser WORKDIR /app COPY --chown=appuser:appgroup . . USER appuser EXPOSE 3000 CMD ["node", "server.js"] Enter fullscreen mode Exit fullscreen mode 4. Health Check FROM node:22-alpine WORKDIR /app COPY . . RUN npm ci EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=3s \ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1 CMD ["node", "server.js"] Enter fullscreen mode Exit fullscreen mode Common Docker Problems & Solutions "I changed my code but nothing happened!" # Docker builds use layer caching. Force rebuild: docker build --no-cache -t myapp . # Or with Compose: docker compose up -d --build Enter fullscreen mode Exit fullscreen mode "My container exits immediately!" # Check why: docker logs # Common causes: # 1. Process crashes β fix the error in logs # 2. No foreground process β use CMD or entrypoint # 3. Port conflict β change port mapping Enter fullscreen mode Exit fullscreen mode "How do I debug inside a container?" # Shell into a running container docker exec -it sh # Check file system ls -la /app # Check installed packages cat /etc/os-release node -v npm -v # Test commands manually node -e "console.log(require('./package.json'))" Enter fullscreen mode Exit fullscreen mode "Disk space full!" # Clean up Docker docker system prune -af --volumes # Check what's using space docker system df Enter fullscreen mode Exit fullscreen mode Docker vs Alternatives Tool Best For Learning Curve Docker General containerization Medium Podman Rootless containers (security) Low (drop-in) Kubernetes Orchestration at scale High Railway/Render Zero-config deployment Very low Start with Docker. Add Kubernetes when you have 5+ services. Are you using Docker yet? What's your biggest question about containers? Follow @armorbreak for more DevOps content.
Docker in 20 Minutes: Everything You Need to Start Containerizing
Full Article
Original Source
Read the full article at Dev →KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.