
บทนำ: ทำไม Docker และ Container ถึงเปลี่ยนวงการ IT Infrastructure ไปตลอดกาล?
ในยุค 2026 ถ้าคุณเป็น System Admin หรือ IT Infrastructure Engineer แล้วยังไม่รู้จัก Docker และ Container ก็เหมือนกับช่างยนต์ที่ไม่รู้จักเครื่องยนต์ไฟฟ้า เทคโนโลยี containerization ได้ปฏิวัติวิธีการ deploy, manage และ scale แอปพลิเคชันอย่างสิ้นเชิง ตั้งแต่บริษัท startup เล็กๆ ไปจนถึงองค์กรระดับ enterprise อย่าง Google, Netflix, Spotify ต่างใช้ container เป็นแกนหลักในการ run infrastructure ทั้งหมด
ก่อนมี container สมัยก่อนเราต้องติดตั้งแอปพลิเคชันลงบน server โดยตรง ถ้ามีแอปหลายตัวที่ต้องการ library version ต่างกัน ก็จะเกิดปัญหา “dependency hell” หรือไม่ก็ต้องสร้าง Virtual Machine แยกสำหรับแต่ละแอป ซึ่งกิน resource มหาศาล Container เข้ามาแก้ปัญหานี้โดยการ package แอปพลิเคชันพร้อม dependency ทั้งหมดไว้ในหน่วยเล็กๆ ที่เบา เร็ว และ portable ได้ทุกที่
บทความนี้จะพาคุณเรียนรู้ทุกอย่างเกี่ยวกับ Docker และ Container ตั้งแต่พื้นฐานไปจนถึงการใช้งานจริงในระดับ production เหมาะสำหรับ System Admin, DevOps Engineer, IT Infrastructure Team และทุกคนที่ต้องการก้าวทันเทคโนโลยีที่กำลังเปลี่ยนโลก IT
ส่วนที่ 1: Containerization คืออะไร? ทำความเข้าใจแนวคิดพื้นฐาน
1.1 จาก Bare Metal สู่ VM สู่ Container
เพื่อเข้าใจว่า container คืออะไร ต้องย้อนดูวิวัฒนาการของการ deploy แอปพลิเคชัน:
ยุคที่ 1: Bare Metal (Traditional Deployment)
- ติดตั้ง OS และแอปพลิเคชันลงบน physical server โดยตรง
- 1 server = 1 แอป (หรือหลายแอปที่อาจขัดแย้งกัน)
- การ scale ต้องซื้อ server เพิ่ม ใช้เวลาหลายสัปดาห์
- utilization ต่ำ (ใช้ resource เฉลี่ยแค่ 10-20%)
ยุคที่ 2: Virtual Machines (Virtualized Deployment)
- ใช้ hypervisor (VMware ESXi, Hyper-V, KVM) สร้าง VM หลายตัวบน server เดียว
- แต่ละ VM มี OS เต็มรูปแบบของตัวเอง (Guest OS)
- isolation ดีมาก แต่ VM กิน resource เยอะ (RAM, CPU, disk)
- boot time นาน (นาที) และ image ขนาดใหญ่ (GB)
ยุคที่ 3: Containers (Container Deployment)
- แชร์ OS kernel ของ host กับ container ทุกตัว
- แต่ละ container มี filesystem, network, process space ของตัวเอง (isolation ผ่าน namespaces และ cgroups)
- เบามาก — image ขนาดเล็ก (MB) boot ในวินาที
- utilization สูงมาก — run container ได้หลายสิบหลายร้อยตัวบน server เดียว
1.2 Container คืออะไรในเชิงเทคนิค?
Container คือ isolated process ที่ run อยู่บน host OS โดยใช้ feature ของ Linux kernel 2 อย่างหลัก:
- Namespaces — สร้าง isolated view ของ system resources ให้แต่ละ container เช่น PID namespace (เห็นแค่ process ของตัวเอง), Network namespace (มี network stack ของตัวเอง), Mount namespace (มี filesystem ของตัวเอง), User namespace, IPC namespace, UTS namespace (มี hostname ของตัวเอง)
- Control Groups (cgroups) — จำกัดและจัดสรร resource ที่ container ใช้ได้ เช่น CPU, RAM, Disk I/O, Network bandwidth ป้องกัน container ตัวหนึ่งกิน resource จนกระทบตัวอื่น
- Union Filesystem (OverlayFS) — ระบบ layered filesystem ที่ทำให้ image ประหยัดพื้นที่ โดย layer ที่ซ้ำกันจะ share กันได้
ดังนั้น container ไม่ใช่ VM ไม่มี guest OS ของตัวเอง ไม่มี kernel ของตัวเอง มันคือ process ที่ถูก isolate ด้วยกลไกของ kernel ทำให้เบาและเร็วกว่า VM มาก
1.3 Docker vs VM: เปรียบเทียบแบบจัดเต็ม
ตาราง comparison ระหว่าง container และ virtual machine:
คุณสมบัติ | Container (Docker) | Virtual Machine
-------------------|-----------------------|------------------
Isolation | Process-level | Hardware-level
OS | Share host kernel | Full guest OS
Boot time | วินาที (seconds) | นาที (minutes)
Image size | MB (เล็ก) | GB (ใหญ่)
Resource usage | น้อยมาก | มาก (RAM, CPU)
Performance | Near-native | Overhead จาก hypervisor
Density | สูง (100+ per host) | ต่ำ (10-20 per host)
Portability | สูงมาก | ปานกลาง
Security isolation | ปานกลาง | สูงมาก
Use case | Microservices, CI/CD | Legacy apps, ต้อง OS ต่าง
สรุป: Container ไม่ได้มาแทน VM แต่เป็น complement กัน ในทางปฏิบัติหลายองค์กรรัน container บน VM อีกที เพื่อได้ทั้ง security isolation ของ VM และความเบาของ container
ส่วนที่ 2: Docker คืออะไร? สถาปัตยกรรมและ Component หลัก
2.1 ประวัติของ Docker
Docker เริ่มต้นในปี 2013 โดย Solomon Hykes ที่บริษัท dotCloud (ต่อมาเปลี่ยนชื่อเป็น Docker, Inc.) Docker ไม่ได้ประดิษฐ์ container ขึ้นมาใหม่ (container technology อย่าง LXC มีมาก่อนแล้ว) แต่ Docker ทำให้ container ใช้งานง่าย ด้วย developer-friendly tooling, image format, และ Docker Hub ทำให้ container เข้าถึงคนทั่วไปได้
ปัจจุบัน (2026) Docker ยังคงเป็น container runtime ที่ได้รับความนิยมมากที่สุด แม้ว่าจะมี alternatives อย่าง Podman, containerd, CRI-O ขึ้นมา แต่ Docker ยังเป็นมาตรฐานที่ทุกคนต้องเรียนรู้
2.2 Docker Architecture
Docker ใช้สถาปัตยกรรมแบบ client-server ประกอบด้วย component หลักดังนี้:
Docker Client (docker CLI)
- เป็น command-line tool ที่ผู้ใช้ interact ด้วย
- ส่งคำสั่ง (docker run, docker build, docker pull ฯลฯ) ไปยัง Docker Daemon ผ่าน REST API
- สามารถ connect ไปยัง remote Docker Daemon ได้ (ผ่าน TCP/TLS)
Docker Daemon (dockerd)
- เป็น background process หลักที่ run อยู่บน host machine
- รับคำสั่งจาก Docker Client ผ่าน Unix socket (/var/run/docker.sock) หรือ TCP
- manage ทุกอย่าง: images, containers, networks, volumes
- ภายใต้ Docker Daemon จะใช้ containerd เป็น container runtime จริงๆ
containerd
- เป็น high-level container runtime ที่ manage container lifecycle (create, start, stop, delete)
- เป็น CNCF graduated project ใช้ได้โดยไม่ต้องมี Docker
- ภายใน containerd ใช้ runc เป็น low-level runtime ในการสร้าง container จริงๆ
Docker Registry
- เป็นที่เก็บ Docker Images คล้ายกับ Git repository
- Docker Hub คือ public registry ที่ใหญ่ที่สุด (hub.docker.com)
- สามารถตั้ง private registry ได้ (Harbor, GitLab Container Registry, AWS ECR, Azure ACR)
Docker Objects:
- Image — template (read-only) ที่ใช้สร้าง container ประกอบด้วย layers ซ้อนกัน
- Container — running instance ของ image (มี writable layer ด้านบน)
- Volume — persistent storage ที่อยู่นอก container lifecycle
- Network — virtual network ที่เชื่อม container เข้าด้วยกัน
ส่วนที่ 3: การติดตั้ง Docker (Windows และ Linux)
3.1 ติดตั้ง Docker บน Ubuntu/Debian Linux
การติดตั้ง Docker บน Linux เป็นวิธีที่แนะนำมากที่สุดสำหรับ production:
# อัปเดต package index
sudo apt update
# ติดตั้ง prerequisites
sudo apt install -y ca-certificates curl gnupg lsb-release
# เพิ่ม Docker official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# เพิ่ม Docker repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list
# ติดตั้ง Docker Engine
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# ทดสอบ
sudo docker run hello-world
# เพิ่ม user ปัจจุบันเข้า docker group (ไม่ต้องใช้ sudo)
sudo usermod -aG docker $USER
newgrp docker
3.2 ติดตั้ง Docker บน CentOS/RHEL/Rocky Linux
# ติดตั้ง prerequisites
sudo yum install -y yum-utils
# เพิ่ม Docker repo
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# ติดตั้ง Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Start Docker service
sudo systemctl start docker
sudo systemctl enable docker
# ทดสอบ
sudo docker run hello-world
3.3 ติดตั้ง Docker Desktop บน Windows
สำหรับ Windows 10/11 Pro หรือ Enterprise:
- ต้องเปิด WSL2 (Windows Subsystem for Linux 2) ก่อน
- ดาวน์โหลด Docker Desktop จาก docker.com
- ติดตั้งและ restart เครื่อง
- Docker Desktop จะ run Docker Engine ภายใน WSL2 Linux VM
- สามารถใช้ docker CLI ได้ทั้งจาก PowerShell, CMD และ WSL terminal
# เปิด WSL2 (PowerShell as Admin)
wsl --install
# ดาวน์โหลดและติดตั้ง Docker Desktop
# https://desktop.docker.com/win/main/amd64/Docker%20Desktop%20Installer.exe
# ทดสอบหลังติดตั้ง
docker version
docker run hello-world
3.4 Post-installation: ตั้งค่าเบื้องต้น
หลังติดตั้งเสร็จ ควรตั้งค่าเพิ่มเติม:
# ตั้ง Docker ให้ start เมื่อ boot (Linux)
sudo systemctl enable docker
sudo systemctl enable containerd
# ตั้งค่า logging driver (ป้องกัน log บวม)
sudo nano /etc/docker/daemon.json
# เพิ่มเนื้อหา:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
# Restart Docker
sudo systemctl restart docker
# ตรวจสอบ Docker info
docker info
ส่วนที่ 4: Docker Commands พื้นฐานที่ต้องรู้
4.1 คำสั่งจัดการ Images
# ดึง image จาก Docker Hub
docker pull nginx
docker pull nginx:1.25-alpine # ระบุ tag เฉพาะ
docker pull ubuntu:22.04
# ดู images ทั้งหมดในเครื่อง
docker images
docker image ls
# ค้นหา image บน Docker Hub
docker search mysql
# ลบ image
docker rmi nginx
docker image rm nginx:1.25-alpine
# ลบ images ที่ไม่ได้ใช้ (dangling)
docker image prune -a
# ดูรายละเอียด image (layers, size)
docker image inspect nginx
# ดูประวัติ layers ของ image
docker image history nginx
4.2 คำสั่งจัดการ Containers
# Run container ใหม่
docker run nginx # foreground mode
docker run -d nginx # detached (background) mode
docker run -d --name web nginx # ตั้งชื่อ container
docker run -d -p 8080:80 nginx # map port 8080 (host) -> 80 (container)
docker run -d -p 8080:80 --name web nginx # รวมทุกอย่าง
docker run -it ubuntu bash # interactive + tty (เข้า shell)
# ดู containers ที่กำลัง run
docker ps
docker container ls
# ดู containers ทั้งหมด (รวมที่หยุดแล้ว)
docker ps -a
# หยุด container
docker stop web
docker stop $(docker ps -q) # หยุดทุก container
# Start container ที่หยุดอยู่
docker start web
# Restart container
docker restart web
# ลบ container
docker rm web
docker rm -f web # force remove (แม้กำลัง run อยู่)
# ลบ containers ทั้งหมดที่หยุดแล้ว
docker container prune
4.3 คำสั่ง Exec, Logs และ Inspect
# เข้าไปใน container ที่กำลัง run อยู่
docker exec -it web bash
docker exec -it web sh # ถ้า image ไม่มี bash (alpine)
docker exec web cat /etc/nginx/nginx.conf # run command เดียว
# ดู logs ของ container
docker logs web
docker logs -f web # follow (real-time)
docker logs --tail 100 web # ดู 100 บรรทัดล่าสุด
docker logs --since 1h web # ดู log ย้อนหลัง 1 ชั่วโมง
# ดูรายละเอียด container
docker inspect web
docker inspect --format '{{.NetworkSettings.IPAddress}}' web # ดูเฉพาะ IP
# ดู resource usage
docker stats
docker stats web
# ดู processes ภายใน container
docker top web
# Copy files เข้า/ออก container
docker cp myfile.txt web:/tmp/
docker cp web:/var/log/nginx/access.log ./
4.4 คำสั่ง Build และ Push
# Build image จาก Dockerfile
docker build -t myapp:1.0 .
docker build -t myapp:1.0 -f Dockerfile.prod . # ระบุ Dockerfile
docker build --no-cache -t myapp:1.0 . # build โดยไม่ใช้ cache
# Tag image
docker tag myapp:1.0 myregistry.com/myapp:1.0
docker tag myapp:1.0 myapp:latest
# Push image ไป registry
docker login
docker push myregistry.com/myapp:1.0
# Save image เป็นไฟล์ (สำหรับ transfer แบบ offline)
docker save myapp:1.0 -o myapp.tar
# Load image จากไฟล์
docker load -i myapp.tar
ส่วนที่ 5: Dockerfile — เขียน Recipe สำหรับสร้าง Image
5.1 Dockerfile Basics
Dockerfile คือ text file ที่บอก Docker ว่าจะสร้าง image อย่างไร แต่ละบรรทัดเป็น instruction ที่สร้าง layer ใหม่:
# ตัวอย่าง Dockerfile สำหรับ Node.js app
FROM node:20-alpine
# Set working directory
WORKDIR /app
# Copy package files ก่อน (เพื่อใช้ cache layer)
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy source code
COPY . .
# Expose port
EXPOSE 3000
# Set non-root user
USER node
# Start application
CMD ["node", "server.js"]
5.2 คำสั่ง Dockerfile ที่สำคัญ
- FROM — กำหนด base image ที่จะใช้ ทุก Dockerfile ต้องเริ่มด้วย FROM
- WORKDIR — กำหนด working directory ภายใน container (เหมือน cd)
- COPY — คัดลอกไฟล์จาก host เข้า image (ใช้แทน ADD เมื่อไม่ต้องการ auto-extract)
- ADD — เหมือน COPY แต่สามารถ extract tar files และดึงไฟล์จาก URL ได้
- RUN — execute command ระหว่าง build (เช่น apt install, npm install)
- CMD — คำสั่งที่ run เมื่อ container start (override ได้ตอน docker run)
- ENTRYPOINT — คำสั่งหลักที่ run เมื่อ container start (ไม่ถูก override ง่ายๆ)
- ENV — กำหนด environment variable
- EXPOSE — ประกาศว่า container listen port อะไร (documentation purpose)
- VOLUME — ประกาศ mount point สำหรับ persistent data
- USER — กำหนด user ที่ใช้ run คำสั่งถัดไป
- ARG — กำหนด build-time variable (ใช้ได้เฉพาะตอน build)
- HEALTHCHECK — กำหนดวิธีตรวจสอบสุขภาพ container
5.3 Dockerfile Best Practices
การเขียน Dockerfile ที่ดีมีผลอย่างมากต่อ security, build speed และ image size:
1. ใช้ specific base image tag (อย่าใช้ latest)
# ไม่ดี
FROM node:latest
# ดี
FROM node:20.11-alpine3.19
2. ใช้ multi-stage build เพื่อลดขนาด image
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Production (image สุดท้ายจะเล็กมาก)
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
USER node
CMD ["node", "dist/server.js"]
3. ลำดับ COPY ให้ถูกต้องเพื่อใช้ cache ให้มีประสิทธิภาพ
- ไฟล์ที่เปลี่ยนน้อย (package.json) COPY ก่อน แล้ว RUN install
- ไฟล์ที่เปลี่ยนบ่อย (source code) COPY ทีหลัง
- เพราะ Docker cache ทำงานแบบ layer-by-layer ถ้า layer ก่อนหน้าไม่เปลี่ยน ก็ใช้ cache ได้
4. รวม RUN commands เพื่อลดจำนวน layers
# ไม่ดี (3 layers)
RUN apt update
RUN apt install -y curl
RUN apt clean
# ดี (1 layer)
RUN apt update && apt install -y --no-install-recommends curl && apt clean && rm -rf /var/lib/apt/lists/*
5. ใช้ .dockerignore
# .dockerignore
node_modules
.git
.env
*.log
docker-compose*.yml
README.md
6. อย่า run เป็น root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
7. ใช้ HEALTHCHECK
HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD curl -f http://localhost:3000/health || exit 1
ส่วนที่ 6: Docker Compose — จัดการ Multi-Container Applications
6.1 Docker Compose คืออะไร?
Docker Compose คือเครื่องมือสำหรับ define และ run แอปพลิเคชันที่ประกอบด้วยหลาย containers ใช้ไฟล์ YAML (docker-compose.yml หรือ compose.yml) ในการกำหนดค่า services, networks และ volumes ทั้งหมด แทนที่จะพิมพ์คำสั่ง docker run ยาวๆ ทีละ container ก็สั่ง docker compose up เพียงคำสั่งเดียว
6.2 ตัวอย่าง Docker Compose สำหรับ WordPress + MySQL
ตัวอย่างนี้เหมาะมากสำหรับ IT Ops ที่ต้องการ deploy WordPress ให้ทีมทดสอบ:
# docker-compose.yml
version: '3.8'
services:
db:
image: mysql:8.0
container_name: wp-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: rootpass123
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass123
volumes:
- db_data:/var/lib/mysql
networks:
- wp-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
wordpress:
image: wordpress:6.4-php8.3-apache
container_name: wp-app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wppass123
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html
networks:
- wp-network
volumes:
db_data:
wp_data:
networks:
wp-network:
driver: bridge
6.3 คำสั่ง Docker Compose ที่สำคัญ
# Start ทุก services (background mode)
docker compose up -d
# ดู status ของ services
docker compose ps
# ดู logs
docker compose logs
docker compose logs -f wordpress # follow logs ของ service เฉพาะ
# หยุดทุก services
docker compose down
# หยุดและลบ volumes ด้วย (ระวัง! ข้อมูลหาย)
docker compose down -v
# Rebuild images
docker compose build
docker compose up -d --build # build ใหม่แล้ว start
# Scale service
docker compose up -d --scale web=3
# Execute command ใน service
docker compose exec db mysql -u root -p
6.4 ตัวอย่าง Docker Compose สำหรับ Full-Stack Application
# docker-compose.yml สำหรับ Node.js + Redis + MongoDB + Nginx
version: '3.8'
services:
app:
build: .
container_name: node-app
restart: unless-stopped
environment:
- NODE_ENV=production
- MONGO_URL=mongodb://mongo:27017/myapp
- REDIS_URL=redis://redis:6379
depends_on:
- mongo
- redis
networks:
- app-network
nginx:
image: nginx:1.25-alpine
container_name: nginx-proxy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- app
networks:
- app-network
mongo:
image: mongo:7
container_name: mongodb
restart: unless-stopped
volumes:
- mongo_data:/data/db
networks:
- app-network
redis:
image: redis:7-alpine
container_name: redis-cache
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- app-network
volumes:
mongo_data:
redis_data:
networks:
app-network:
driver: bridge
ส่วนที่ 7: Docker Networking — เครือข่ายใน Container
7.1 Docker Network Drivers
Docker มี network driver หลายแบบ แต่ละแบบเหมาะกับ use case ต่างกัน:
Bridge Network (default)
- เป็น default network สำหรับ standalone containers
- Docker สร้าง virtual bridge (docker0) บน host
- containers ที่อยู่ใน bridge เดียวกันสามารถคุยกันได้ผ่าน IP
- ถ้าใช้ user-defined bridge สามารถ resolve container name เป็น IP ได้ (DNS)
- เหมาะสำหรับ: single-host deployment
# สร้าง custom bridge network
docker network create my-network
# Run container ใน network ที่สร้าง
docker run -d --name web --network my-network nginx
docker run -d --name api --network my-network node-app
# container ชื่อ api สามารถเข้าถึง web ได้ผ่านชื่อ: curl http://web
Host Network
- container ใช้ network stack ของ host โดยตรง (ไม่มี network isolation)
- performance ดีที่สุด (ไม่มี NAT overhead)
- แต่ port ชนกันได้ถ้าหลาย container ใช้ port เดียวกัน
- เหมาะสำหรับ: high-performance applications, network monitoring tools
docker run -d --network host nginx
Overlay Network
- สร้าง virtual network ข้าม hosts หลายเครื่อง (multi-host networking)
- ใช้กับ Docker Swarm หรือ Kubernetes
- ใช้ VXLAN encapsulation สำหรับ cross-host communication
- เหมาะสำหรับ: cluster deployment, microservices ที่ run บนหลาย hosts
Macvlan Network
- กำหนด MAC address ให้ container ให้เหมือนเป็น physical device บน network
- container สามารถมี IP จาก DHCP ของ physical network ได้
- เหมาะสำหรับ: legacy applications ที่ต้องมี IP จริงบน LAN, network appliances
7.2 คำสั่ง Network ที่ใช้บ่อย
# ดู networks ทั้งหมด
docker network ls
# ดูรายละเอียด network
docker network inspect bridge
# สร้าง network
docker network create --driver bridge --subnet 172.20.0.0/16 my-net
# เชื่อม container เข้า network
docker network connect my-net web
# ถอด container ออกจาก network
docker network disconnect my-net web
# ลบ network
docker network rm my-net
ส่วนที่ 8: Docker Volumes — จัดการ Persistent Storage
8.1 ทำไมต้องใช้ Volume?
Container เป็น ephemeral (ชั่วคราว) — เมื่อ container ถูกลบ ข้อมูลภายในจะหายไปด้วย ถ้าเราต้องการเก็บข้อมูลถาวร (database files, uploaded files, config files) ต้องใช้ Volume
8.2 ประเภทของ Storage ใน Docker
Named Volumes (แนะนำ)
- Docker manage ให้ทั้งหมด เก็บใน /var/lib/docker/volumes/
- portable, backup ง่าย ใช้ง่ายที่สุด
# สร้าง volume
docker volume create db-data
# ใช้ volume กับ container
docker run -d -v db-data:/var/lib/mysql mysql:8.0
# ดู volumes ทั้งหมด
docker volume ls
# ดูรายละเอียด volume
docker volume inspect db-data
# ลบ volume
docker volume rm db-data
# ลบ volumes ที่ไม่ได้ใช้
docker volume prune
Bind Mounts
- mount directory จาก host เข้า container โดยตรง
- เหมาะสำหรับ development (แก้ code บน host แล้วเห็นผลใน container ทันที)
- ต้องระบุ absolute path
# Bind mount
docker run -d -v /home/user/myapp:/app -p 3000:3000 node:20
# Read-only bind mount
docker run -d -v /home/user/config:/etc/myapp:ro myapp
tmpfs Mounts
- เก็บข้อมูลใน RAM ของ host (ไม่เขียนลง disk)
- เร็วมาก แต่หายไปเมื่อ container หยุด
- เหมาะสำหรับ sensitive data ที่ไม่ต้องการให้อยู่บน disk (secrets, session data)
docker run -d --tmpfs /tmp:rw,size=100m myapp
8.3 Backup และ Restore Volume
# Backup volume เป็น tar
docker run --rm -v db-data:/data -v $(pwd):/backup alpine tar czf /backup/db-backup-$(date +%Y%m%d).tar.gz -C /data .
# Restore volume จาก tar
docker run --rm -v db-data:/data -v $(pwd):/backup alpine tar xzf /backup/db-backup-20260408.tar.gz -C /data
ส่วนที่ 9: Docker Hub และ Private Registry
9.1 Docker Hub
Docker Hub (hub.docker.com) คือ public registry ที่ใหญ่ที่สุดของ Docker มี image สำเร็จรูปหลายล้าน images:
- Official Images — images ที่ Docker, Inc. ดูแลร่วมกับผู้พัฒนา (nginx, mysql, node, python, redis) ปลอดภัย อัปเดตสม่ำเสมอ
- Verified Publisher — images จากบริษัทที่ Docker ตรวจสอบแล้ว (Microsoft, Oracle, Bitnami)
- Community Images — images จากผู้ใช้ทั่วไป ต้องตรวจสอบก่อนใช้
ข้อควรระวัง: อย่าใช้ community image ที่ไม่รู้จักใน production ให้ใช้ official หรือ verified publisher เท่านั้น หรือ build image เอง
9.2 Private Registry
สำหรับองค์กร ควรมี private registry เพื่อเก็บ images ภายใน:
ตัวเลือก Private Registry ยอดนิยม:
- Docker Registry (official) — open-source, ใช้ได้ฟรี แต่ไม่มี UI
- Harbor — CNCF graduated project, มี UI, vulnerability scanning, RBAC, replication
- GitLab Container Registry — มาพร้อม GitLab ใช้ได้เลย
- AWS ECR, Azure ACR, Google GCR — managed registry บน cloud
- JFrog Artifactory — enterprise-grade, รองรับหลาย format
# ตั้ง private registry ง่ายๆ ด้วย Docker
docker run -d -p 5000:5000 --name registry -v registry_data:/var/lib/registry registry:2
# Push image ไป private registry
docker tag myapp:1.0 localhost:5000/myapp:1.0
docker push localhost:5000/myapp:1.0
# Pull image จาก private registry
docker pull localhost:5000/myapp:1.0
ส่วนที่ 10: Container Security — ความปลอดภัยของ Container
10.1 Security Best Practices
Container security เป็นเรื่องสำคัญมาก โดยเฉพาะใน production:
Image Security:
- ใช้ official base images หรือ build จาก minimal images (alpine, distroless)
- Scan images หา vulnerability ด้วย Trivy, Snyk, Docker Scout
- อย่าเก็บ secrets (passwords, API keys) ใน image ใช้ Docker Secrets หรือ environment variables
- ใช้ multi-stage build เพื่อลดขนาดและ attack surface
- Sign images ด้วย Docker Content Trust (DCT) หรือ Cosign
Runtime Security:
- อย่า run container เป็น root — ใช้ USER instruction ใน Dockerfile
- ใช้ read-only filesystem: docker run –read-only myapp
- จำกัด resources: docker run –memory=512m –cpus=1 myapp
- Drop unnecessary Linux capabilities: docker run –cap-drop ALL –cap-add NET_BIND_SERVICE myapp
- ใช้ security profiles: AppArmor, Seccomp
- ใช้ network policies เพื่อจำกัดการสื่อสารระหว่าง containers
Host Security:
- อัปเดต Docker Engine สม่ำเสมอ
- ป้องกัน Docker socket (/var/run/docker.sock) — ใครที่เข้าถึงได้มีสิทธิ์เทียบเท่า root
- ใช้ rootless Docker ถ้าเป็นไปได้ (Docker Rootless Mode)
- เปิด Docker Content Trust (DOCKER_CONTENT_TRUST=1)
10.2 Vulnerability Scanning ด้วย Trivy
# ติดตั้ง Trivy
sudo apt install -y trivy
# Scan Docker image
trivy image nginx:1.25
trivy image --severity HIGH,CRITICAL myapp:1.0
# Scan Dockerfile
trivy config Dockerfile
# Scan ใน CI/CD pipeline
trivy image --exit-code 1 --severity CRITICAL myapp:1.0
ส่วนที่ 11: Docker in Production — Swarm vs Kubernetes Overview
11.1 ทำไมต้องมี Orchestration?
เมื่อมี container จำนวนมากใน production ต้องมีระบบจัดการที่ดูแล:
- Scheduling — กระจาย container ไปยัง host ที่เหมาะสม
- Scaling — เพิ่ม/ลด replica ตาม load
- Self-healing — restart container ที่ fail อัตโนมัติ
- Load balancing — กระจาย traffic ไปยัง replicas
- Rolling updates — อัปเดตโดยไม่ downtime
- Service discovery — ค้นหา container/service โดยใช้ชื่อ
- Secret management — จัดการ credentials อย่างปลอดภัย
11.2 Docker Swarm
Docker Swarm คือ built-in orchestration ของ Docker มาพร้อมกับ Docker Engine:
- ข้อดี: ใช้ง่าย ไม่ต้องติดตั้งเพิ่ม เรียนรู้เร็ว ใช้ Docker Compose file ได้เลย
- ข้อเสีย: feature น้อยกว่า Kubernetes, community เล็กกว่า, ecosystem จำกัด
- เหมาะสำหรับ: องค์กรเล็ก-กลาง, ทีมที่ไม่มีคนเชี่ยวชาญ Kubernetes
# Init Swarm mode
docker swarm init
# Deploy stack จาก compose file
docker stack deploy -c docker-compose.yml mystack
# ดู services
docker service ls
# Scale service
docker service scale mystack_web=5
# Rolling update
docker service update --image nginx:1.26 mystack_web
11.3 Kubernetes (K8s) Overview
Kubernetes คือ container orchestration platform ที่ทรงพลังที่สุดในปัจจุบัน พัฒนาโดย Google แล้ว donate ให้ CNCF:
- ข้อดี: feature ครบทุกอย่าง, ecosystem ใหญ่มาก, cloud provider ทุกรายรองรับ (EKS, AKS, GKE)
- ข้อเสีย: complexity สูง เรียนรู้ยาก ต้องมีทีม dedicated
- เหมาะสำหรับ: องค์กรขนาดกลาง-ใหญ่, microservices architecture, multi-cloud deployment
เลือกอะไรดี? ถ้า container น้อยกว่า 50 ตัว และไม่ต้องการ advanced features ใช้ Docker Swarm ถ้ามากกว่านั้นหรือต้องการ auto-scaling, canary deployment, service mesh ใช้ Kubernetes
ส่วนที่ 12: Monitoring Containers — Portainer และ cAdvisor
12.1 Portainer — GUI สำหรับจัดการ Docker
Portainer เป็น web-based management UI สำหรับ Docker ที่ดีที่สุดในปัจจุบัน ใช้ง่าย ติดตั้งเร็ว:
# ติดตั้ง Portainer CE (Community Edition)
docker volume create portainer_data
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
# เข้าใช้งาน: https://localhost:9443
Portainer ทำอะไรได้บ้าง:
- ดูและจัดการ containers, images, volumes, networks ผ่าน web UI
- Deploy stack จาก Docker Compose
- ดู logs, console access (exec) ผ่าน browser
- จัดการ Docker Swarm และ Kubernetes clusters
- User management และ RBAC
- Container templates (deploy apps สำเร็จรูป)
12.2 cAdvisor — Resource Monitoring
cAdvisor (Container Advisor) พัฒนาโดย Google ใช้ monitor resource usage ของ container:
# Run cAdvisor
docker run -d --name cadvisor --volume=/:/rootfs:ro --volume=/var/run:/var/run:ro --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --publish=8080:8080 gcr.io/cadvisor/cadvisor:latest
# เข้าใช้งาน: http://localhost:8080
12.3 Full Monitoring Stack: Prometheus + Grafana
สำหรับ production monitoring ควรใช้ stack เต็มรูปแบบ:
# docker-compose-monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
restart: unless-stopped
grafana:
image: grafana/grafana:latest
container_name: grafana
volumes:
- grafana_data:/var/lib/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
restart: unless-stopped
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
ports:
- "9100:9100"
restart: unless-stopped
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker:/var/lib/docker:ro
ports:
- "8080:8080"
restart: unless-stopped
volumes:
prometheus_data:
grafana_data:
ส่วนที่ 13: Use Cases สำหรับ IT Ops — ตัวอย่างการใช้งานจริง
13.1 Database Containers
IT Ops ใช้ Docker สำหรับ database development/staging ได้ดีมาก:
# MySQL 8.0
docker run -d --name mysql-dev -e MYSQL_ROOT_PASSWORD=rootpass -e MYSQL_DATABASE=devdb -v mysql_data:/var/lib/mysql -p 3306:3306 mysql:8.0
# PostgreSQL 16
docker run -d --name postgres-dev -e POSTGRES_PASSWORD=pgpass -e POSTGRES_DB=devdb -v pg_data:/var/lib/postgresql/data -p 5432:5432 postgres:16-alpine
# MongoDB 7
docker run -d --name mongo-dev -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=mongopass -v mongo_data:/data/db -p 27017:27017 mongo:7
# Redis 7
docker run -d --name redis-cache -v redis_data:/data -p 6379:6379 redis:7-alpine redis-server --requirepass redispass
13.2 Web Server Containers
# Nginx reverse proxy
docker run -d --name nginx-proxy -p 80:80 -p 443:443 -v ./nginx.conf:/etc/nginx/nginx.conf:ro -v ./certs:/etc/nginx/certs:ro nginx:1.25-alpine
# Apache HTTP Server
docker run -d --name apache-web -p 8080:80 -v ./html:/usr/local/apache2/htdocs/ httpd:2.4-alpine
# Traefik (modern reverse proxy with auto SSL)
docker run -d --name traefik -p 80:80 -p 443:443 -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock traefik:v3.0 --api.insecure=true --providers.docker
13.3 Development Environment
สร้าง dev environment ที่ consistent สำหรับทั้งทีม:
# docker-compose-dev.yml
version: '3.8'
services:
# Code editor in browser
code-server:
image: lscr.io/linuxserver/code-server:latest
container_name: code-server
environment:
- PASSWORD=devpass123
volumes:
- ./workspace:/config/workspace
ports:
- "8443:8443"
# phpMyAdmin
phpmyadmin:
image: phpmyadmin:latest
container_name: pma
environment:
- PMA_HOST=db
- PMA_PORT=3306
ports:
- "8081:80"
# MailHog (email testing)
mailhog:
image: mailhog/mailhog:latest
container_name: mailhog
ports:
- "1025:1025" # SMTP
- "8025:8025" # Web UI
13.4 IT Infrastructure Tools ใน Container
หลาย IT tools สามารถ deploy ผ่าน Docker ได้ง่ายดาย:
- Pi-hole — DNS ad blocker สำหรับ network ทั้งหมด
- Grafana + Prometheus — monitoring และ alerting
- GitLab CE — self-hosted Git server พร้อม CI/CD
- Nextcloud — self-hosted cloud storage (ทดแทน Google Drive)
- Zabbix — network monitoring
- Guacamole — clientless remote desktop gateway (RDP/SSH/VNC ผ่าน browser)
- Vault — secrets management
- AWX/Semaphore — Ansible automation UI
ส่วนที่ 14: Docker Troubleshooting — แก้ปัญหาที่พบบ่อย
14.1 Container ไม่ Start
# ดู logs เพื่อหาสาเหตุ
docker logs container_name
# ดู exit code
docker inspect container_name --format='{{.State.ExitCode}}'
# Exit code 0 = ปกติ, 1 = application error, 137 = killed (OOM), 139 = segfault
# ดู events
docker events --since 1h
# ลอง run แบบ interactive เพื่อ debug
docker run -it --entrypoint /bin/sh myapp:1.0
14.2 Port ชนกัน
# Error: Bind for 0.0.0.0:80 failed: port is already allocated
# หา process ที่ใช้ port อยู่
sudo lsof -i :80
# หรือ
sudo netstat -tlnp | grep :80
# เปลี่ยน port mapping
docker run -d -p 8080:80 nginx # ใช้ port 8080 แทน
14.3 Disk เต็มจาก Docker
# ดู disk usage ของ Docker
docker system df
docker system df -v # verbose
# ลบ resources ที่ไม่ใช้แล้ว
docker system prune # ลบ stopped containers, dangling images, unused networks
docker system prune -a # ลบทุกอย่างที่ไม่ใช้ (รวม images ที่ไม่มี container ใช้)
docker system prune --volumes # รวม volumes ด้วย
# ตั้ง log rotation (ป้องกัน log ไฟล์บวม)
# ใน /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
14.4 Container ช้าหรือกิน RAM มากเกินไป
# ดู resource usage real-time
docker stats
# จำกัด memory
docker run -d --memory=512m --memory-swap=1g myapp
# จำกัด CPU
docker run -d --cpus=1.5 myapp # ใช้ได้ 1.5 CPU cores
docker run -d --cpu-shares=512 myapp # relative weight
# ดู resource limits ของ container
docker inspect container_name | grep -A 10 "Resources"
14.5 Network Issues
# ตรวจสอบ container IP
docker inspect -f '{{.NetworkSettings.IPAddress}}' container_name
# ตรวจสอบ DNS resolution ภายใน container
docker exec container_name nslookup other_container
# ตรวจสอบ connectivity ระหว่าง containers
docker exec container_name ping other_container
docker exec container_name curl http://other_container:port
# ดู network ที่ container เชื่อมอยู่
docker inspect container_name | grep -A 20 "Networks"
14.6 Image Build ช้า
# ใช้ BuildKit (เร็วกว่า builder เดิม)
DOCKER_BUILDKIT=1 docker build -t myapp .
# ใช้ --cache-from สำหรับ CI/CD
docker build --cache-from myregistry/myapp:cache -t myapp .
# ตรวจสอบ .dockerignore ให้ครบ
# ไม่ส่ง node_modules, .git, logs เข้า build context
ส่วนที่ 15: Docker Cheat Sheet — คำสั่งที่ใช้บ่อย
# === LIFECYCLE ===
docker run -d -p 80:80 --name web nginx # สร้างและ run
docker start/stop/restart web # จัดการ container
docker rm -f web # ลบ container
# === INFO ===
docker ps -a # ดู containers ทั้งหมด
docker logs -f web # ดู logs (follow)
docker stats # ดู resource usage
docker inspect web # ดูรายละเอียดทั้งหมด
# === EXEC ===
docker exec -it web bash # เข้า shell
docker cp file.txt web:/tmp/ # copy file เข้า container
# === IMAGE ===
docker build -t myapp:1.0 . # build image
docker images # ดู images
docker pull/push image_name # ดึง/ส่ง image
# === CLEANUP ===
docker system prune -a # ลบทุกอย่างที่ไม่ใช้
docker volume prune # ลบ volumes ที่ไม่ใช้
# === COMPOSE ===
docker compose up -d # start ทุก services
docker compose down # หยุดทุก services
docker compose logs -f # ดู logs ทุก services
สรุป
Docker และ Container technology เป็นทักษะที่ IT Ops ทุกคนต้องมีในปี 2026 ไม่ว่าจะเป็น System Admin, DevOps Engineer หรือ Infrastructure Team container ช่วยให้การ deploy, manage และ scale แอปพลิเคชันทำได้ง่าย เร็ว และ consistent กว่าวิธีแบบเดิมอย่างมาก
สิ่งที่ควรเริ่มทำตอนนี้:
- ติดตั้ง Docker บนเครื่องตัวเองและเริ่มทดลอง run containers
- เรียนรู้ Dockerfile และ Docker Compose เพื่อ define infrastructure as code
- ใช้ Docker ในงานจริง เริ่มจาก development environments, database containers, IT tools
- ศึกษา container security เพราะ security เป็นเรื่องสำคัญที่สุดสำหรับ production
- เรียนรู้ orchestration (Docker Swarm สำหรับ simple use cases, Kubernetes สำหรับ enterprise)
Container ไม่ใช่เทคโนโลยีที่จะหายไป — มันเป็นมาตรฐานใหม่ของการ deploy แอปพลิเคชัน และยิ่งทวีความสำคัญมากขึ้นทุกปี ลงมือเรียนรู้วันนี้ แล้วคุณจะเห็นว่ามันเปลี่ยนวิธีทำงานของคุณไปตลอดกาล
หากสนใจศึกษาเพิ่มเติมเกี่ยวกับ VMware Virtualization, Linux Server, Backup & DR และ Network Monitoring สามารถอ่านบทความเพิ่มเติมได้ที่ siamlancard.com