ในยุคที่เทคโนโลยีพัฒนาอย่างรวดเร็ว การพัฒนาและ deploy แอปพลิเคชันต้องการความยืดหยุ่นและประสิทธิภาพสูง Docker เป็นเทคโนโลยีที่ปฏิวัติวงการ DevOps และ Software Development ด้วยการนำเสนอแนวคิดของ Containerization ที่ทำให้การพัฒนา testing และ deployment แอปพลิเคชันง่ายและรวดเร็วขึ้นอย่างมาก
ก่อนที่จะมี Docker นักพัฒนาต้องเจอปัญหาเหล่านี้บ่อยครั้ง:
Docker เป็น open-source platform ที่ใช้สำหรับพัฒนา shipping และรันแอปพลิเคชันภายใน containers ซึ่ง containers เป็นหน่วยมาตรฐานของซอฟต์แวร์ที่รวม code และ dependencies ทั้งหมดไว้ด้วยกัน ทำให้แอปพลิเคชันสามารถทำงานได้อย่างรวดเร็วและเชื่อถือได้ในสภาพแวดล้อมที่แตกต่างกัน
เพื่อเข้าใจ Docker ให้ดีขึ้น เราต้องเข้าใจความแตกต่างระหว่าง Containerization กับ Virtualization
graph TB
subgraph "Physical Server"
Hardware[Hardware/Infrastructure]
HostOS[Host Operating System]
Hypervisor[Hypervisor]
subgraph VM1["Virtual Machine 1"]
GuestOS1[Guest OS]
Bins1[Binaries/Libraries]
App1[Application 1]
end
subgraph VM2["Virtual Machine 2"]
GuestOS2[Guest OS]
Bins2[Binaries/Libraries]
App2[Application 2]
end
subgraph VM3["Virtual Machine 3"]
GuestOS3[Guest OS]
Bins3[Binaries/Libraries]
App3[Application 3]
end
end
Hardware --> HostOS
HostOS --> Hypervisor
Hypervisor --> VM1
Hypervisor --> VM2
Hypervisor --> VM3
Virtual Machines ทำงานโดย:
graph TB
subgraph "Physical Server"
Hardware2[Hardware/Infrastructure]
HostOS2[Host Operating System]
DockerEngine[Docker Engine]
subgraph Container1["Container 1"]
Bins4[Binaries/Libraries]
App4[Application 1]
end
subgraph Container2["Container 2"]
Bins5[Binaries/Libraries]
App5[Application 2]
end
subgraph Container3["Container 3"]
Bins6[Binaries/Libraries]
App6[Application 3]
end
end
Hardware2 --> HostOS2
HostOS2 --> DockerEngine
DockerEngine --> Container1
DockerEngine --> Container2
DockerEngine --> Container3
Containers ทำงานโดย:
| คุณสมบัติ | Virtual Machines | Containers |
|---|---|---|
| ขนาด | GBs (รวม OS เต็มระบบ) | MBs (เฉพาะ app และ dependencies) |
| Startup Time | นาที | วินาที |
| ประสิทธิภาพ | น้อยกว่า (overhead จาก virtualization) | ใกล้เคียง native |
| Isolation | สมบูรณ์แบบ (Hardware-level) | Process-level |
| Resource Usage | สูง | ต่ำ |
| Portability | ต่ำ (ขึ้นกับ hypervisor) | สูง (รันได้ทุกที่ที่มี Docker) |
Docker ใช้สถาปัตยกรรมแบบ client-server มาทำงาน
graph LR
Client[Docker Client
docker CLI]
Daemon[Docker Daemon
dockerd]
Registry[Docker Registry
Docker Hub]
Client -->|REST API| Daemon
Daemon -->|Pull/Push| Registry
subgraph "Docker Host"
Daemon
Images[(Images)]
Containers[Containers]
Volumes[(Volumes)]
Networks[Networks]
end
Daemon --> Images
Daemon --> Containers
Daemon --> Volumes
Daemon --> Networks
docker ที่เราพิมพ์บน terminalหลังจากติดตั้งแล้ว ให้ตรวจสอบว่า Docker ทำงานได้:
# ตรวจสอบ version
docker --version
# ตรวจสอบข้อมูลระบบ
docker info
# ทดสอบรัน container แรก
docker run hello-world
ผลลัพธ์ที่ควรได้:
Hello from Docker!
This message shows that your installation appears to be working correctly.
Image คือ template สำหรับสร้าง containers ประกอบด้วย layers ของ filesystem และ metadata
graph TD
A[Base Image
Ubuntu 20.04] --> B[Layer 2
Install Python]
B --> C[Layer 3
Copy App Code]
C --> D[Layer 4
Install Dependencies]
D --> E[Final Image
My App:v1.0]
style A fill:#e1f5ff
style B fill:#b3e5fc
style C fill:#81d4fa
style D fill:#4fc3f7
style E fill:#29b6f6
# ค้นหา image ของ nginx
docker search nginx
# ค้นหาแบบจำกัดผลลัพธ์
docker search --limit 5 nginx
# Pull image เวอร์ชันล่าสุด
docker pull nginx
# Pull image เวอร์ชันเฉพาะ (แนะนำ)
docker pull nginx:1.25.3
# Pull image จาก official repository
docker pull ubuntu:22.04
# Pull image จาก user/organization
docker pull mysql:8.0
# แสดง images ทั้งหมด
docker images
# แสดงแบบละเอียด
docker images --all
# แสดงเฉพาะ Image IDs
docker images -q
# กรองตาม repository name
docker images nginx
ตัวอย่างผลลัพธ์:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 141MB
nginx 1.25.3 605c77e624dd 2 weeks ago 141MB
ubuntu 22.04 174c8c134b2a 3 weeks ago 77.8MB
mysql 8.0 3218b38490ce 4 weeks ago 517MB
# ดูข้อมูลเต็มของ image
docker inspect nginx:latest
# ดูประวัติการสร้าง layers
docker history nginx:latest
# ดู metadata เฉพาะส่วน
docker inspect --format='{{.Architecture}}' nginx:latest
# ลบ image ตาม name:tag
docker rmi nginx:1.25.3
# ลบ image ตาม Image ID
docker rmi 605c77e624dd
# บังคับลบ (ถึงแม้มี container ใช้งานอยู่)
docker rmi -f nginx:latest
# ลบ images ที่ไม่มี tag (dangling images)
docker image prune
# ลบ images ทั้งหมดที่ไม่ได้ใช้งาน
docker image prune -a
Dockerfile เป็นไฟล์ text ที่มีคำสั่งสำหรับสร้าง image
สร้างไฟล์โครงสร้างดังนี้:
my-python-app/
├── Dockerfile
├── app.py
└── requirements.txt
app.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello from Docker Container!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
requirements.txt:
flask==3.0.0
Dockerfile:
# เริ่มจาก base image
FROM python:3.11-slim
# ตั้ง working directory
WORKDIR /app
# Copy requirements file
COPY requirements.txt .
# ติดตั้ง dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY app.py .
# เปิด port
EXPOSE 5000
# คำสั่งรัน application
CMD ["python", "app.py"]
สร้าง Image:
# Build image พร้อมตั้งชื่อและ tag
docker build -t my-python-app:1.0 .
# Build แบบไม่ใช้ cache
docker build --no-cache -t my-python-app:1.0 .
# ดู build process แบบละเอียด
docker build -t my-python-app:1.0 . --progress=plain
Dockerfile:
FROM node:18-alpine
WORKDIR /usr/src/app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy app source
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Build Command:
docker build -t my-node-app:latest .
# สร้าง tag ใหม่สำหรับ image ที่มีอยู่
docker tag my-python-app:1.0 my-python-app:latest
# สร้าง tag สำหรับ push ไปยัง registry
docker tag my-python-app:1.0 username/my-python-app:1.0
# Tag พร้อมชื่อ registry
docker tag my-python-app:1.0 myregistry.com:5000/my-python-app:1.0
# Login เข้า Docker Hub
docker login
# Push image
docker push username/my-python-app:1.0
# Push ทุก tags
docker push --all-tags username/my-python-app
# Save image เป็นไฟล์ tar
docker save -o my-python-app.tar my-python-app:1.0
# Save หลาย images
docker save -o my-images.tar nginx:latest ubuntu:22.04
# Load image จากไฟล์
docker load -i my-python-app.tar
# Load และแสดง output
docker load < my-python-app.tar
Container คือ runnable instance ของ image ที่สามารถ start, stop, move และ delete ได้
stateDiagram-v2
[*] --> Created: docker create
Created --> Running: docker start
Running --> Paused: docker pause
Paused --> Running: docker unpause
Running --> Stopped: docker stop
Stopped --> Running: docker start
Running --> Killed: docker kill
Killed --> [*]
Stopped --> [*]: docker rm
Created --> [*]: docker rm
docker run เป็นคำสั่งที่รวม create และ start เข้าด้วยกัน
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# รัน nginx container
docker run nginx
# รัน container แบบ detached (background)
docker run -d nginx
# รัน container พร้อมตั้งชื่อ
docker run -d --name my-nginx nginx
# รัน container พร้อม publish port
docker run -d -p 8080:80 --name web-server nginx
อธิบาย options:
-d หรือ --detach: รัน container ใน background--name: ตั้งชื่อให้ container-p หรือ --publish: map port จาก host ไปยัง container (HOST_PORT:CONTAINER_PORT)# รัน Ubuntu container แบบ interactive
docker run -it ubuntu bash
# รันคำสั่งใน container แล้วออก
docker run ubuntu echo "Hello Docker"
# รัน container พร้อม environment variables
docker run -it -e "MY_VAR=Hello" ubuntu bash
# ใน container: echo $MY_VAR
# รัน Alpine Linux (lightweight)
docker run -it alpine sh
อธิบาย options:
-i หรือ --interactive: เปิด STDIN-t หรือ --tty: จัดสรร pseudo-TTY-e หรือ --env: ตั้งค่า environment variable# Map single port
docker run -d -p 8080:80 nginx
# Map multiple ports
docker run -d -p 8080:80 -p 8443:443 nginx
# Map ทุก ports ที่ expose (แบบสุ่ม)
docker run -d -P nginx
# Map specific IP address
docker run -d -p 127.0.0.1:8080:80 nginx
# ตรวจสอบ port mapping
docker port my-nginx
# จำกัด memory
docker run -d --memory="512m" nginx
# จำกัด CPU
docker run -d --cpus="1.5" nginx
# จำกัดทั้ง memory และ CPU
docker run -d \
--memory="1g" \
--memory-swap="2g" \
--cpus="2" \
--name limited-nginx \
nginx
# ดูการใช้ทรัพยากร real-time
docker stats limited-nginx
# ตั้งค่า environment variable เดียว
docker run -d -e MYSQL_ROOT_PASSWORD=secret mysql:8.0
# ตั้งค่าหลาย environment variables
docker run -d \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=myapp \
-e MYSQL_USER=appuser \
-e MYSQL_PASSWORD=apppass \
--name mysql-server \
mysql:8.0
# ใช้ env file
# สร้างไฟล์ db.env
# MYSQL_ROOT_PASSWORD=secret
# MYSQL_DATABASE=myapp
docker run -d --env-file db.env mysql:8.0
# ไม่ restart อัตโนมัติ (default)
docker run -d --restart=no nginx
# Restart เสมอ
docker run -d --restart=always --name always-nginx nginx
# Restart เมื่อ fail เท่านั้น
docker run -d --restart=on-failure --name onfail-nginx nginx
# Restart เมื่อ fail พร้อมจำกัดจำนวนครั้ง
docker run -d --restart=on-failure:5 nginx
# Restart เว้นแต่จะ stop ด้วยตัวเอง
docker run -d --restart=unless-stopped nginx
# แสดง containers ที่กำลังรันอยู่
docker ps
# แสดง containers ทั้งหมด (รวมที่หยุดแล้ว)
docker ps -a
# แสดงเฉพาะ Container IDs
docker ps -q
# แสดงแบบ custom format
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
# แสดง containers ล่าสุด (5 ตัว)
docker ps -n 5
# ดูข้อมูลทั้งหมดของ container
docker inspect my-nginx
# ดูข้อมูลเฉพาะส่วน
docker inspect --format='{{.NetworkSettings.IPAddress}}' my-nginx
# ดู logs
docker logs my-nginx
# ดู logs แบบ follow (real-time)
docker logs -f my-nginx
# ดู logs พร้อม timestamp
docker logs -t my-nginx
# ดู logs จำนวนจำกัด
docker logs --tail 50 my-nginx
# Start container ที่หยุดอยู่
docker start my-nginx
# Stop container (graceful shutdown)
docker stop my-nginx
# Stop พร้อมกำหนด timeout
docker stop -t 30 my-nginx
# Restart container
docker restart my-nginx
# Pause container (หยุดชั่วคราว)
docker pause my-nginx
# Unpause container
docker unpause my-nginx
# Kill container (force stop)
docker kill my-nginx
# Kill ด้วย specific signal
docker kill -s SIGTERM my-nginx
# รันคำสั่งใน container
docker exec my-nginx ls -la
# เข้าไปใช้ bash ใน container
docker exec -it my-nginx bash
# รันคำสั่งในฐานะ specific user
docker exec -u root -it my-nginx bash
# รันคำสั่งใน working directory เฉพาะ
docker exec -w /var/log -it my-nginx bash
# รันคำสั่งพร้อม environment variable
docker exec -e MY_VAR=test my-nginx env
# Copy จาก host ไป container
docker cp myfile.txt my-nginx:/usr/share/nginx/html/
# Copy จาก container มา host
docker cp my-nginx:/var/log/nginx/access.log ./
# Copy ทั้ง directory
docker cp ./my-website/. my-nginx:/usr/share/nginx/html/
# Copy พร้อม preserve ownership
docker cp --archive my-nginx:/app/data ./backup
# ลบ container ที่หยุดแล้ว
docker rm my-nginx
# บังคับลบ container ที่กำลังรัน
docker rm -f my-nginx
# ลบหลาย containers
docker rm container1 container2 container3
# ลบ containers ทั้งหมดที่หยุดแล้ว
docker container prune
# ลบ containers ทั้งหมด (รวมที่กำลังรัน)
docker rm -f $(docker ps -aq)
# รัน Nginx web server
docker run -d \
--name my-website \
-p 8080:80 \
-v $(pwd)/html:/usr/share/nginx/html:ro \
--restart=unless-stopped \
nginx:latest
# ทดสอบ
curl http://localhost:8080
# รัน MySQL container
docker run -d \
--name mysql-db \
-e MYSQL_ROOT_PASSWORD=rootpass123 \
-e MYSQL_DATABASE=myapp \
-e MYSQL_USER=appuser \
-e MYSQL_PASSWORD=apppass123 \
-p 3306:3306 \
-v mysql-data:/var/lib/mysql \
--restart=always \
mysql:8.0
# เชื่อมต่อเข้า MySQL
docker exec -it mysql-db mysql -u root -p
# Backup database
docker exec mysql-db mysqldump -u root -prootpass123 myapp > backup.sql
# Restore database
docker exec -i mysql-db mysql -u root -prootpass123 myapp < backup.sql
# รัน Redis
docker run -d \
--name redis-cache \
-p 6379:6379 \
-v redis-data:/data \
--restart=always \
redis:alpine redis-server --appendonly yes
# ทดสอบ Redis
docker exec -it redis-cache redis-cli
# ใน redis-cli: SET mykey "Hello Docker"
# ใน redis-cli: GET mykey
# รัน MongoDB
docker run -d \
--name mongodb \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=adminpass \
-p 27017:27017 \
-v mongo-data:/data/db \
--restart=always \
mongo:7.0
# เชื่อมต่อเข้า MongoDB
docker exec -it mongodb mongosh -u admin -p adminpass
Docker Networks ช่วยให้ containers สามารถสื่อสารกันได้ และควบคุมการเข้าถึงจากภายนอก
graph TB
subgraph "Docker Host"
subgraph "Bridge Network (default)"
C1[Container 1
172.17.0.2]
C2[Container 2
172.17.0.3]
end
subgraph "Custom Bridge Network"
C3[Container 3
my-app]
C4[Container 4
my-db]
end
subgraph "Host Network"
C5[Container 5
uses host network]
end
C1 <--> C2
C3 <--> C4
end
Host[Host Machine] <--> C1
Host <--> C2
Host <--> C3
Host <--> C4
Host <--> C5
Internet[Internet] <--> Host
# แสดง networks ทั้งหมด
docker network ls
# แสดงแบบ custom format
docker network ls --format "table {{.Name}}\t{{.Driver}}\t{{.Scope}}"
# กรองตาม driver
docker network ls --filter driver=bridge
# ดูข้อมูล network
docker network inspect bridge
# ดูเฉพาะ containers ใน network
docker network inspect --format='{{json .Containers}}' bridge | jq
# สร้าง bridge network
docker network create my-network
# สร้าง network พร้อมกำหนด subnet
docker network create \
--driver bridge \
--subnet=172.20.0.0/16 \
--gateway=172.20.0.1 \
my-custom-network
# สร้าง network พร้อม options เพิ่มเติม
docker network create \
--driver bridge \
--subnet=172.25.0.0/16 \
--ip-range=172.25.5.0/24 \
--gateway=172.25.0.1 \
--label env=production \
prod-network
# เชื่อมต่อ container เข้า network
docker network connect my-network my-container
# เชื่อมต่อพร้อมกำหนด IP
docker network connect --ip 172.20.0.10 my-network my-container
# เชื่อมต่อพร้อมกำหนด alias
docker network connect --alias db my-network mysql-container
# ตัดการเชื่อมต่อ
docker network disconnect my-network my-container
# บังคับตัดการเชื่อมต่อ
docker network disconnect -f my-network my-container
# ลบ network
docker network rm my-network
# ลบหลาย networks
docker network rm network1 network2
# ลบ networks ที่ไม่ได้ใช้งาน
docker network prune
# บังคับลบทั้งหมด
docker network prune -f
# รัน containers บน default bridge
docker run -d --name web1 nginx
docker run -d --name web2 nginx
# ตรวจสอบ IP ของ containers
docker inspect web1 | grep IPAddress
docker inspect web2 | grep IPAddress
# ทดสอบการเชื่อมต่อระหว่าง containers (ต้องใช้ IP)
docker exec web1 ping -c 3 <IP-ของ-web2>
# ⚠️ ไม่สามารถใช้ชื่อ container ได้
docker exec web1 ping web2 # จะไม่สำเร็จ
# สร้าง custom network
docker network create my-app-network
# รัน containers บน custom network
docker run -d --name web --network my-app-network nginx
docker run -d --name db --network my-app-network mysql:8.0
# ทดสอบการเชื่อมต่อ (ใช้ชื่อได้)
docker exec web ping -c 3 db
# ใช้ DNS resolution
docker exec web nslookup db
# รัน container ใหม่บน network เดียวกัน
docker run -d \
--name api \
--network my-app-network \
-e DB_HOST=db \
my-api-image
# รัน container บน host network
docker run -d --network host nginx
# Container จะใช้ ports ของ host โดยตรง
# ไม่ต้อง publish ports (-p)
# ดู network interfaces
docker run --network host alpine ip addr show
# รัน container โดยไม่มี network
docker run -d --network none alpine sleep 3600
# ทดสอบว่าไม่มี network
docker exec <container-id> ip addr show
# จะเห็นแค่ loopback interface
# สร้าง 2 networks
docker network create frontend-network
docker network create backend-network
# รัน database บน backend network
docker run -d \
--name postgres-db \
--network backend-network \
-e POSTGRES_PASSWORD=secret \
postgres:15
# รัน API server เชื่อมต่อทั้ง 2 networks
docker run -d \
--name api-server \
--network frontend-network \
my-api:latest
# เชื่อมต่อ API เข้า backend network
docker network connect backend-network api-server
# ตอนนี้ api-server สามารถเข้าถึง postgres-db ได้
# และรับ requests จาก frontend-network ได้
ตัวอย่างการสร้าง web application stack ที่สมบูรณ์:
# 1. สร้าง networks
docker network create frontend-net
docker network create backend-net
# 2. รัน database (backend เท่านั้น)
docker run -d \
--name postgres \
--network backend-net \
-e POSTGRES_DB=myapp \
-e POSTGRES_USER=appuser \
-e POSTGRES_PASSWORD=apppass \
-v postgres-data:/var/lib/postgresql/data \
postgres:15
# 3. รัน Redis cache (backend เท่านั้น)
docker run -d \
--name redis \
--network backend-net \
-v redis-data:/data \
redis:alpine
# 4. รัน API server (ทั้ง frontend และ backend)
docker run -d \
--name api \
--network backend-net \
-e DATABASE_URL=postgresql://appuser:apppass@postgres:5432/myapp \
-e REDIS_URL=redis://redis:6379 \
my-api:latest
docker network connect frontend-net api
# 5. รัน web frontend (frontend เท่านั้น)
docker run -d \
--name webapp \
--network frontend-net \
-p 80:80 \
-e API_URL=http://api:8000 \
my-webapp:latest
# 6. รัน Nginx reverse proxy
docker run -d \
--name nginx \
--network frontend-net \
-p 443:443 \
-v ./nginx.conf:/etc/nginx/nginx.conf:ro \
nginx:alpine
โครงสร้าง Network:
graph TB
Internet[Internet]
subgraph "Frontend Network"
Nginx[Nginx
Reverse Proxy]
WebApp[Web App
Frontend]
end
subgraph "Backend Network"
API[API Server]
Postgres[PostgreSQL
Database]
Redis[Redis
Cache]
end
Internet --> Nginx
Nginx --> WebApp
WebApp --> API
API --> Postgres
API --> Redis
style Frontend Network fill:#e3f2fd
style Backend Network fill:#fff3e0
# สร้าง network และ containers
docker network create test-net
docker run -d --name server1 --network test-net nginx
docker run -d --name server2 --network test-net nginx
# ทดสอบ DNS resolution
docker exec server1 ping -c 2 server2
docker exec server1 nslookup server2
# ดู DNS entries
docker exec server1 cat /etc/hosts
docker exec server1 cat /etc/resolv.conf
# ใช้ network alias
docker run -d --name db \
--network test-net \
--network-alias database \
--network-alias mysql-server \
mysql:8.0
# ตอนนี้สามารถเข้าถึงได้ทั้ง 3 ชื่อ:
# - db
# - database
# - mysql-server
Volumes เป็นกลไกสำหรับเก็บข้อมูลถาวร (persistent data) และแชร์ข้อมูลระหว่าง containers
graph LR
subgraph "Host Filesystem"
HostDir["/host/data"]
DockerVolumes["/var/lib/docker/volumes/"]
end
subgraph "Container 1"
App1[Application]
Mount1["/app/data"]
end
subgraph "Container 2"
App2[Application]
Mount2["/app/data"]
end
HostDir -.Bind Mount.-> Mount1
DockerVolumes -->|Named Volume| Mount2
style DockerVolumes fill:#bbdefb
style HostDir fill:#c8e6c9
/var/lib/docker/volumes/# แสดง volumes ทั้งหมด
docker volume ls
# กรอง dangling volumes
docker volume ls --filter dangling=true
# แสดงแบบ custom format
docker volume ls --format "table {{.Name}}\t{{.Driver}}\t{{.Mountpoint}}"
# สร้าง named volume
docker volume create my-volume
# สร้าง volume พร้อม label
docker volume create --label env=production prod-data
# สร้าง volume พร้อม driver options
docker volume create \
--driver local \
--opt type=none \
--opt device=/path/on/host \
--opt o=bind \
custom-volume
# ดูข้อมูล volume
docker volume inspect my-volume
# ดูตำแหน่งบน host
docker volume inspect --format='{{.Mountpoint}}' my-volume
# ดูว่า volume ใช้โดย containers ใดบ้าง
docker ps -a --filter volume=my-volume
# ลบ volume
docker volume rm my-volume
# ลบหลาย volumes
docker volume rm vol1 vol2 vol3
# ลบ volumes ที่ไม่ได้ใช้งาน
docker volume prune
# ลบ volumes ทั้งหมดที่ไม่ได้ใช้ (ระวัง!)
docker volume prune -a
# บังคับลบ
docker volume prune -f
# สร้าง volume
docker volume create mysql-data
# รัน MySQL พร้อม named volume
docker run -d \
--name mysql-db \
-e MYSQL_ROOT_PASSWORD=secret \
-v mysql-data:/var/lib/mysql \
mysql:8.0
# ตรวจสอบว่า volume ถูกใช้งาน
docker volume inspect mysql-data
# รัน container ตัวใหม่ใช้ volume เดียวกัน
docker run -d \
--name mysql-backup \
-v mysql-data:/var/lib/mysql:ro \
mysql:8.0
# ข้อมูลจะยังอยู่แม้ลบ container
docker rm -f mysql-db
docker volume ls # mysql-data ยังอยู่
# สร้าง directory บน host
mkdir -p ~/my-website/html
echo "<h1>Hello Docker</h1>" > ~/my-website/html/index.html
# Mount directory จาก host
docker run -d \
--name dev-server \
-p 8080:80 \
-v ~/my-website/html:/usr/share/nginx/html \
nginx
# แก้ไขไฟล์บน host
echo "<h1>Updated Content</h1>" > ~/my-website/html/index.html
# การเปลี่ยนแปลงจะเห็นทันทีที่ http://localhost:8080
# Mount แบบ read-only
docker run -d \
--name prod-server \
-p 8081:80 \
-v ~/my-website/html:/usr/share/nginx/html:ro \
nginx
# สร้าง volume สำหรับ shared data
docker volume create shared-data
# Container 1: เขียนข้อมูล
docker run -d \
--name writer \
-v shared-data:/data \
alpine \
sh -c "while true; do echo $(date) >> /data/log.txt; sleep 5; done"
# Container 2: อ่านข้อมูล
docker run -d \
--name reader \
-v shared-data:/data:ro \
alpine \
sh -c "while true; do tail -f /data/log.txt; sleep 1; done"
# ดู logs ของ reader
docker logs -f reader
# Container 3: Backup data
docker run --rm \
-v shared-data:/source:ro \
-v $(pwd)/backup:/backup \
alpine \
tar czf /backup/shared-data-backup.tar.gz -C /source .
# PostgreSQL
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=myapp \
-v postgres-data:/var/lib/postgresql/data \
-p 5432:5432 \
postgres:15
# MongoDB
docker run -d \
--name mongodb \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=secret \
-v mongo-data:/data/db \
-v mongo-config:/data/configdb \
-p 27017:27017 \
mongo:7.0
# Redis with persistence
docker run -d \
--name redis \
-v redis-data:/data \
-p 6379:6379 \
redis:alpine redis-server --appendonly yes
Backup Volume:
# สร้างและใช้งาน volume
docker volume create app-data
docker run -d --name app -v app-data:/data alpine sleep 3600
# เพิ่มข้อมูลทดสอบ
docker exec app sh -c "echo 'Important data' > /data/file.txt"
# Backup volume เป็น tar file
docker run --rm \
-v app-data:/source:ro \
-v $(pwd):/backup \
alpine \
tar czf /backup/app-data-backup-$(date +%Y%m%d).tar.gz -C /source .
# ตรวจสอบ backup file
ls -lh app-data-backup-*.tar.gz
Restore Volume:
# สร้าง volume ใหม่
docker volume create app-data-restored
# Restore จาก backup file
docker run --rm \
-v app-data-restored:/target \
-v $(pwd):/backup \
alpine \
sh -c "cd /target && tar xzf /backup/app-data-backup-20241104.tar.gz"
# ตรวจสอบข้อมูล
docker run --rm -v app-data-restored:/data alpine cat /data/file.txt
# Mount tmpfs สำหรับข้อมูลชั่วคราว
docker run -d \
--name app-with-tmpfs \
--tmpfs /tmp:rw,size=100m,mode=1777 \
--tmpfs /run:rw,size=50m \
nginx
# ข้อมูลใน /tmp และ /run จะหายเมื่อหยุด container
docker exec app-with-tmpfs sh -c "echo 'temp data' > /tmp/temp.txt"
docker restart app-with-tmpfs
docker exec app-with-tmpfs cat /tmp/temp.txt # ไฟล์หายไป
# สร้าง source และ destination volumes
docker volume create source-vol
docker volume create dest-vol
# เพิ่มข้อมูลใน source volume
docker run --rm -v source-vol:/data alpine \
sh -c "echo 'Original data' > /data/file.txt"
# Copy ข้อมูลจาก source ไป destination
docker run --rm \
-v source-vol:/source:ro \
-v dest-vol:/dest \
alpine \
cp -av /source/. /dest/
# ตรวจสอบผลลัพธ์
docker run --rm -v dest-vol:/data alpine cat /data/file.txt
# ดี - ชื่อบอกจุดประสงค์
docker volume create postgres-prod-data
docker volume create redis-cache-dev
# ไม่ดี - ชื่อไม่ชัดเจน
docker volume create vol1
docker volume create data
# สร้าง volumes พร้อม labels
docker volume create \
--label env=production \
--label app=myapp \
--label backup=daily \
myapp-prod-data
# Filter volumes ตาม label
docker volume ls --filter label=env=production
# Script สำหรับ backup ทุกวัน
#!/bin/bash
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d)
for VOLUME in $(docker volume ls -q); do
docker run --rm \
-v $VOLUME:/source:ro \
-v $BACKUP_DIR:/backup \
alpine \
tar czf /backup/${VOLUME}-${DATE}.tar.gz -C /source .
done
# แสดง volumes ที่ไม่ได้ใช้งาน
docker volume ls --filter dangling=true
# ลบ volumes ที่ไม่ได้ใช้งาน
docker volume prune
# ตรวจสอบก่อนลบ
docker volume prune --dry-run
# ดี - ใช้ official image
docker pull nginx
docker pull postgres:15
# ระวัง - third-party images
docker pull randomuser/nginx
# ใน Dockerfile
FROM node:18-alpine
# สร้าง user
RUN addgroup -g 1001 appgroup && \
adduser -D -u 1001 -G appgroup appuser
# เปลี่ยนเป็น non-root user
USER appuser
WORKDIR /app
COPY --chown=appuser:appgroup . .
CMD ["node", "server.js"]
# จำกัด memory และ CPU
docker run -d \
--name limited-app \
--memory="512m" \
--memory-swap="1g" \
--cpus="1.0" \
--pids-limit=100 \
my-app:latest
# รัน container แบบ read-only
docker run -d \
--name readonly-app \
--read-only \
--tmpfs /tmp \
nginx
# ดี - specific version
docker pull nginx:1.25.3
docker pull node:18.17-alpine
# หลีกเลี่ยง - latest tag
docker pull nginx:latest
# Build stage
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
USER node
EXPOSE 3000
CMD ["node", "dist/index.js"]
# ดี - layers ที่เปลี่ยนน้อยไว้ด้านบน
FROM python:3.11-slim
# Dependencies (เปลี่ยนน้อย)
COPY requirements.txt .
RUN pip install -r requirements.txt
# Application code (เปลี่ยนบ่อย)
COPY . .
CMD ["python", "app.py"]
# ดี - ชื่อบอกจุดประสงค์
docker run -d --name web-frontend-prod nginx
docker run -d --name postgres-myapp-db postgres
# ไม่ดี - ชื่อไม่ชัดเจน
docker run -d --name c1 nginx
docker run -d --name test postgres
FROM nginx:alpine
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1
COPY html /usr/share/nginx/html
# Production - always restart
docker run -d --restart=always --name prod-app my-app
# Development - no restart
docker run -d --restart=no --name dev-app my-app
# Restart เฉพาะเมื่อ error
docker run -d --restart=on-failure:5 --name critical-app my-app
# สร้าง custom network
docker network create app-network
# รัน containers บน custom network
docker run -d --name web --network app-network nginx
docker run -d --name api --network app-network my-api
# สร้าง networks แยกกัน
docker network create frontend
docker network create backend
# Database อยู่บน backend only
docker run -d --name db --network backend postgres
# API อยู่บนทั้งสอง networks
docker run -d --name api --network backend my-api
docker network connect frontend api
# Frontend อยู่บน frontend only
docker run -d --name web --network frontend nginx
# Production - named volume
docker run -d \
--name prod-db \
-v postgres-prod-data:/var/lib/postgresql/data \
postgres:15
# Development - bind mount
docker run -d \
--name dev-app \
-v $(pwd)/src:/app/src \
my-app:dev
# Backup script
#!/bin/bash
VOLUMES=("postgres-data" "redis-data" "app-uploads")
BACKUP_DIR="/backups/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
for VOL in "${VOLUMES[@]}"; do
docker run --rm \
-v $VOL:/source:ro \
-v $BACKUP_DIR:/backup \
alpine \
tar czf /backup/${VOL}.tar.gz -C /source .
echo "Backed up $VOL"
done
# สร้าง cleanup script
#!/bin/bash
echo "Cleaning up Docker resources..."
# ลบ stopped containers
docker container prune -f
# ลบ unused images
docker image prune -a -f
# ลบ unused volumes (ระวัง!)
docker volume prune -f
# ลบ unused networks
docker network prune -f
# ดูพื้นที่ที่ใช้
docker system df
echo "Cleanup completed!"
# ดู stats ของ containers ทั้งหมด
docker stats
# ดู stats ของ specific containers
docker stats web api db
# แสดง stats ครั้งเดียว (ไม่ stream)
docker stats --no-stream
# ดู logs พร้อม timestamp
docker logs -t my-container
# ดู logs แบบ follow
docker logs -f my-container
# จำกัด log lines
docker logs --tail 100 my-container
# ดู logs ในช่วงเวลา
docker logs --since 1h my-container
docker logs --until 2024-01-01T10:00:00 my-container
# ใช้ json-file log driver พร้อม rotation
docker run -d \
--name app \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
my-app
# ใช้ syslog
docker run -d \
--name app \
--log-driver syslog \
--log-opt syslog-address=udp://192.168.0.1:514 \
my-app
# 1. สร้าง development environment
docker network create dev-network
# 2. รัน database
docker run -d \
--name dev-db \
--network dev-network \
-e POSTGRES_PASSWORD=devpass \
-v dev-db-data:/var/lib/postgresql/data \
postgres:15
# 3. รัน application พร้อม hot reload
docker run -it \
--name dev-app \
--network dev-network \
-p 3000:3000 \
-v $(pwd)/src:/app/src \
-v $(pwd)/package.json:/app/package.json \
-e DATABASE_URL=postgresql://postgres:devpass@dev-db:5432/myapp \
my-app:dev npm run dev
# 4. รัน tests
docker run --rm \
--network dev-network \
-e DATABASE_URL=postgresql://postgres:devpass@dev-db:5432/test \
my-app:dev npm test
# รัน container
docker run -d --name myapp -p 8080:80 nginx
# แสดงรายการ containers
docker ps # ที่กำลังรัน
docker ps -a # ทั้งหมด
# จัดการ lifecycle
docker start myapp
docker stop myapp
docker restart myapp
docker kill myapp
docker rm myapp
# เข้าไปใน container
docker exec -it myapp bash
# ดู logs
docker logs -f myapp
# Copy files
docker cp file.txt myapp:/path/
docker cp myapp:/path/file.txt .
# Pull และ push
docker pull nginx:latest
docker push username/myapp:1.0
# Build
docker build -t myapp:1.0 .
# แสดงรายการ
docker images
# ลบ
docker rmi myapp:1.0
docker image prune -a
# สร้างและจัดการ
docker network create mynet
docker network ls
docker network inspect mynet
docker network rm mynet
# เชื่อมต่อ container
docker network connect mynet myapp
docker network disconnect mynet myapp
# สร้างและจัดการ
docker volume create mydata
docker volume ls
docker volume inspect mydata
docker volume rm mydata
docker volume prune
# ใช้งาน
docker run -v mydata:/data myapp
docker run -v $(pwd):/app myapp
# ดูข้อมูลระบบ
docker info
docker version
docker system df
# ทำความสะอาด
docker system prune # ลบ unused objects
docker system prune -a # ลบทั้งหมดรวม images
docker system prune --volumes # รวม volumes
Docker เป็นเครื่องมือที่ทรงพลังสำหรับ containerization ที่ช่วยให้การพัฒนา การทดสอบ และการ deploy แอปพลิเคชันเป็นไปอย่างมีประสิทธิภาพ ในบทความนี้เราได้เรียนรู้:
docker runDocker เป็นเพียงจุดเริ่มต้นของโลก containerization ซึ่งยังมีเครื่องมืออื่นๆ เช่น Kubernetes สำหรับ orchestration ขั้นสูง แต่การเข้าใจพื้นฐาน Docker อย่างแข็งแรงจะช่วยให้คุณก้าวไปสู่ระดับถัดไปได้อย่างมั่นใจ
หมายเหตุ: บทความนี้เป็นคู่มือเบื้องต้นสำหรับ Docker ไม่รวม Docker Compose และ Docker Swarm ซึ่งเป็น advanced topics สำหรับ multi-container orchestration
เวอร์ชัน: Docker 24.x