惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
博客园 - 叶小钗
Last Week in AI
Last Week in AI
Google DeepMind News
Google DeepMind News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
P
Proofpoint News Feed
大猫的无限游戏
大猫的无限游戏
The Cloudflare Blog
aimingoo的专栏
aimingoo的专栏
月光博客
月光博客
量子位
A
About on SuperTechFans
Engineering at Meta
Engineering at Meta
Apple Machine Learning Research
Apple Machine Learning Research
Jina AI
Jina AI
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
D
DataBreaches.Net
博客园_首页
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Stack Overflow Blog
Stack Overflow Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Docker for Developers: The Only Guide You Actually Need (...
Alex Chen · 2026-05-18 · via DEV Community

Alex Chen

Docker for Developers: The Only Guide You Actually Need (2026)

Stop memorizing Docker commands. Understand how it works once, and you'll never be confused again.

Why Docker Matters

"It works on my machine" → No longer a valid excuse.

Docker ensures your app runs the same way:
→ On your laptop
→ On your teammate's Mac
→ On the Linux server
→ In CI/CD pipeline

One command to rule them all: docker compose up

Enter fullscreen mode Exit fullscreen mode

Docker vs VMs (The Key Insight)

Virtual Machine:
┌─────────────────────────────────┐
│         Host OS                 │
│  ┌─────────────────────────┐    │
│  │      Guest OS           │    │  ← Full OS (GBs of RAM)
│  │   ┌───────────────┐     │    │
│   │   │    Your App   │     │    │
│   │   └───────────────┘     │    │
│  └─────────────────────────┘    │
└─────────────────────────────────┘

Container:
┌─────────────────────────────────┐
│         Host OS (Linux)         │
│  ┌─────────────────────────┐    │
│  │    Docker Engine        │    │
│  │  ┌───────────────┐     │    │
│  │  │   Your App    │     │    │  ← Just your app + deps (MBs)
│  │  └───────────────┘     │    │
│  └─────────────────────────┘    │
└─────────────────────────────────┘

Enter fullscreen mode Exit fullscreen mode

Containers share the host OS kernel. That's why they're lightweight.

Essential Concepts (5 Minutes)

Image vs Container

# Image = Blueprint (like a class)
# Container = Running instance (like an object)

docker run node:20-alpine          # Pull image + create container
docker images                       # List all images
docker ps                           # List running containers
docker ps -a                        # List ALL containers (including stopped)

Enter fullscreen mode Exit fullscreen mode

Dockerfile = Your Build Recipe

# Every Dockerfile starts with a base image
FROM node:20-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

docker-compose.yml = Multi-Service Orchestration

version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://user:pass@db:5432/myapp
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: myapp
    restart: unless-stopped

volumes:
  pgdata:

Enter fullscreen mode Exit fullscreen mode

The Commands I Use Every Day

# === Building & Running ===
docker compose up -d              # Start services in background
docker compose down               # Stop & remove containers
docker compose logs -f --tail 50  # Follow logs (last 50 lines)
docker compose restart app        # Restart one service

# === Debugging ===
docker exec -it app sh            # Shell into running container
docker exec -it app npm test      # Run command inside container
docker compose run --rm app npm run migrate  # Run one-off command

# === Cleanup ===
docker system df                   # See disk usage
docker system prune -a             # Remove unused images, containers, volumes
docker volume prune                # Remove unused volumes

# === Inspecting ===
docker inspect <container>         # Full JSON config of container
docker stats                       # Live resource usage (CPU, MEM, NET)
docker logs <container> -f         # Follow specific container logs

Enter fullscreen mode Exit fullscreen mode

Real-World Examples

1. Node.js API with PostgreSQL

# Dockerfile
FROM node:20-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .

FROM node:20-alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 app && adduser -u 1001 -G app -s /bin/sh -D app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
USER app
EXPOSE 3000
CMD ["node", "dist/server.js"]

Enter fullscreen mode Exit fullscreen mode

# docker-compose.yml
version: '3.8'
services:
  api:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://app:secret@db:5432/appdb
      REDIS_URL: redis://redis:6379
    depends_on:
      - db
      - redis

  db:
    image: postgres:16-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: appdb
    ports:
      - "5432:5432"

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  postgres_data:

Enter fullscreen mode Exit fullscreen mode

2. Static Site with Nginx

version: '3.8'
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./public:/usr/share/nginx/html:ro
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    restart: unless-stopped

Enter fullscreen mode Exit fullscreen mode

3. Development Environment (Hot Reload)

version: '3.8'
services:
  dev:
    image: node:20-alpine
    working_dir: /app
    command: sh -c "npm install && npm run dev"
    ports:
      - "3000:3000"
      - "9229:9229"  # Node.js debugger
    volumes:
      - .:/app       # Live reload source changes!
      - node_modules:/app/node_modules  # Persist installed modules
    environment:
      - NODE_ENV=development

volumes:
  node_modules:

Enter fullscreen mode Exit fullscreen mode

Performance Tips

1. Optimize Your Dockerfile

# ❌ BAD — Rebuilds everything on any code change
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "server.js"]

# ✅ GOOD — Leverages layer caching
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci                    # Only re-runs if package.json changes
COPY . .
CMD ["node", "server.js"]

# ✅ BETTER — Multi-stage build (smaller final image)
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
CMD ["node", "server.js"]

Enter fullscreen mode Exit fullscreen mode

2. Use .dockerignore

# .dockerignore — like .gitignore for Docker
node_modules
npm-debug.log
.git
.env
coverage
.next
build
.DS_Store
*.md
!README.md

Enter fullscreen mode Exit fullscreen mode

This can cut build time from minutes to seconds.

3. Smaller Base Images

Image Size When to use
node:20 ~1 GB Development
node:20-alpine ~180 MB Production (most cases)
node:20-slim ~200 MB Need glibc compatibility

Common Problems & Solutions

"Permission denied" in mounted volumes

# Add this to your service
user: "${UID:-1000}:${GID:-1000}"

Enter fullscreen mode Exit fullscreen mode

Then run: UID=$(id -u) GID=$(id -g) docker compose up -d

Container eats all memory

# Add memory limits
services:
  app:
    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M

Enter fullscreen mode Exit fullscreen mode

Port already in use

# Find what's using the port
lsof -i :3000

# Kill it or change your mapping
ports:
  - "3001:3000"  # Map host 3001 → container 3000

Enter fullscreen mode Exit fullscreen mode

Images getting too large

# Check what's taking space
docker history your-image:latest

# Clean up in Dockerfile
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

Enter fullscreen mode Exit fullscreen mode

Docker for Side Projects (My Setup)

I run 4 projects on one VPS using Docker Compose:

# docker-compose.yml (production)
version: '3.8'

services:
  agentvote:
    build: ./agentvote
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production

  signal:
    build: ./crypto-signal
    restart: unless-stopped
    ports:
      - "3001:3001"
    volumes:
      - signal_data:/app/data

  blog:
    image: nginx:alpine
    restart: unless-stopped
    volumes:
      - ./blog/public:/usr/share/nginx/html:ro
    ports:
      - "8080:80"

  formatter:
    build: ./text-formatter
    restart: unless-stopped
    ports:
      - "3099:3099"

volumes:
  signal_data:

Enter fullscreen mode Exit fullscreen mode

# Deploy everything
docker compose up -d --build

# Update one service
docker compose up -d --build agentvote

# Check everything's running
docker compose ps

Enter fullscreen mode Exit fullscreen mode

Quick Reference Card

# Lifecycle
docker compose up -d        # Start
docker compose down         # Stop
docker compose restart      # Restart

# Debugging
docker exec -it <svc> sh    # Shell in
docker compose logs -f      # Logs
docker compose ps           # Status

# Maintenance
docker system prune -a      # Cleanup
docker compose pull         # Update images
docker compose up -d --build # Rebuild & restart

Enter fullscreen mode Exit fullscreen mode


What's your Docker setup look like? Still avoiding it?

Follow @armorbreak for more practical DevOps guides.