ข้ามไปเนื้อหาหลัก

Category: reference

Docker Basics — Container, Image, Compose

คำสั่ง Docker ที่ใช้บ่อยสำหรับ developer: build image, run container, Compose, volume, network

· อ่านประมาณ 4 นาที

สารบัญ

Core Concepts

  • Image — blueprint (read-only) — เหมือน class ใน OOP
  • Container — instance ที่ run จาก image — เหมือน object ที่ new จาก class
  • Volume — persistent storage ที่ attach กับ container
  • Network — virtual network ให้ containers คุยกัน
  • Registry — ที่เก็บ images (Docker Hub, GHCR, ECR)

คำสั่งพื้นฐาน

# ดู images ที่มีอยู่
docker images

# ดู containers ที่กำลัง run
docker ps

# ดู containers ทั้งหมด (รวมที่หยุดแล้ว)
docker ps -a

# ดู resource usage
docker stats

# ลบ containers ที่หยุดแล้ว, unused images, networks
docker system prune
docker system prune -a  # รวม unused images ด้วย

Run Container

# run แบบ interactive (เข้า shell)
docker run -it ubuntu bash

# run แบบ detached (background)
docker run -d nginx

# ตั้งชื่อ container
docker run -d --name my-nginx nginx

# map port: host:container
docker run -d -p 8080:80 nginx

# mount volume: host-path:container-path
docker run -d -v $(pwd):/app node:20

# environment variables
docker run -d -e NODE_ENV=production -e API_KEY=abc node:20

# run แล้วลบ container อัตโนมัติเมื่อจบ
docker run --rm node:20 node -e "console.log('hello')"

Build Image

# build จาก Dockerfile ใน current directory
docker build -t my-app:1.0 .

# build แล้ว tag ด้วย
docker build -t my-app:latest -t my-app:1.0 .

# rebuild ไม่ใช้ cache
docker build --no-cache -t my-app .

# ดู layers ของ image
docker history my-app

Dockerfile สำหรับ Node.js App

# ใช้ slim image (เล็กกว่า node:20 มาก)
FROM node:20-slim

WORKDIR /app

# Copy package files ก่อน (เพื่อ cache layer นี้)
COPY package*.json ./
RUN npm ci --only=production

# Copy source code
COPY . .

# Build ถ้ามี TypeScript
RUN npm run build

EXPOSE 3000
CMD ["node", "dist/index.js"]

Multi-stage build — ลด image size มาก:

# Stage 1: build
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: runtime (เล็กกว่าเดิมมาก)
FROM node:20-slim AS runtime
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]

.dockerignore

node_modules
dist
.env
.git
*.log
*.md
.DS_Store

Container Management

# หยุด container
docker stop my-nginx

# เริ่มใหม่
docker start my-nginx
docker restart my-nginx

# ลบ container
docker rm my-nginx
docker rm -f my-nginx  # force stop แล้วลบ

# เข้า shell ของ container ที่กำลัง run
docker exec -it my-nginx bash

# ดู logs
docker logs my-nginx
docker logs -f my-nginx  # follow (real-time)
docker logs --tail 50 my-nginx

Docker Compose

จัดการหลาย services พร้อมกัน:

# docker-compose.yml
version: '3.9'

services:
  app:
    build: .
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
    volumes:
      - .:/app
      - /app/node_modules   # ไม่ mount node_modules จาก host
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - postgres-data:/var/lib/postgresql/data
    ports:
      - '5432:5432'

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

volumes:
  postgres-data:
# เปิด services ทั้งหมด
docker compose up -d

# ดู logs ทุก services
docker compose logs -f

# ดู logs เฉพาะ service
docker compose logs -f app

# หยุดและลบ containers (ไม่ลบ volumes)
docker compose down

# ลบรวม volumes
docker compose down -v

# rebuild images
docker compose build

# run command ใน service
docker compose exec app bash
docker compose exec db psql -U user mydb

Volumes

# สร้าง named volume
docker volume create my-data

# ดู volumes
docker volume ls

# ลบ volume
docker volume rm my-data

# ลบ unused volumes
docker volume prune

Network

# สร้าง network
docker network create my-network

# ให้ containers คุยกัน
docker run -d --network my-network --name service-a my-image-a
docker run -d --network my-network --name service-b my-image-b
# service-b เรียก service-a ด้วย hostname "service-a"

# ดู networks
docker network ls
docker network inspect my-network

Dev Workflow — Node.js

# run แบบ dev (auto-reload)
docker run -it --rm \
  -v $(pwd):/app \
  -w /app \
  -p 3000:3000 \
  node:20 \
  sh -c "npm install && npm run dev"
# docker-compose.dev.yml
services:
  app:
    image: node:20
    working_dir: /app
    volumes:
      - .:/app
    ports:
      - '3000:3000'
    command: sh -c "npm install && npm run dev"
docker compose -f docker-compose.dev.yml up

Useful Aliases

# ~/.zshrc หรือ ~/.bashrc
alias dps='docker ps'
alias dpsa='docker ps -a'
alias dexec='docker exec -it'
alias dlogs='docker logs -f'
alias dprune='docker system prune -f'
alias dc='docker compose'
alias dcup='docker compose up -d'
alias dcdown='docker compose down'
alias dclogs='docker compose logs -f'