
Docker คืออะไร? ทำไม IT ยุค 2026 ต้องรู้?
Docker คือ Platform สำหรับสร้าง จัดการ และรัน Container ซึ่งเป็นวิธีการ Package Application พร้อมทุกอย่างที่จำเป็น (Code, Runtime, Libraries, Config) ไว้ในหน่วยเดียวที่สามารถรันได้ทุกที่ ไม่ว่าจะเป็น Laptop, Server หรือ Cloud
ในปี 2026 Docker กลายเป็น ทักษะพื้นฐาน ที่ IT Operations, Developer และ DevOps ทุกคนต้องมี เพราะ 80%+ ขององค์กรใช้ Container ในการ Deploy Application ไม่ว่าจะเป็น Microservices, CI/CD Pipeline หรือแม้แต่ Testing Environment
Container vs Virtual Machine
| เปรียบเทียบ | Container (Docker) | Virtual Machine (VM) |
|---|---|---|
| Boot Time | วินาที (1-3 sec) | นาที (30-120 sec) |
| ขนาด | MB (10-500 MB) | GB (2-20 GB) |
| OS | Share Host Kernel | แต่ละ VM มี OS เต็ม |
| Performance | Near-native | Overhead จาก Hypervisor |
| Isolation | Process-level | Full Hardware-level |
| Resource Usage | น้อย (แชร์ Kernel) | มาก (OS ซ้ำกันทุก VM) |
| Density | รันได้หลายร้อยตัว/Host | รันได้ไม่กี่สิบตัว/Host |
| Use Case | Microservices, CI/CD, Dev/Test | Legacy App, แยก OS ต่างกัน |
Docker Architecture
# Docker Architecture Overview
#
# ┌─────────────────────────────────────────┐
# │ Docker Client (CLI) │
# │ docker run, docker build, docker ps │
# └─────────────┬───────────────────────────┘
# │ REST API
# ┌─────────────▼───────────────────────────┐
# │ Docker Daemon (dockerd) │
# │ จัดการ Containers, Images, Networks │
# └─────────────┬───────────────────────────┘
# │
# ┌─────────────▼───────────────────────────┐
# │ Container Runtime (containerd) │
# │ + runc (OCI Runtime) │
# └─────────────────────────────────────────┘
#
# Components:
# - Docker Client: CLI ที่ใช้สั่งงาน Docker
# - Docker Daemon: Background process ที่จัดการทุกอย่าง
# - Image: Template สำหรับสร้าง Container (read-only)
# - Container: Running instance ของ Image
# - Registry: ที่เก็บ Image (Docker Hub, Private Registry)
ติดตั้ง Docker — Ubuntu, CentOS, Windows, Mac
Ubuntu 22.04/24.04 (แนะนำ)
# ลบ Docker เก่า (ถ้ามี)
sudo apt remove docker docker-engine docker.io containerd runc 2>/dev/null
# ติดตั้ง Prerequisites
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
# เพิ่ม Docker GPG Key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /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
# เพิ่ม User เข้ากลุ่ม docker (ไม่ต้อง sudo ทุกครั้ง)
sudo usermod -aG docker $USER
newgrp docker
# ทดสอบ
docker run hello-world
docker version
docker info
CentOS/RHEL/Rocky Linux
# ลบ Podman (ถ้ามี — CentOS 8+ มาพร้อม Podman)
sudo yum remove podman buildah 2>/dev/null
# เพิ่ม Docker Repo
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# ติดตั้ง
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# เริ่ม Docker
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
# ทดสอบ
docker run hello-world
Windows / macOS
# Windows:
# 1. ดาวน์โหลด Docker Desktop จาก https://www.docker.com/products/docker-desktop
# 2. ติดตั้ง → Enable WSL 2 Backend
# 3. Restart → Docker Desktop จะรันอัตโนมัติ
#
# macOS:
# 1. ดาวน์โหลด Docker Desktop for Mac (Apple Silicon / Intel)
# 2. ลาก Docker.app ไป Applications
# 3. เปิด Docker Desktop → รอ Engine เริ่ม
#
# ทั้งสองระบบ: เปิด Terminal แล้วทดสอบ
docker version
docker run hello-world
Docker CLI พื้นฐาน — คำสั่งที่ต้องรู้
docker pull — ดึง Image จาก Registry
# ดึง Image จาก Docker Hub
docker pull nginx # Latest version
docker pull nginx:1.25-alpine # Specific version (แนะนำ!)
docker pull mysql:8.0
docker pull python:3.12-slim
docker pull ubuntu:22.04
# ดู Image ที่มีในเครื่อง
docker images
# REPOSITORY TAG IMAGE ID SIZE
# nginx 1.25-alpine abcd1234 40MB
# mysql 8.0 efgh5678 580MB
# python 3.12-slim ijkl9012 130MB
# ลบ Image
docker rmi nginx:1.25-alpine
docker image prune # ลบ Image ที่ไม่ใช้
docker run — สร้างและรัน Container
# Basic: รัน Nginx web server
docker run -d -p 8080:80 --name my-nginx nginx:1.25-alpine
# -d = Detached mode (รัน Background)
# -p 8080:80 = Map port 8080 (Host) → port 80 (Container)
# --name my-nginx = ตั้งชื่อ Container
# เปิด Browser → http://localhost:8080 → เห็นหน้า Nginx!
# รัน Ubuntu แบบ Interactive
docker run -it ubuntu:22.04 /bin/bash
# -it = Interactive + Terminal
# จะได้ Shell ภายใน Container
# พิมพ์ exit เพื่อออก
# รัน MySQL Database
docker run -d --name my-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=MyStr0ngPass! -e MYSQL_DATABASE=myapp -v mysql-data:/var/lib/mysql mysql:8.0
# -e = Environment variable
# -v = Volume mount (เก็บ Data ถาวร)
# รัน Python script
docker run --rm -v $(pwd):/app -w /app python:3.12-slim python my_script.py
# --rm = ลบ Container อัตโนมัติหลังจบ
# -v $(pwd):/app = Mount directory ปัจจุบันเข้า Container
# -w /app = ตั้ง Working directory
docker ps, stop, start, rm — จัดการ Container
# ดู Container ที่รันอยู่
docker ps
# CONTAINER ID IMAGE STATUS PORTS NAMES
# a1b2c3d4e5f6 nginx:1.25-alpine Up 5min 0.0.0.0:8080->80/tcp my-nginx
# f6e5d4c3b2a1 mysql:8.0 Up 3min 0.0.0.0:3306->3306/tcp my-mysql
# ดู Container ทั้งหมด (รวมที่หยุดแล้ว)
docker ps -a
# หยุด Container
docker stop my-nginx
# เริ่ม Container ที่หยุดแล้ว
docker start my-nginx
# Restart Container
docker restart my-nginx
# ลบ Container (ต้อง stop ก่อน)
docker stop my-nginx && docker rm my-nginx
# ลบ Container แบบ Force (ไม่ต้อง stop)
docker rm -f my-nginx
# ลบ Container ที่หยุดแล้วทั้งหมด
docker container prune
docker exec — เข้าไปใน Container ที่รันอยู่
# เข้า Shell ของ Container
docker exec -it my-nginx /bin/sh
# (Alpine ใช้ /bin/sh ไม่ใช่ /bin/bash)
docker exec -it my-mysql bash
# ใช้ mysql client ภายใน Container
mysql -u root -p
# รันคำสั่งเดี่ยว (ไม่ต้องเข้า Shell)
docker exec my-nginx nginx -t # ทดสอบ Nginx config
docker exec my-mysql mysqldump myapp # Dump database
# ดู Environment Variables
docker exec my-nginx env
# Copy ไฟล์ระหว่าง Host กับ Container
docker cp my-nginx:/etc/nginx/nginx.conf ./nginx.conf # Container → Host
docker cp ./custom.conf my-nginx:/etc/nginx/conf.d/ # Host → Container
docker logs — ดู Log ของ Container
# ดู Log ทั้งหมด
docker logs my-nginx
# ดู Log แบบ Real-time (Follow)
docker logs -f my-nginx
# ดู Log 50 บรรทัดล่าสุด
docker logs --tail 50 my-nginx
# ดู Log ตั้งแต่เวลาที่กำหนด
docker logs --since "2026-04-01T00:00:00" my-nginx
# ดู Log พร้อม Timestamp
docker logs -t my-nginx
Dockerfile — สร้าง Custom Image
Dockerfile พื้นฐาน — Node.js Application
# Dockerfile
FROM node:20-alpine
# ตั้ง Working Directory
WORKDIR /app
# Copy package.json ก่อน (ใช้ Docker Layer Cache)
COPY package.json package-lock.json ./
# ติดตั้ง Dependencies
RUN npm ci --production
# Copy Source Code
COPY . .
# Expose Port
EXPOSE 3000
# Health Check
HEALTHCHECK --interval=30s --timeout=3s CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
# Command ที่รันเมื่อ Container Start
CMD ["node", "server.js"]
Dockerfile — Python Flask Application
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
# ติดตั้ง Dependencies ก่อน (Layer Cache)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
# ใช้ Gunicorn สำหรับ Production
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "4", "app:app"]
docker build — สร้าง Image จาก Dockerfile
# Build Image
docker build -t my-app:1.0 .
# -t = Tag ชื่อ Image
# . = ใช้ Dockerfile ใน Directory ปัจจุบัน
# Build พร้อม Build Arguments
docker build --build-arg NODE_ENV=production -t my-app:1.0 .
# ดูขั้นตอนการ Build
docker build --progress=plain -t my-app:1.0 .
# Multi-stage Build (ลดขนาด Image)
# Dockerfile.multi
FROM node:20-alpine AS builder
WORKDIR /build
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /build/dist ./dist
COPY --from=builder /build/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]
# Build Multi-stage
docker build -f Dockerfile.multi -t my-app:1.0 .
# Image ขนาดเล็กกว่ามาก! (ไม่มี devDependencies, source code)
Docker Compose — รัน Multi-Container Application
docker-compose.yml — WordPress + MySQL
# docker-compose.yml
# ตัวอย่าง: รัน WordPress + MySQL ด้วยคำสั่งเดียว!
services:
db:
image: mysql:8.0
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: rootpass123
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass456
volumes:
- db-data:/var/lib/mysql
networks:
- wp-network
wordpress:
image: wordpress:6.5-apache
restart: unless-stopped
depends_on:
- db
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wppass456
volumes:
- wp-data:/var/www/html
networks:
- wp-network
volumes:
db-data:
wp-data:
networks:
wp-network:
driver: bridge
Docker Compose Commands
# เริ่ม Services ทั้งหมด (Background)
docker compose up -d
# ดู Status
docker compose ps
# ดู Logs
docker compose logs -f
# หยุด Services
docker compose stop
# หยุดและลบ Containers
docker compose down
# หยุดและลบ Containers + Volumes (ระวัง! ลบ Data ด้วย)
docker compose down -v
# Build ใหม่แล้ว Start
docker compose up -d --build
# Scale Service (รันหลาย Instance)
docker compose up -d --scale wordpress=3
docker-compose.yml — Full Stack (Node.js + Redis + Nginx)
# docker-compose.yml
services:
app:
build: .
restart: unless-stopped
environment:
NODE_ENV: production
REDIS_URL: redis://redis:6379
depends_on:
- redis
networks:
- app-network
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis-data:/data
networks:
- app-network
nginx:
image: nginx:1.25-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- app
networks:
- app-network
volumes:
redis-data:
networks:
app-network:
driver: bridge
Docker Networking — เชื่อมต่อ Container
Network Types
# Docker Network Types:
#
# 1. bridge (Default) — Container คนละ Network, ต้อง -p map port
# 2. host — Container ใช้ Network ของ Host ตรง ๆ (Linux only)
# 3. none — ไม่มี Network
# 4. overlay — ข้าม Host (Docker Swarm)
# 5. macvlan — Container ได้ MAC Address ของตัวเอง
# สร้าง Custom Bridge Network (แนะนำ!)
docker network create my-network
# รัน Container ใน Network เดียวกัน
docker run -d --name app --network my-network my-app:1.0
docker run -d --name redis --network my-network redis:7-alpine
# Container ในเครือข่ายเดียวกัน สามารถใช้ชื่อ Container เป็น Hostname ได้!
# app สามารถเชื่อมต่อ redis ด้วย redis:6379
# ดู Networks
docker network ls
docker network inspect my-network
# ลบ Network
docker network rm my-network
Docker Volumes — เก็บ Data ถาวร
3 วิธีจัดการ Data
# 1. Named Volume (แนะนำ!)
# Docker จัดการให้ เก็บใน /var/lib/docker/volumes/
docker run -d -v my-data:/var/lib/mysql --name db mysql:8.0
# 2. Bind Mount
# Mount Directory จาก Host เข้า Container
docker run -d -v /home/user/data:/var/lib/mysql --name db mysql:8.0
docker run -d -v $(pwd)/html:/usr/share/nginx/html --name web nginx
# 3. tmpfs Mount (เก็บใน RAM เท่านั้น ไม่ถาวร)
docker run -d --tmpfs /tmp --name app my-app:1.0
# จัดการ Volumes
docker volume ls # ดู Volumes ทั้งหมด
docker volume inspect my-data # ดูรายละเอียด
docker volume rm my-data # ลบ Volume
docker volume prune # ลบ Volume ที่ไม่ใช้
ตัวอย่างจริง — รัน Nginx Web Server
# สร้างไฟล์ HTML
mkdir -p ~/docker-test/html
cat > ~/docker-test/html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head><title>Docker Test</title></head>
<body>
<h1>Hello from Docker Container!</h1>
<p>ถ้าเห็นหน้านี้ แสดงว่า Docker ทำงานถูกต้อง</p>
</body>
</html>
EOF
# รัน Nginx พร้อม Custom HTML
docker run -d --name web-test -p 8080:80 -v ~/docker-test/html:/usr/share/nginx/html:ro nginx:1.25-alpine
# ทดสอบ
curl http://localhost:8080
# → Hello from Docker Container!
ตัวอย่างจริง — รัน MySQL + phpMyAdmin
# docker-compose.yml
services:
mysql:
image: mysql:8.0
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: RootP@ss2026
MYSQL_DATABASE: myapp
volumes:
- mysql-data:/var/lib/mysql
ports:
- "3306:3306"
phpmyadmin:
image: phpmyadmin:latest
restart: unless-stopped
depends_on:
- mysql
ports:
- "8081:80"
environment:
PMA_HOST: mysql
PMA_PORT: 3306
volumes:
mysql-data:
# เริ่ม
# docker compose up -d
# เปิด Browser → http://localhost:8081
# Login: root / RootP@ss2026
Docker Hub และ Image Management
Push Image ไป Docker Hub
# Login Docker Hub
docker login
# ใส่ Username + Password
# Tag Image ตามรูปแบบ Docker Hub
docker tag my-app:1.0 username/my-app:1.0
docker tag my-app:1.0 username/my-app:latest
# Push ไป Docker Hub
docker push username/my-app:1.0
docker push username/my-app:latest
# ใครก็ดึงไปใช้ได้
docker pull username/my-app:1.0
Private Registry
# รัน Private Registry บน Server ของเราเอง
docker run -d -p 5000:5000 --name registry -v registry-data:/var/lib/registry registry:2
# Push Image ไป Private Registry
docker tag my-app:1.0 localhost:5000/my-app:1.0
docker push localhost:5000/my-app:1.0
# Pull จาก Private Registry
docker pull localhost:5000/my-app:1.0
Docker Security พื้นฐาน
Best Practices สำหรับ Security
# 1. ใช้ Official Images + Specific Version (ไม่ใช้ :latest ใน Production)
FROM nginx:1.25-alpine # ดี
FROM nginx:latest # ไม่ดี (เปลี่ยนได้ตลอด)
# 2. ไม่รัน Container ด้วย root
FROM node:20-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
COPY --chown=appuser:appgroup . .
# 3. Scan Image หา Vulnerability
docker scout cves my-app:1.0 # Docker Scout (Built-in)
docker run --rm aquasec/trivy image my-app:1.0 # Trivy
# 4. ใช้ .dockerignore
# .dockerignore
node_modules
.git
.env
*.log
Dockerfile
docker-compose.yml
# 5. ไม่ Hardcode Secrets ใน Dockerfile
# แย่:
ENV DB_PASSWORD=secret123
# ดี: ใช้ Docker Secrets หรือ Environment variable ตอน run
docker run -e DB_PASSWORD=secret123 my-app:1.0
# 6. Resource Limits
docker run -d --memory=512m --cpus=1.0 my-app:1.0
# 7. Read-only Filesystem (ถ้าทำได้)
docker run -d --read-only --tmpfs /tmp my-app:1.0
Docker สำหรับ Testing/Development
# รัน Test Environment ชั่วคราว
docker run --rm -it python:3.12-slim bash
# ทดสอบ Python library ได้เลย ไม่กระทบเครื่อง
# รัน Database สำหรับ Test
docker run --rm -d -p 5432:5432 -e POSTGRES_PASSWORD=testpass --name test-db postgres:16-alpine
# รัน Test → docker stop test-db → ลบอัตโนมัติ
# Test Application ใน Environment ต่าง ๆ
docker run --rm -v $(pwd):/app -w /app node:18 npm test
docker run --rm -v $(pwd):/app -w /app node:20 npm test
docker run --rm -v $(pwd):/app -w /app node:22 npm test
# → ทดสอบกับ Node 18, 20, 22 ได้โดยไม่ต้องติดตั้ง!
Useful Docker Commands — รวมคำสั่งที่ใช้บ่อย
| คำสั่ง | อธิบาย |
|---|---|
docker ps |
ดู Container ที่รันอยู่ |
docker ps -a |
ดู Container ทั้งหมด |
docker images |
ดู Images ทั้งหมด |
docker pull IMAGE |
ดึง Image |
docker run -d -p H:C IMAGE |
รัน Container (Background) |
docker exec -it NAME bash |
เข้า Shell ของ Container |
docker logs -f NAME |
ดู Log แบบ Real-time |
docker stop NAME |
หยุด Container |
docker rm NAME |
ลบ Container |
docker rmi IMAGE |
ลบ Image |
docker build -t NAME . |
สร้าง Image จาก Dockerfile |
docker compose up -d |
เริ่ม Docker Compose Services |
docker compose down |
หยุด Docker Compose Services |
docker system prune -a |
ลบทุกอย่างที่ไม่ใช้ (ระวัง!) |
docker inspect NAME |
ดูรายละเอียด Container/Image |
docker stats |
ดู Resource Usage แบบ Real-time |
docker network ls |
ดู Networks |
docker volume ls |
ดู Volumes |
Troubleshooting Docker ที่พบบ่อย
| ปัญหา | สาเหตุ | วิธีแก้ |
|---|---|---|
| Port already in use | Port ถูกใช้แล้ว | เปลี่ยน Port หรือ docker stop Container เดิม |
| Permission denied | User ไม่อยู่ใน docker group | sudo usermod -aG docker $USER |
| No space left on device | Disk เต็มจาก Images/Containers | docker system prune -a |
| Container exits immediately | Command จบทันที | ใช้ -it หรือตรวจ CMD ใน Dockerfile |
| Cannot connect between containers | อยู่คนละ Network | ใช้ Custom Network หรือ Docker Compose |
| Build ช้ามาก | ไม่ใช้ Layer Cache | COPY dependency files ก่อน source code |
| Image ใหญ่มาก | ใช้ Full OS Image | ใช้ Alpine + Multi-stage build |
ก้าวต่อไป — จาก Docker สู่ Kubernetes
เมื่อ Docker เริ่มคล่อง สิ่งที่ควรเรียนรู้ต่อ:
| หัวข้อ | อธิบาย | เมื่อไรควรเรียน |
|---|---|---|
| Docker Swarm | Orchestration เบื้องต้น (Built-in Docker) | ต้องการรันหลาย Node แบบง่าย |
| Kubernetes (K8s) | Container Orchestration มาตรฐานอุตสาหกรรม | Enterprise, Microservices, Auto-scaling |
| CI/CD Pipeline | Build + Test + Deploy อัตโนมัติ | ทุกโปรเจค Production |
| Helm Charts | Package Manager สำหรับ Kubernetes | หลังจากเรียน K8s พื้นฐาน |
| Monitoring | Prometheus + Grafana สำหรับ Container | เมื่อมี Container หลายตัว |
สรุป — Docker สำหรับ IT มือใหม่
Docker ทำให้การ Deploy Application ง่ายขึ้นมาก จาก "ทำงานบนเครื่องฉัน" เป็น "ทำงานได้ทุกที่" ด้วยการ Package App + Dependencies ไว้ใน Container เดียว
สิ่งที่ต้องจำ: ใช้ Specific Image Tag (ไม่ใช้ :latest), เก็บ Data ด้วย Volume (ไม่เก็บใน Container), ใช้ Docker Compose สำหรับ Multi-Container, ไม่รัน root ใน Container, Scan Image หา Vulnerability เสมอ และ ใช้ .dockerignore ลดขนาด Image
เริ่มจาก docker run hello-world แล้วค่อย ๆ สร้าง Dockerfile, Docker Compose จนเชี่ยวชาญ แล้วก้าวไปสู่ Kubernetes เมื่อพร้อม!