- 1. บทนำสู่ Docker
- 2. การติดตั้งและตั้งค่า Docker
- 3. การใช้งาน Docker เบื้องต้น
- 4. การสร้าง Docker Image ด้วย Dockerfile
- 5. Docker Compose – การจัดการ Multi-Container Application
- 6. ตัวอย่างการสร้างโปรเจค Docker แบบ End-to-End
- 7. การจัดการและ Debug Container
- 8. แนวทางการ Deploy Docker ใน Production
- 9. การปรับปรุงและขยายความสามารถของ Docker
- 10. สรุปและแนวทางการเรียนรู้ต่อยอด
- 11. ตัวอย่างการ Build และอธิบาย Dockerfile
ก่อนเข้าสู่เนื้อหา โปรดสมัครและเตรียมรายการบริการทั้งหมดนี้พร้อม login ไว้
-
Docker Hub
- URL: https://hub.docker.com/
- จำเป็นต้องสมัครสมาชิก (สมัครฟรีด้วยอีเมลหรือผ่าน Google/GitHub)
-
GitHub
- URL: https://github.com/
- จำเป็นต้องสมัครสมาชิกเพื่อใช้งาน repository และ GitHub Actions
-
GitLab
- URL: https://gitlab.com/
- จำเป็นต้องสมัครสมาชิกเพื่อใช้งาน repository และ CI/CD
-
Cloudflare
- URL: https://www.cloudflare.com/
- จำเป็นต้องสมัครสมาชิกเพื่อใช้งาน DNS, CDN และ Reverse Proxy
-
Uptime Monitoring Service (ตัวอย่าง Uptime Robot)
- URL: https://uptimerobot.com/
- จำเป็นต้องสมัครสมาชิกเพื่อใช้งานบริการตรวจสอบสถานะ (มีทั้งฟรีและแบบเสียเงิน)
-
Grafana Cloud
- URL: https://grafana.com/products/cloud/
- จำเป็นต้องสมัครสมาชิก (มีทั้ง Free tier และแบบเสียเงินสำหรับฟีเจอร์ขั้นสูง)
-
Deploy on Vercel
- URL: https://vercel.com/
- จำเป็นต้องสมัครสมาชิก (เชื่อมต่อกับ GitHub/GitLab/Bitbucket)
-
Deploy on Netlify
- URL: https://www.netlify.com/
- จำเป็นต้องสมัครสมาชิก (เชื่อมต่อกับ Git repository หรือสมัครด้วยอีเมล)
-
DigitalOcean (สำหรับ Droplets, App Platform และ Managed Kubernetes/DOKS)
- URL: https://www.digitalocean.com/
- จำเป็นต้องสมัครสมาชิกและผูกวิธีชำระเงิน เพื่อใช้งาน Droplets, App Platform
-
ดาวน์โหลดและติดตั้ง Git
- URL: https://git-scm.com/
- ทำตามขั้นตอนการติดตั้งที่แนะนำ โดยทั่วไป, คุณสามารถใช้ค่าเริ่มต้นได้
-
GitHub Desktop
Docker เป็นแพลตฟอร์มสำหรับการทำ containerization ที่พัฒนาขึ้นในปี 2013 ซึ่งช่วยให้การพัฒนา ทดสอบ และนำไปใช้งานแอปพลิเคชันในสภาพแวดล้อมที่แยกออกจากกันเป็นไปได้อย่างง่ายดาย โดยที่ไม่ต้องกังวลกับปัญหาความเข้ากันได้กับระบบปฏิบัติการหรือโครงสร้างพื้นฐานที่แตกต่างกัน
- Containerization: แนวคิดการแยกส่วนแอปพลิเคชันและ dependencies ออกจากระบบปฏิบัติการหลัก ทำให้แอปพลิเคชันสามารถทำงานได้อย่างคงเส้นคงวาบนทุกสภาพแวดล้อม
- ข้อดี:
- ลดขั้นตอนการตั้งค่าสภาพแวดล้อมที่ซับซ้อน
- สามารถใช้งานได้ทั้งในเครื่องพัฒนาและระบบ production
- เพิ่มความสามารถในการย้ายข้ามแพลตฟอร์มได้อย่างไร้รอยต่อ
- ลดปัญหา "works on my machine" ที่พบบ่อยในการพัฒนาซอฟต์แวร์
- เริ่มต้นทำงานได้เร็วกว่า VM เนื่องจากใช้ทรัพยากรน้อยกว่า
graph TB
subgraph "Virtual Machines"
Application1[Application 1] --> GuestOS1[Guest OS 1]
Application2[Application 2] --> GuestOS2[Guest OS 2]
Application3[Application 3] --> GuestOS3[Guest OS 3]
GuestOS1 --> Hypervisor
GuestOS2 --> Hypervisor
GuestOS3 --> Hypervisor
Hypervisor --> HostOS[Host OS]
HostOS --> Infrastructure
end
subgraph "Containers"
ContainerApp1[Application 1] --> ContainerRuntime1[Container Runtime]
ContainerApp2[Application 2] --> ContainerRuntime2[Container Runtime]
ContainerApp3[Application 3] --> ContainerRuntime3[Container Runtime]
ContainerRuntime1 --> DockerEngine[Docker Engine]
ContainerRuntime2 --> DockerEngine
ContainerRuntime3 --> DockerEngine
DockerEngine --> HostOS2[Host OS]
HostOS2 --> Infrastructure2[Infrastructure]
end
Virtual Machines:
- ต้องมี Guest OS แต่ละ VM ซึ่งใช้ทรัพยากรมาก
- Boot time ช้า (นาที)
- ขนาดใหญ่ (GB)
- การจัดการทรัพยากร (Hypervisor)
Containers:
- ใช้ OS kernel ร่วมกัน
- Boot time เร็ว (วินาที)
- ขนาดเล็ก (MB)
- การจัดการทรัพยากร (Container Engine)
- Images: เป็นแม่แบบ read-only ของ container ที่มีการกำหนดค่าต่าง ๆ ที่จำเป็นสำหรับการรันแอปพลิเคชัน รวมถึง dependencies, libraries, และ configuration ต่าง ๆ
- Containers: เป็น instance ที่รันจาก image ซึ่งมีสภาพแวดล้อมการทำงานที่แยกออกจากกัน มีชั้น read-write ที่วางทับบน image ช่วยให้สามารถบันทึกการเปลี่ยนแปลงระหว่างที่ container ทำงานได้
- Dockerfile: ไฟล์ที่ใช้สำหรับสร้าง Docker image โดยระบุขั้นตอนและคำสั่งที่จำเป็นต่าง ๆ เช่น การเลือกฐาน image, การติดตั้งแพ็คเกจ, การกำหนดคำสั่งที่จะทำงานเมื่อ container เริ่มทำงาน
- Docker Hub: Registry สาธารณะที่ใช้เป็นแหล่งเก็บ Docker image ซึ่งผู้ใช้สามารถดึง official image เช่น ubuntu, nginx, mysql หรือ image ที่สร้างโดยชุมชนมาใช้งานได้
- Registry: แหล่งเก็บและดึง Docker image ซึ่งอาจเป็น public (เช่น Docker Hub) หรือ private registry ที่องค์กรสร้างขึ้นเอง
- Docker Compose: เครื่องมือสำหรับกำหนดและรัน multi-container applications โดยใช้ไฟล์ YAML ในการกำหนดค่า
- Docker Swarm: ระบบ orchestration ที่มาพร้อมกับ Docker สำหรับการจัดการ container ในโหมด cluster
graph TD
dockerfile[Dockerfile] -->|build| dockerimage[Docker Image]
dockerimage -->|run| container[Container]
dockerimage -->|push| registry[Docker Registry]
registry -->|pull| dockerimage2[Docker Image]
dockerimage2 -->|run| container2[Container]
เอกสารนี้มีวัตถุประสงค์เพื่อให้ผู้อ่านได้เข้าใจและปฏิบัติการใช้งาน Docker อย่างครบวงจร ผ่านตัวอย่างที่เป็นขั้นตอนและเข้าใจง่าย โดยจะครอบคลุมหัวข้อต่าง ๆ ตั้งแต่การติดตั้ง Docker จนถึงการปรับใช้แอปพลิเคชันในระบบ production รวมถึงการจัดการปัญหาที่อาจเกิดขึ้นในการใช้งานจริง
เป้าหมายการเรียนรู้:
- เข้าใจแนวคิดพื้นฐานและประโยชน์ของ containerization
- สามารถติดตั้งและใช้งาน Docker ได้อย่างถูกต้อง
- สร้างและจัดการ Docker images และ containers
- เขียน Dockerfile เพื่อสร้าง custom image
- ใช้งาน Docker Compose สำหรับแอปพลิเคชันที่มี container หลายตัว
- เข้าใจแนวทางการนำ Docker ไปใช้ในสภาพแวดล้อม production
อัพเดตแพ็คเกจเพื่อให้มั่นใจว่าระบบเป็นเวอร์ชันล่าสุด:
apt update
apt upgrade -yติดตั้งแพ็คเกจที่จำเป็นสำหรับการติดตั้ง Docker:
apt install apt-transport-https ca-certificates curl gnupg lsb-release curl sudo -yเพิ่ม Docker GPG key เพื่อให้ระบบเชื่อถือแหล่งที่มาของแพ็คเกจ:
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpgเพิ่ม Docker repository เข้าสู่ระบบ:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/nullติดตั้ง Docker Engine และ components ที่เกี่ยวข้อง:
apt update
apt install docker-ce docker-ce-cli containerd.io -yตรวจสอบการติดตั้งโดยดูเวอร์ชัน Docker:
docker --versionตรวจสอบว่า Docker daemon กำลังทำงานอยู่:
systemctl status dockerข้อกำหนดสำหรับ Windows:
- Windows 10 64-bit: Pro, Enterprise, หรือ Education (Build 16299 หรือใหม่กว่า)
- Hyper-V และ Containers Windows features ต้องเปิดใช้งาน
ขั้นตอนการติดตั้ง:
- ดาวน์โหลด Docker Desktop จาก Docker Hub
- ดับเบิลคลิกที่ไฟล์ติดตั้ง Docker Desktop Installer.exe
- ทำตามขั้นตอนการติดตั้งในวิซาร์ด
- เมื่อเสร็จสิ้น จะมีการรีสตาร์ทเครื่อง
- หลังจากรีสตาร์ท Docker Desktop จะเริ่มทำงานโดยอัตโนมัติ
ทดสอบการติดตั้ง: เปิด PowerShell หรือ Command Prompt และรันคำสั่ง:
docker version
docker run hello-worldข้อกำหนดสำหรับ macOS:
- macOS 10.14 (Mojave) ขึ้นไป สำหรับ Intel Mac
- macOS 11 (Big Sur) ขึ้นไป สำหรับ Apple Silicon Mac
ขั้นตอนการติดตั้ง:
- ดาวน์โหลด Docker Desktop จาก Docker Hub
- ดับเบิลคลิกที่ไฟล์ DMG และลาก Docker.app ไปยัง Applications
- เปิด Docker จาก Applications folder
- ตอบรับคำขอสิทธิ์ที่จำเป็น
ทดสอบการติดตั้ง: เปิด Terminal และรันคำสั่ง:
docker version
docker run hello-worldเพิ่มผู้ใช้ปัจจุบันเข้ากลุ่ม docker เพื่อให้สามารถรันคำสั่ง Docker ได้โดยไม่ต้องใช้ sudo:
usermod -aG docker $USERเพื่อให้การเปลี่ยนแปลงมีผล คุณจำเป็นต้อง:
- ออกจากระบบแล้วกลับเข้าสู่ระบบใหม่ หรือ
- รันคำสั่งต่อไปนี้เพื่อใช้งานในเซสชันปัจจุบัน:
newgrp dockerทดสอบว่าสามารถรัน Docker โดยไม่ใช้ sudo:
docker run hello-worldสำหรับ Linux:
Docker Compose ไม่ได้มากับ Docker Engine โดยอัตโนมัติในระบบ Linux จึงต้องติดตั้งเพิ่มเติม:
curl -L "https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --versionสำหรับ Windows และ macOS:
Docker Compose มาพร้อมกับ Docker Desktop แล้ว ไม่จำเป็นต้องติดตั้งเพิ่มเติม
คุณสามารถปรับแต่ง Docker daemon เพื่อให้เข้ากับความต้องการใช้งานได้ โดยแก้ไขไฟล์ /etc/docker/daemon.json (สร้างไฟล์หากยังไม่มี):
{
"default-address-pools": [
{
"base": "172.20.0.0/16",
"size": 24
}
],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2"
}รีสตาร์ท Docker daemon เพื่อให้การเปลี่ยนแปลงมีผล:
systemctl restart dockerflowchart LR
A[docker run] --> B[Container ทำงาน]
C[docker ps] --> D[ดูรายการ Container]
E[docker stop] --> F[หยุด Container]
G[docker rm] --> H[ลบ Container]
I[docker images] --> J[ดูรายการ Image]
K[docker rmi] --> L[ลบ Image]
M[docker pull] --> N[ดึง Image จาก Registry]
docker pull: ดาวน์โหลด image จาก Docker Registry
# รูปแบบ: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
docker pull ubuntu:22.04docker images: แสดงรายการ images ที่มีในเครื่อง
docker imagesdocker rmi: ลบ image ที่ไม่จำเป็นต้องใช้แล้ว
# รูปแบบ: docker rmi [OPTIONS] IMAGE [IMAGE...]
docker rmi ubuntu:22.04
# ลบหลาย image พร้อมกัน
docker rmi image1 image2 image3docker build: สร้าง image จาก Dockerfile
# รูปแบบ: docker build [OPTIONS] PATH | URL | -
docker build -t myapp:1.0 .docker tag: กำหนด tag ให้กับ image
# รูปแบบ: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
docker tag myapp:1.0 username/myapp:latestdocker run: สร้างและเริ่มต้น container จาก image
# รูปแบบพื้นฐาน
docker run hello-world
# รันแบบ interactive
docker run -it ubuntu bash
# รันในโหมด detached (รันเป็น background)
docker run -d nginx
# กำหนด port mapping (-p host_port:container_port)
docker run -d -p 8080:80 nginx
# กำหนดชื่อ container
docker run -d --name my-nginx nginx
# ระบุ environment variables
docker run -e ENV_VAR=value nginxdocker ps: แสดงรายการ container ที่กำลังทำงาน
# ดู container ที่กำลังทำงานอยู่
docker ps
# ดูทั้ง container ที่กำลังทำงานและที่หยุดการทำงาน
docker ps -adocker stop: หยุดการทำงานของ container
# รูปแบบ: docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker stop container_id_or_name
# หยุดหลาย container พร้อมกัน
docker stop container1 container2docker start: เริ่มการทำงานของ container ที่หยุดไว้
docker start container_id_or_namedocker restart: รีสตาร์ท container
docker restart container_id_or_namedocker rm: ลบ container ที่ไม่ใช้งานแล้ว
docker rm container_id_or_name
# ลบ container พร้อมกัน
docker rm container1 container2
# ลบ container ที่หยุดทำงานแล้วทั้งหมด
docker container prunedocker logs: ดู logs ของ container
# ดู logs ทั้งหมด
docker logs container_id_or_name
# ติดตาม logs แบบเรียลไทม์ (เหมือน tail -f)
docker logs -f container_id_or_name
# ดู logs จำนวนจำกัด
docker logs --tail 100 container_id_or_nameการรัน container ในโหมด interactive ช่วยให้เราสามารถเข้าถึง shell ภายใน container เพื่อดีบัก ทดสอบ หรือจัดการกับไฟล์ภายใน container
# รูปแบบ: docker run -it IMAGE [COMMAND]
docker run -it ubuntu /bin/bashอธิบายการใช้ flags:
-i(interactive) เก็บ STDIN เปิดไว้แม้จะไม่มีการ attach-t(tty) จัดสรรเทอร์มินัลเสมือนให้กับ container
# รูปแบบ: docker exec -it CONTAINER COMMAND
docker exec -it container_name /bin/bashตัวอย่าง 1: ทดสอบการติดตั้งแพ็คเกจใน Ubuntu container
docker run -it ubuntu /bin/bash
apt update
apt install curl
curl --version
exit # ออกจาก containerตัวอย่าง 2: ตรวจสอบไฟล์ configuration ใน Nginx container
docker run -d --name my-nginx nginx
docker exec -it my-nginx /bin/bash
cat /etc/nginx/nginx.conf
exitDocker Volume เป็นกลไกในการจัดเก็บข้อมูลของ container อย่างถาวร ซึ่งจะยังคงอยู่แม้ว่า container จะถูกลบไปแล้ว ช่วยให้สามารถแชร์ข้อมูลระหว่าง container และระหว่าง container กับโฮสต์
graph TD
subgraph "Host Machine"
A[Host File System]
V[Docker Volume]
end
subgraph "Container 1"
C1[Container File System]
end
subgraph "Container 2"
C2[Container File System]
end
A -- bind mount --> C1
V -- volume mount --> C1
V -- volume mount --> C2
- Volumes: จัดการโดย Docker เอง เก็บที่
/var/lib/docker/volumes/บนโฮสต์ - Bind Mounts: เชื่อมกับไดเรกทอรีที่กำหนดบนระบบไฟล์โฮสต์
- tmpfs Mounts: เก็บใน memory ของโฮสต์ ไม่เขียนลงดิสก์
สร้าง volume:
docker volume create my-volumeดูรายละเอียด volume:
docker volume inspect my-volumeรัน container โดยใช้ volume:
# รูปแบบ: docker run -v VOLUME_NAME:CONTAINER_PATH IMAGE
docker run -d -v my-volume:/app nginxรัน container โดยใช้ bind mount:
# รูปแบบ: docker run -v HOST_PATH:CONTAINER_PATH IMAGE
docker run -d -v /home/user/data:/app/data nginxแชร์ volume ระหว่าง container:
# สร้าง container แรกที่ใช้ volume
docker run -d --name container1 -v my-volume:/app nginx
# สร้าง container ที่สองที่ใช้ volume เดิม
docker run -d --name container2 -v my-volume:/app nginxเก็บข้อมูลฐานข้อมูล:
docker volume create mysql_data
docker run -d \
--name mysql_db \
-e MYSQL_ROOT_PASSWORD=secret \
-v mysql_data:/var/lib/mysql \
mysql:8.0แชร์โค้ดแอปพลิเคชันกับ container (สำหรับ development):
docker run -d \
--name node_app \
-v $(pwd):/app \
-w /app \
-p 3000:3000 \
node:14 \
npm startเก็บ configuration files:
docker run -d \
--name nginx \
-v /path/to/nginx.conf:/etc/nginx/nginx.conf:ro \
-p 80:80 \
nginx# ลบ volume
docker volume rm my-volume
# ลบ volume ที่ไม่ได้ใช้งาน
docker volume pruneDockerfile คือไฟล์ข้อความที่ประกอบด้วยชุดคำสั่งที่ใช้สำหรับสร้าง Docker image โดยอัตโนมัติ ซึ่งมีความสำคัญดังนี้:
- การทำให้สามารถทำซ้ำได้ (Reproducibility): ช่วยให้สามารถสร้าง image ที่เหมือนกันได้ทุกครั้ง ไม่ว่าจะบนเครื่องไหนหรือใครเป็นคนสร้าง
- การจัดการเวอร์ชัน (Version Control): สามารถเก็บ Dockerfile ไว้ใน version control system เช่น Git ได้ ทำให้สามารถติดตามการเปลี่ยนแปลงของสภาพแวดล้อมได้
- การจัดการขั้นตอนการสร้างอัตโนมัติ (Automation): สามารถใช้ในระบบ CI/CD เพื่อสร้าง image โดยอัตโนมัติ
- การจัดการสภาพแวดล้อมเป็นโค้ด (Infrastructure as Code): ช่วยให้สามารถจัดการสภาพแวดล้อมการรันแอปพลิเคชันเป็นโค้ด
ตัวอย่าง Dockerfile สำหรับแอปพลิเคชัน Node.js:
# เริ่มต้นด้วย base image
FROM node:14
# กำหนด working directory
WORKDIR /app
# คัดลอกไฟล์ package.json และ package-lock.json
COPY package*.json ./
# ติดตั้ง dependencies
RUN npm install
# คัดลอกโค้ดแอปพลิเคชันทั้งหมดไปยัง container
COPY . .
# กำหนด port ที่จะ expose
EXPOSE 3000
# กำหนดคำสั่งรันเมื่อ container ถูกสร้างขึ้น
CMD ["node", "app.js"]สร้างไฟล์ Dockerfile ใน directory ของโปรเจค
รันคำสั่งต่อไปนี้เพื่อสร้าง image:
docker build -t my-node-app .ตรวจสอบ image ที่สร้างขึ้น:
docker imagesDocker Compose คือเครื่องมือสำหรับการจัดการและตั้งค่าการรันหลาย container ในแอปพลิเคชันเดียวกัน โดยใช้ไฟล์ docker-compose.yml
ตัวอย่างการตั้งค่า Docker Compose สำหรับแอปพลิเคชันที่ประกอบด้วย Web Server และ Database:
version: '3'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:13
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:การรัน:
docker-compose up -dการตรวจสอบ log:
docker-compose logsการหยุดและลบ container ที่รันด้วย Compose:
docker-compose downในบทนี้เราจะสร้างโปรเจคที่มีแอปพลิเคชัน Node.js ติดต่อกับฐานข้อมูล PostgreSQL โดยใช้ Docker และ Docker Compose
my-docker-project/
├── app.js
├── package.json
├── Dockerfile
└── docker-compose.yml
app.js (ตัวอย่างโค้ดเบื้องต้น):
const express = require('express');
const { Client } = require('pg');
const app = express();
const port = 3000;
// กำหนดการเชื่อมต่อฐานข้อมูล
const client = new Client({
host: 'db',
user: 'user',
password: 'password',
database: 'mydb'
});
client.connect()
.then(() => console.log('Connected to PostgreSQL'))
.catch(err => console.error('Connection error', err.stack));
app.get('/', async (req, res) => {
try {
const result = await client.query('SELECT NOW()');
res.send(`Server time is: ${result.rows[0].now}`);
} catch (err) {
res.status(500).send(err.toString());
}
});
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});ตามที่แสดงในบทที่ 4
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]version: '3'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:13
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:เปิด terminal ไปที่ directory ของโปรเจค
รันคำสั่ง:
docker-compose up -dตรวจสอบว่าแอปพลิเคชันและฐานข้อมูลทำงานได้อย่างถูกต้องโดยเข้าเว็บเบราว์เซอร์ที่:
http://localhost:3000
ดู log ของ container ที่ระบุ:
docker logs <container_id>ดู log แบบเรียลไทม์:
docker logs -f <container_id>หากต้องการตรวจสอบหรือ debug ภายใน container สามารถใช้คำสั่ง exec:
docker exec -it <container_id> /bin/bash- ปัญหา Port Conflict: ตรวจสอบว่า port ที่ระบุใน
docker-compose.ymlหรือdocker runไม่ถูกใช้งานโดยโปรเซสอื่น - ปัญหา Image Build: ตรวจสอบ Dockerfile และ cache ด้วยคำสั่ง
docker build --no-cache - ปัญหา Network: ตรวจสอบ network ของ container โดยใช้คำสั่ง
docker network lsและdocker network inspect
- การใช้ Docker Swarm หรือ Kubernetes: สำหรับการจัดการ container ที่มีจำนวนมากและต้องการ scaling แบบอัตโนมัติ
- การ Monitor Container: ใช้เครื่องมือเช่น Prometheus, Grafana ในการติดตามสถานะ container
- การ Log และ Centralized Logging: ใช้ ELK Stack (Elasticsearch, Logstash, Kibana) หรือ Splunk ในการรวบรวม log
- ใช้ multi-stage builds เพื่อลดขนาด image
- ไม่เก็บข้อมูลสำคัญใน image โดยตรง
- กำหนด resource limits (CPU, Memory) ในไฟล์ compose หรือใน orchestration tool
- ตรวจสอบความปลอดภัยของ container ด้วยการสแกน vulnerabilities
สร้าง custom network เพื่อให้ container สามารถสื่อสารกันได้ง่ายและแยกออกจาก network ภายนอก
docker network create my_custom_network
docker run -d --network my_custom_network my-node-appgraph TD
subgraph "Custom Network: my_custom_network"
A[Container 1] -->|Communicates| B[Container 2]
B -->|Communicates| C[Container 3]
C -->|Communicates| A
end
A -->|Communicates| D[Container 4]
D -->|Communicates| E[Container 5]
กำหนด environment variables ใน container เพื่อความยืดหยุ่นในการปรับเปลี่ยนค่า config
ผ่าน Dockerfile:
ENV NODE_ENV=productionผ่าน docker-compose.yml:
environment:
- NODE_ENV=production- ใช้ Docker Secrets (สำหรับ swarm) หรือจัดการไฟล์ config ที่ปลอดภัย
- ป้องกันข้อมูลสำคัญ (เช่น รหัสผ่าน) ไม่ให้ถูก hard-coded ลงใน Dockerfile
ในเอกสารนี้เราได้เรียนรู้:
- พื้นฐานและแนวคิดของ Docker
- การติดตั้งและตั้งค่า Docker บนระบบปฏิบัติการต่าง ๆ
- คำสั่งพื้นฐานสำหรับการจัดการ container และ image
- การสร้าง Dockerfile และการสร้าง Docker Image
- การใช้งาน Docker Compose สำหรับ multi-container applications
- ตัวอย่างโปรเจคจริงแบบ End-to-End
- เคล็ดลับในการ debug, monitoring และ deployment ใน production
- ลองสร้างโปรเจคใหม่ ๆ โดยนำ Docker เข้ามาช่วยจัดการ environment
- สำรวจเครื่องมือ orchestration อย่าง Kubernetes สำหรับการจัดการ container ในระดับ production
- เรียนรู้การ Integrate Docker กับ CI/CD Pipeline (เช่น Jenkins, GitLab CI) เพื่อให้การ deploy เป็นไปโดยอัตโนมัติ
- ศึกษา Docker Security เพื่อให้แอปพลิเคชันของคุณปลอดภัยมากขึ้น
ในบทนี้เราจะดูตัวอย่างการ Build Dockerfile ของแอปพลิเคชันประเภทต่างๆ โดยเน้นที่การอธิบายโครงสร้างและคำสั่งใน Dockerfile
php/
├── src/
│ ├── index.php
│ └── landing.html
└── Dockerfile
FROM php:8.0-apache
WORKDIR /var/www/html
COPY ./src/index.php .
COPY ./src/landing.html .
EXPOSE 80คำอธิบาย Dockerfile:
FROM php:8.0-apache- ใช้ image พื้นฐานที่มี PHP 8.0 และ Apache web serverWORKDIR /var/www/html- กำหนด working directory ภายใน container เป็นโฟลเดอร์ที่ Apache ใช้เป็น document rootCOPY ./src/index.php .- คัดลอกไฟล์ index.php จากโฟลเดอร์ src ในโปรเจคไปยัง working directoryCOPY ./src/landing.html .- คัดลอกไฟล์ landing.html ไปยัง working directory เช่นกันEXPOSE 80- ระบุว่า container จะใช้พอร์ต 80 (HTTP)
# Build image
docker build -t php-app -f Dockerfile .
# Run container
docker run -d -p 8080:80 --name my-php-app php-appหลังจากรันคำสั่งด้านบน คุณสามารถเข้าถึงแอปพลิเคชัน PHP ได้ที่ http://localhost:8080
html/
├── index.html
├── racksync.html
└── Dockerfile
FROM httpd:2.4
COPY . /usr/local/apache2/htdocs
WORKDIR /usr/local/apache2/htdocs
EXPOSE 80
ENV HOST=0.0.0.0
ENV PORT=80คำอธิบาย Dockerfile:
FROM httpd:2.4- ใช้ image พื้นฐานของ Apache HTTP Server รุ่น 2.4COPY . /usr/local/apache2/htdocs- คัดลอกทุกไฟล์จากโฟลเดอร์ปัจจุบันไปยังโฟลเดอร์ document root ของ ApacheWORKDIR /usr/local/apache2/htdocs- กำหนด working directory ภายใน containerEXPOSE 80- ระบุว่า container จะใช้พอร์ต 80 (HTTP)ENV HOST=0.0.0.0- กำหนดตัวแปรสภาพแวดล้อมสำหรับระบุ hostENV PORT=80- กำหนดตัวแปรสภาพแวดล้อมสำหรับระบุ port
# Build image
docker build -t html-app .
# Run container
docker run -d -p 8088:80 --name my-html-app html-appหลังจากรันคำสั่งด้านบน คุณสามารถเข้าถึงเว็บไซต์ HTML ได้ที่ http://localhost:8088
nodejs-app/
├── src/
│ └── app.js
├── package.json
└── Dockerfile
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY ./src .
EXPOSE 3000
CMD ["node", "app.js"]คำอธิบาย Dockerfile:
FROM node:14- ใช้ image พื้นฐานที่มี Node.js รุ่น 14WORKDIR /app- กำหนด working directory ใน container เป็น /appCOPY package*.json ./- คัดลอกไฟล์ package.json และ package-lock.json (ถ้ามี) ไปยัง working directoryRUN npm install- รันคำสั่ง npm install เพื่อติดตั้ง dependenciesCOPY ./src .- คัดลอกโค้ดแอปพลิเคชันจากโฟลเดอร์ src ไปยัง working directoryEXPOSE 3000- ระบุว่า container จะใช้พอร์ต 3000CMD ["node", "app.js"]- กำหนดคำสั่งที่จะทำงานเมื่อ container เริ่มต้น
# Build image
docker build -t nodejs-app .
# Run container
docker run -d -p 3000:3000 --name my-nodejs-app nodejs-appMulti-stage build ช่วยให้สามารถลดขนาดของ image สุดท้ายโดยแยกขั้นตอนการ build และ runtime
# Build stage
FROM node:14 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Production stage
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]คำอธิบาย Dockerfile:
-
Build stage:
FROM node:14 AS build- ใช้ image พื้นฐานที่มี Node.js สำหรับการ build และตั้งชื่อ stage นี้ว่า "build"WORKDIR /app- กำหนด working directoryCOPY package*.json ./- คัดลอกไฟล์ package.json เพื่อติดตั้ง dependenciesRUN npm install- ติดตั้ง dependenciesCOPY . .- คัดลอกโค้ดทั้งหมดไปยัง working directoryRUN npm run build- build แอปพลิเคชันเพื่อสร้างไฟล์ static
-
Production stage:
FROM nginx:alpine- ใช้ image ขนาดเล็กของ Nginx สำหรับเซิร์ฟไฟล์ staticCOPY --from=build /app/build /usr/share/nginx/html- คัดลอกไฟล์ที่ build จาก stage แรกไปยัง document root ของ NginxEXPOSE 80- ระบุว่า container จะใช้พอร์ต 80CMD ["nginx", "-g", "daemon off;"]- คำสั่งเริ่มต้น Nginx
# Build image
docker build -t react-app .
# Run container
docker run -d -p 8080:80 --name my-react-app react-app| คำสั่ง | คำอธิบาย | ตัวอย่าง |
|---|---|---|
FROM |
กำหนด base image | FROM node:14 |
WORKDIR |
กำหนด working directory | WORKDIR /app |
COPY |
คัดลอกไฟล์จากโฮสต์ไปยัง container | COPY . /app |
ADD |
คล้าย COPY แต่สามารถใช้กับ URL และไฟล์ tar |
ADD https://example.com/file.tar.gz /app |
RUN |
รันคำสั่งระหว่างการสร้าง image | RUN npm install |
ENV |
กำหนดตัวแปรสภาพแวดล้อม | ENV NODE_ENV production |
ARG |
กำหนดตัวแปรที่ใช้ในขณะสร้าง image | ARG VERSION=latest |
EXPOSE |
ระบุพอร์ตที่ container จะเปิดให้ใช้งาน | EXPOSE 80 |
CMD |
กำหนดคำสั่งเริ่มต้นเมื่อ container เริ่มทำงาน | CMD ["node", "app.js"] |
ENTRYPOINT |
กำหนดแอปพลิเคชันหลักที่จะรันใน container | ENTRYPOINT ["npm", "start"] |
VOLUME |
สร้าง mount point สำหรับข้อมูลที่ต้องคงอยู่ | VOLUME /data |
USER |
กำหนด user ที่จะรันคำสั่งต่อไป | USER node |
HEALTHCHECK |
กำหนดการตรวจสอบสถานะของ container | `HEALTHCHECK CMD curl -f http://localhost/ |
LABEL |
เพิ่ม metadata ให้กับ image | LABEL version="1.0" maintainer="user@example.com" |
SHELL |
กำหนด shell ที่ใช้กับคำสั่ง RUN, CMD, ENTRYPOINT | SHELL ["/bin/bash", "-c"] |
-
ใช้ multi-stage builds เพื่อลดขนาด image
FROM node:14 AS build # คำสั่งสำหรับการ build FROM nginx:alpine COPY --from=build /app/dist /usr/share/nginx/html
-
จัดลำดับชั้นตามความถี่ของการเปลี่ยนแปลง โดยวางชั้นที่มีการเปลี่ยนแปลงน้อยไว้ด้านบน เพื่อใช้ประโยชน์จาก Docker cache
# คัดลอก package.json ก่อนเพื่อใช้ประโยชน์จาก cache COPY package.json . RUN npm install # คัดลอกไฟล์โค้ดที่อาจมีการเปลี่ยนแปลงบ่อย COPY . .
-
รวมคำสั่ง RUN เพื่อลดจำนวนชั้น
# แนะนำให้ใช้ RUN apt-get update && apt-get install -y \ package1 \ package2 \ && rm -rf /var/lib/apt/lists/* # ไม่แนะนำให้ใช้ RUN apt-get update RUN apt-get install -y package1 RUN apt-get install -y package2
-
ใช้ .dockerignore เพื่อลดขนาด build context
# .dockerignore node_modules npm-debug.log .git -
หลีกเลี่ยงการติดตั้งแพ็คเกจที่ไม่จำเป็น
# ใช้ --no-install-recommends เพื่อติดตั้งเฉพาะแพ็คเกจที่จำเป็น RUN apt-get update && apt-get install -y --no-install-recommends \ package1 \ && rm -rf /var/lib/apt/lists/*
-
ใช้ specific tag แทน latest เพื่อความคงเส้นคงวา
# แนะนำให้ใช้ FROM node:14.17.0-alpine # ไม่แนะนำให้ใช้ FROM node:latest
-
ลบไฟล์ที่ไม่จำเป็นหลังจากติดตั้ง
RUN apt-get update && apt-get install -y \ package1 \ && rm -rf /var/lib/apt/lists/* -
ใช้ non-root user เพื่อความปลอดภัย
RUN useradd -r appuser USER appuser
| ลักษณะ | การ Deploy แบบดั้งเดิม | การ Deploy ด้วย Docker |
|---|---|---|
| การติดตั้ง Dependencies | ต้องติดตั้ง runtime และ dependencies บน server โดยตรง | มาพร้อมกับ image ไม่ต้องติดตั้งเพิ่มเติม |
| ความสอดคล้องของสภาพแวดล้อม | อาจแตกต่างระหว่าง development และ production | สภาพแวดล้อมเหมือนกันทุกที่ |
| การ Scale | ต้องตั้งค่า load balancer และเพิ่ม server แยก | สามารถ scale ได้ง่ายด้วย orchestration tools |
| การแยกแอปพลิเคชัน | ต้องใช้ VM หรือ server แยก | แต่ละ container แยกออกจากกันโดยธรรมชาติ |
| การ Rollback | มักซับซ้อนและใช้เวลา | สามารถทำได้อย่างรวดเร็วโดยการเปลี่ยน image tag |
| CI/CD | ต้องตั้งค่าเพิ่มเติมมาก | บูรณาการได้ง่ายกับ workflows |
ด้วยความรู้เกี่ยวกับการสร้างและใช้งาน Dockerfile ที่ได้เรียนรู้ในบทนี้ คุณจะสามารถสร้าง Docker image สำหรับแอปพลิเคชันของคุณได้อย่างมีประสิทธิภาพ และนำไปสู่การพัฒนาและ deploy แอปพลิเคชันที่มีความคงเส้นคงวาและจัดการได้ง่าย