Skip to content
← All Skills
🐳

Docker

InfrastructureOfficial Site ›

Container orchestration สำหรับ development, CI/CD และ production บน AWS EC2

What I Can Do

  • Build และ run containerized applications
  • เขียน multi-stage Dockerfile เพื่อลด image size
  • จัดการ multi-container apps ด้วย Docker Compose
  • Debug container issues บน production (AWS EC2)
  • Setup volume, network, environment variables อย่างถูกต้อง

Commands I Use Daily

Container Management

bash
# ดู running containers
docker ps

# ดู container ทั้งหมดรวม stopped
docker ps -a

# run container แบบ detach + ตั้งชื่อ + map port
docker run -d --name myapp -p 8080:3000 myapp:latest

# หยุด container
docker stop myapp

# ลบ container
docker rm myapp

# หยุดแล้วลบทีเดียว
docker rm -f myapp

# เข้าไปใน container (shell)
docker exec -it myapp /bin/sh

# run command ใน container โดยไม่เข้า shell
docker exec myapp ls /app

# ดู log แบบ follow + แสดงเวลา
docker logs -f --timestamps myapp

# ดู resource usage แบบ real-time (CPU, memory, network I/O)
docker stats

# ดู config detail ของ container — ใช้ debug network, volume, env
docker inspect myapp

# copy file จาก container ออกมา host
docker cp myapp:/app/config.json ./config.json

# restart container
docker restart myapp

Image Management

bash
# build image จาก Dockerfile + tag
docker build -t myapp:1.0 .

# build ด้วย specific Dockerfile
docker build -f Dockerfile.prod -t myapp:prod .

# ดู images ทั้งหมด
docker image ls

# ดู image size + layers
docker history myapp:latest

# tag image สำหรับ push ไป registry
docker tag myapp:1.0 registry.example.com/myapp:1.0

# push image ไป registry
docker push registry.example.com/myapp:1.0

# pull image จาก registry
docker pull nginx:alpine

# ลบ image
docker rmi myapp:old

# ลบ dangling images (untagged)
docker image prune -f

Docker Compose

bash
# start ทุก services (detach mode)
docker compose up -d

# rebuild แล้ว start (ใช้ตอน code เปลี่ยน)
docker compose up -d --build

# หยุดทุก services
docker compose down

# หยุด + ลบ volumes ด้วย (ระวัง ข้อมูล DB หาย)
docker compose down -v

# ดู status ของ services
docker compose ps

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

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

# restart เฉพาะ service เดียว
docker compose restart api

# scale service (เช่น run 3 instances)
docker compose up -d --scale worker=3

Network & Volume

bash
# ดู network ทั้งหมด — ใช้ตรวจว่า container อยู่ network เดียวกัน
docker network ls

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

# ดู containers ใน network
docker network inspect my-network

# ดู volumes ทั้งหมด
docker volume ls

# ลบ unused volumes
docker volume prune -f

Cleanup & Disk

bash
# ดู disk usage ของ Docker
docker system df

# ล้าง dangling images, stopped containers, unused networks
docker system prune -f

# ล้างทุกอย่างรวม unused volumes (ใช้ตอน disk เต็ม)
docker system prune -a --volumes

Container คืออะไร

Container เป็น lightweight isolated process ที่ run บน shared OS kernel — ต่างจาก VM ที่ต้อง run ทั้ง OS แยก Container ใช้ Linux namespaces + cgroups ในการแยก process, filesystem, network ทำให้ boot เร็วและใช้ resource น้อยกว่า VM มาก

Image vs Container

  • Image = read-only template (เหมือน class) — สร้างจาก Dockerfile, ประกอบด้วยหลาย layers ซ้อนกัน
  • Container = running instance ของ image (เหมือน object) — สร้างจาก docker run, มี writable layer ด้านบน
  • Image เดียวสามารถสร้างหลาย containers ได้

Dockerfile Basics

Dockerfile คือ set of instructions สำหรับ build image — แต่ละ instruction สร้าง 1 layer

  • FROM — base image เช่น golang:1.22-alpine, node:20-slim
  • WORKDIR — set working directory
  • COPY / ADD — copy files เข้า image
  • RUN — execute command ตอน build เช่น install dependencies
  • EXPOSE — declare port (documentation, ไม่ได้ publish จริง)
  • CMD / ENTRYPOINT — command ที่ run ตอน start container

docker run / build / pull

  • docker build -t myapp . — build image จาก Dockerfile
  • docker pull nginx:alpine — download image จาก registry
  • docker run -d --name myapp myapp — run container แบบ detach

Port Mapping

-p host:container — map port จากเครื่อง host เข้า container เช่น -p 8080:3000 ทำให้เข้า localhost:8080 แล้วไปที่ container port 3000

Volume

  • Named volumedocker volume create pgdata + -v pgdata:/var/lib/postgresql/data — Docker manage ให้, persist ข้ามการ recreate container
  • Bind mount-v ./src:/app/src — mount โฟลเดอร์จาก host เข้า container โดยตรง, ใช้ตอน development

Multi-stage Build

แยก build stage ออกจาก runtime stage เพื่อให้ final image เล็กที่สุด — build tools ไม่ติดไปใน production image

dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o main ./cmd/server

FROM alpine:3.19
WORKDIR /app
COPY --from=builder /app/main .
CMD ["./main"]

Docker Compose

จัดการ multi-container applications ด้วย docker-compose.yml — define services, networks, volumes ในไฟล์เดียว ใช้ docker compose up สั่ง run ทุก service พร้อมกัน

Networking (Bridge / Host)

  • Bridge (default) — container อยู่ใน private network, ติดต่อกันผ่าน container name เป็น hostname
  • Host — container ใช้ network ของ host โดยตรง, ไม่มี network isolation
  • Custom bridge network ทำให้ container คุยกันได้ผ่าน DNS โดยไม่ต้อง link

.dockerignore

ระบุ files/folders ที่ไม่ต้อง copy เข้า build context — ลด build time และป้องกัน sensitive files หลุดเข้า image เช่น node_modules, .git, .env

Layer Caching

Docker cache แต่ละ layer — ถ้า instruction ไม่เปลี่ยน ใช้ cache จาก build ก่อน ดังนั้นควร COPY dependency files ก่อน source code เพื่อให้ go mod download หรือ npm install ถูก cache

Resource Limits

กำหนด memory และ CPU limits เพื่อป้องกัน container ใช้ resource เกิน

yaml
services:
  api:
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "1.0"

Container Orchestration Concepts

เข้าใจหลักการของ orchestration (Kubernetes, Docker Swarm) — service discovery, load balancing, rolling updates, self-healing, desired state management

Security (Non-root User, Read-only FS)

  • Run container ด้วย non-root user — USER 1001 ใน Dockerfile
  • ใช้ read-only filesystem — --read-only flag + tmpfs สำหรับ writable paths
  • Scan image หา vulnerabilities ด้วย docker scout หรือ Trivy
  • ไม่ store secrets ใน image — ใช้ environment variables หรือ secret management

Image Optimization

  • ใช้ Alpine หรือ distroless base image
  • Minimize layers — รวม RUN commands ด้วย &&
  • ใช้ .dockerignore อย่างเคร่งครัด
  • Multi-stage build เพื่อ exclude build tools

Health Checks

กำหนด health check เพื่อให้ Docker รู้ว่า container พร้อม serve traffic จริง — ใช้คู่กับ depends_on: condition: service_healthy

yaml
healthcheck:
  test: ["CMD-SHELL", "pg_isready -U user"]
  interval: 5s
  timeout: 3s
  retries: 5

Logging Drivers

Docker รองรับหลาย logging drivers — json-file (default), syslog, fluentd, awslogs เลือกให้เหมาะกับ infrastructure เช่น ใช้ awslogs ส่ง log ตรงไป CloudWatch

Docker in CI/CD

  • Build image ใน CI pipeline แล้ว push ไป container registry
  • ใช้ build cache (BuildKit) เพื่อเร่ง CI build
  • Tag image ด้วย git SHA สำหรับ traceability
  • ใช้ multi-stage build เพื่อ run tests ใน build stage

ปัญหาที่เจอบ่อย & วิธีแก้

Port already in use

Bind for 0.0.0.0:8080 failed: port is already allocated — port ถูกใช้อยู่แล้ว

วิธีแก้: หา process ที่ใช้ port อยู่ด้วย lsof -i :8080 แล้ว kill หรือเปลี่ยน port mapping เป็น -p 8081:3000

Container exits immediately

docker ps -a เห็น status Exited (1) — container start แล้วตายทันที

วิธีแก้: ดู log ด้วย docker logs myapp เพื่อหาสาเหตุ สาเหตุบ่อย: CMD ผิด, binary ไม่มีใน image, config file หาย, permission denied

Cannot connect between containers

Service A เรียก localhost:5432 ไปหา database แต่ connect ไม่ได้

วิธีแก้: ใน Docker network ต้องใช้ container name เป็น hostname ไม่ใช่ localhost เช่น postgres:5432 (ตาม service name ใน compose)

Image build ช้ามาก

ทุกครั้งที่ build ต้อง install dependencies ใหม่หมดทั้งที่ code เปลี่ยนแค่นิดเดียว

วิธีแก้: เรียงลำดับ COPY ใน Dockerfile ให้ copy dependency files (เช่น go.mod, package.json) ก่อน source code เพื่อให้ layer caching ทำงาน

Disk full / No space left on device

Docker กิน disk เยอะจาก dangling images, stopped containers, unused volumes

วิธีแก้: docker system df ดูว่าอะไรกินที่ แล้ว docker system prune -a --volumes ล้าง (ระวัง volumes ที่ยังใช้อยู่)

Permission denied ใน container

File ที่ COPY เข้าไปอ่านไม่ได้ หรือ write ไม่ได้เพราะ run ด้วย non-root user

วิธีแก้: เพิ่ม RUN chown -R 1001:1001 /app ก่อน USER 1001 ใน Dockerfile หรือ set file permissions ให้ถูกต้อง

Environment variables ไม่เข้า container

ตั้ง env ใน .env แล้วแต่ app อ่านไม่ได้

วิธีแก้: ตรวจว่า compose file มี env_file: .env หรือ environment: section ถูกต้อง ใช้ docker exec myapp env ตรวจว่า env เข้าจริงไหม

Volume mount ไม่ sync กับ host

แก้ไฟล์บน host แล้วแต่ container ไม่เห็นการเปลี่ยนแปลง (macOS)

วิธีแก้: macOS มี file sync delay กับ Docker — ลอง restart container หรือใช้ docker compose watch (Compose v2.22+) สำหรับ auto-sync ที่เร็วขึ้น

Related Skills

  • Go — service ที่ run ใน container
  • PostgreSQL — database ที่ run ผ่าน Docker Compose
  • Kafka — message broker ใน containerized environment