#คู่มือการใช้งานคำสั่ง Docker และ Docker Compose ฉบับใช้งานจริง

Docker เป็นแพลตฟอร์มสำหรับบรรจุแอปพลิเคชันและสิ่งที่แอปพลิเคชันต้องใช้ให้อยู่ในรูปแบบ Container ช่วยให้ระบบทำงานได้อย่างสม่ำเสมอทั้งบนเครื่องนักพัฒนา เครื่องทดสอบ และเซิร์ฟเวอร์ Production

ส่วน Docker Compose ใช้สำหรับกำหนดและจัดการระบบที่ประกอบด้วย Container หลายตัว เช่น Web Application, Database, Redis และ Worker ผ่านไฟล์ compose.yaml เพียงไฟล์เดียว

บทความนี้รวบรวมคำสั่งที่จำเป็น พร้อมตัวอย่างที่สามารถนำไปทดลองและประยุกต์ใช้กับการพัฒนาระบบจริงได้

#สารบัญ

  1. แนวคิดพื้นฐานของ Docker
  2. ตรวจสอบการติดตั้ง
  3. การจัดการ Docker Image
  4. การสร้างและจัดการ Container
  5. การดู Log และเข้าใช้งาน Container
  6. การใช้งาน Volume
  7. การใช้งาน Network
  8. การใช้งาน Docker Compose
  9. ตัวอย่างระบบด้วย Docker Compose
  10. การใช้ Environment Variable
  11. การตรวจสอบและแก้ไขปัญหา
  12. การทำความสะอาด Docker
  13. Docker Command Cheat Sheet

#แนวคิดพื้นฐานของ Docker

องค์ประกอบสำคัญของ Docker มีดังนี้

องค์ประกอบ ความหมาย
Dockerfile ไฟล์คำสั่งที่ใช้กำหนดขั้นตอนการสร้าง Image
Image ต้นแบบแบบอ่านอย่างเดียวสำหรับสร้าง Container
Container Instance ของ Image ที่กำลังทำงานหรือเคยถูกสร้างไว้
Registry แหล่งจัดเก็บและเผยแพร่ Image เช่น Docker Hub
Volume พื้นที่จัดเก็บข้อมูลถาวรของ Container
Network เครือข่ายสำหรับเชื่อมต่อระหว่าง Container
Compose เครื่องมือจัดการระบบที่มีหลาย Container

ลำดับการทำงานทั่วไปคือ:

Dockerfile → Image → Container

ตัวอย่างเช่น เราสามารถสร้าง Image ของ Web Application จาก Dockerfile แล้วนำ Image นั้นไปรันเป็น Container หลายตัวได้


#ตรวจสอบการติดตั้ง

ตรวจสอบเวอร์ชันของ Docker:

docker --version

ตรวจสอบ Docker Compose:

docker compose version

ตรวจสอบรายละเอียดของ Docker Engine:

docker info

ทดลองรัน Container ตัวอย่าง:

docker run --rm hello-world

Docker Compose รุ่นปัจจุบันใช้คำสั่ง docker compose โดยมีช่องว่างระหว่างคำว่า docker และ compose


#การจัดการ Docker Image

#ค้นหาและดาวน์โหลด Image

ค้นหา Image จาก Docker Hub:

docker search nginx

ดาวน์โหลด Image:

docker pull nginx:alpine

หากไม่ระบุ Tag ระบบจะใช้ latest:

docker pull nginx

สำหรับระบบ Production ควรระบุเวอร์ชันอย่างชัดเจน เพื่อป้องกันการเปลี่ยนแปลงของ Image โดยไม่ตั้งใจ

docker pull mysql:8.4

#แสดงรายการ Image

docker images

หรือ:

docker image ls

#สร้าง Image จาก Dockerfile

ตัวอย่าง Dockerfile:

FROM nginx:alpine

COPY ./html /usr/share/nginx/html

EXPOSE 80

สร้าง Image ชื่อ my-web และกำหนด Tag เป็น 1.0:

docker build -t my-web:1.0 .

แสดงรายละเอียดประวัติการสร้าง Image:

docker history my-web:1.0

#กำหนด Tag ให้ Image

docker tag my-web:1.0 username/my-web:1.0

นำ Image ขึ้น Registry:

docker login
docker push username/my-web:1.0

#ลบ Image

docker rmi my-web:1.0

บังคับลบ Image:

docker rmi -f my-web:1.0

#การสร้างและจัดการ Container

#สร้างและรัน Container

รัน Nginx Container:

docker run nginx:alpine

รันแบบเบื้องหลังด้วย -d:

docker run -d nginx:alpine

กำหนดชื่อ Container:

docker run -d --name web-server nginx:alpine

#เชื่อมต่อพอร์ต

เชื่อมต่อพอร์ต 8080 ของเครื่อง Host ไปยังพอร์ต 80 ของ Container:

docker run -d \
  --name web-server \
  -p 8080:80 \
  nginx:alpine

จากนั้นเปิดเว็บเบราว์เซอร์ที่:

http://localhost:8080

รูปแบบการกำหนดพอร์ตคือ:

HOST_PORT:CONTAINER_PORT

#กำหนด Environment Variable

docker run -d \
  --name mysql-server \
  -e MYSQL_ROOT_PASSWORD=root-secret \
  -e MYSQL_DATABASE=demo \
  mysql:8.4

#ลบ Container อัตโนมัติหลังทำงานเสร็จ

ตัวเลือก --rm เหมาะสำหรับ Container ชั่วคราว:

docker run --rm alpine echo "Hello Docker"

#แสดงรายการ Container

แสดงเฉพาะ Container ที่กำลังทำงาน:

docker ps

แสดง Container ทั้งหมด:

docker ps -a

แสดงเฉพาะ Container ID:

docker ps -q

#หยุดและเริ่ม Container

docker stop web-server
docker start web-server
docker restart web-server

หยุด Container โดยกำหนดเวลารอก่อนบังคับหยุด:

docker stop -t 30 web-server

#ลบ Container

Container ต้องหยุดทำงานก่อนจึงจะลบได้:

docker stop web-server
docker rm web-server

หยุดและลบ Container ทันที:

docker rm -f web-server

#ตรวจสอบรายละเอียด Container

docker inspect web-server

ดูการใช้ CPU และ Memory แบบ Real-time:

docker stats

ดู Process ที่ทำงานภายใน Container:

docker top web-server

#การดู Log และเข้าใช้งาน Container

#ดู Log

docker logs web-server

ติดตาม Log แบบ Real-time:

docker logs -f web-server

แสดง Log 100 บรรทัดล่าสุด:

docker logs --tail 100 web-server

แสดง Log พร้อมเวลา:

docker logs -f --timestamps web-server

#เข้าใช้งาน Shell ภายใน Container

สำหรับ Image ขนาดเล็กที่มี sh:

docker exec -it web-server sh

สำหรับ Container ที่มี Bash:

docker exec -it web-server bash

ตัวเลือกที่ใช้มีความหมายดังนี้:

  • -i เปิดรับข้อมูลจากแป้นพิมพ์
  • -t สร้าง Terminal สำหรับโต้ตอบ

#รันคำสั่งภายใน Container

docker exec web-server nginx -v

ตรวจสอบ Environment Variable:

docker exec web-server env

#คัดลอกไฟล์

คัดลอกจาก Host ไปยัง Container:

docker cp index.html web-server:/usr/share/nginx/html/index.html

คัดลอกจาก Container มายัง Host:

docker cp web-server:/etc/nginx/nginx.conf ./nginx.conf

#การใช้งาน Volume

ข้อมูลที่เขียนไว้ภายใน Container อาจหายไปเมื่อ Container ถูกลบ จึงควรใช้ Volume สำหรับข้อมูลที่ต้องเก็บถาวร เช่น Database และไฟล์ที่ผู้ใช้อัปโหลด

#สร้างและจัดการ Named Volume

docker volume create mysql-data
docker volume ls
docker volume inspect mysql-data

นำ Volume ไปใช้กับ MySQL:

docker run -d \
  --name mysql-server \
  -e MYSQL_ROOT_PASSWORD=root-secret \
  -v mysql-data:/var/lib/mysql \
  mysql:8.4

เมื่อลบ Container ข้อมูลใน mysql-data จะยังคงอยู่

#ใช้ Bind Mount

Bind Mount เชื่อมต่อไฟล์หรือโฟลเดอร์บน Host เข้ากับ Container โดยตรง:

docker run -d \
  --name web-server \
  -p 8080:80 \
  -v ./html:/usr/share/nginx/html \
  nginx:alpine

เหมาะสำหรับการพัฒนา เพราะเมื่อแก้ไขไฟล์ในโฟลเดอร์ html การเปลี่ยนแปลงจะปรากฏใน Container ทันที

#ลบ Volume

docker volume rm mysql-data

การลบ Volume อาจทำให้ข้อมูลฐานข้อมูลสูญหายอย่างถาวร ควรสำรองข้อมูลและตรวจสอบชื่อ Volume ก่อนดำเนินการ


#การใช้งาน Network

Docker Network ช่วยให้ Container ติดต่อกันผ่านชื่อ Container หรือชื่อ Service โดยไม่ต้องกำหนด IP Address แบบคงที่

#สร้าง Network

docker network create app-network

แสดง Network ทั้งหมด:

docker network ls

ตรวจสอบรายละเอียด:

docker network inspect app-network

#เชื่อมต่อ Container เข้ากับ Network

รัน MySQL:

docker run -d \
  --name database \
  --network app-network \
  -e MYSQL_ROOT_PASSWORD=root-secret \
  -e MYSQL_DATABASE=demo \
  mysql:8.4

รัน Application ใน Network เดียวกัน:

docker run -d \
  --name application \
  --network app-network \
  my-application:1.0

Application สามารถเชื่อมต่อฐานข้อมูลโดยใช้ Hostname เป็นชื่อ Container:

DB_HOST=database
DB_PORT=3306

ไม่ควรใช้ localhost เพื่อเชื่อมต่อไปยัง Container อื่น เพราะ localhost ภายใน Container หมายถึง Container ตัวนั้นเอง


#การใช้งาน Docker Compose

Docker Compose ช่วยรวมการตั้งค่า Container หลายตัวไว้ในไฟล์ compose.yaml ทำให้สามารถเริ่ม หยุด และลบทั้งระบบได้ด้วยคำสั่งเดียว

#คำสั่งพื้นฐาน

เริ่มระบบและแสดง Log บนหน้าจอ:

docker compose up

เริ่มระบบแบบเบื้องหลัง:

docker compose up -d

สร้าง Image ใหม่ก่อนเริ่มระบบ:

docker compose up -d --build

ตรวจสอบสถานะ Service:

docker compose ps

ดู Log ของทุก Service:

docker compose logs

ติดตาม Log แบบ Real-time:

docker compose logs -f

ดู Log ของ Service เฉพาะ:

docker compose logs -f web

หยุด Service โดยยังไม่ลบ Container:

docker compose stop

เริ่ม Container ที่เคยหยุด:

docker compose start

Restart ทุก Service:

docker compose restart

ปิดระบบและลบ Container กับ Network ที่ Compose สร้าง:

docker compose down

ปิดระบบพร้อมลบ Volume:

docker compose down -v

คำสั่ง docker compose down -v จะลบ Named Volume ของโครงการ ซึ่งอาจรวมถึงข้อมูลฐานข้อมูล


#ตัวอย่างระบบด้วย Docker Compose

ตัวอย่างต่อไปนี้ประกอบด้วย Nginx และ MySQL

#โครงสร้างโครงการ

docker-demo/
├── compose.yaml
├── .env
└── html/
    └── index.html

#ไฟล์ compose.yaml

services:
  web:
    image: nginx:alpine
    ports:
      - "${APP_PORT:-8080}:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    depends_on:
      database:
        condition: service_healthy
    restart: unless-stopped

  database:
    image: mysql:8.4
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    volumes:
      - mysql-data:/var/lib/mysql
    healthcheck:
      test:
        - CMD
        - mysqladmin
        - ping
        - -h
        - localhost
        - -p${MYSQL_ROOT_PASSWORD}
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  mysql-data:

Compose จะสร้าง Default Network ให้โครงการโดยอัตโนมัติ Service web จึงสามารถติดต่อ database ผ่านชื่อ database ได้

#ไฟล์ html/index.html

<!DOCTYPE html>
<html lang="th">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Docker Compose Demo</title>
</head>
<body>
    <h1>Hello Docker Compose</h1>
    <p>เว็บไซต์กำลังทำงานภายใน Nginx Container</p>
</body>
</html>

#เริ่มต้นระบบ

docker compose up -d
docker compose ps

เปิดเว็บเบราว์เซอร์ที่:

http://localhost:8080

#การใช้ Environment Variable

สร้างไฟล์ .env ในโฟลเดอร์เดียวกับ compose.yaml:

APP_PORT=8080
MYSQL_DATABASE=demo
MYSQL_USER=demo
MYSQL_PASSWORD=change-this-password
MYSQL_ROOT_PASSWORD=change-this-root-password

อ้างอิงตัวแปรใน compose.yaml:

services:
  database:
    image: mysql:8.4
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}

ตรวจสอบว่า Compose แปลค่าตัวแปรถูกต้อง:

docker compose config

หากต้องการใช้ไฟล์ Environment อื่น:

docker compose --env-file .env.production up -d

ข้อควรปฏิบัติด้านความปลอดภัย:

  • ไม่ Commit ไฟล์ .env ที่มีรหัสผ่านหรือ API Key ขึ้น Git
  • สร้างไฟล์ .env.example เพื่อแสดงเฉพาะชื่อตัวแปรที่จำเป็น
  • Production ควรใช้ Secret Management ตามแพลตฟอร์มที่นำระบบไปติดตั้ง
  • ไม่เขียนรหัสผ่านไว้โดยตรงใน Dockerfile หรือ Source Code

#การจัดการ Service ด้วย Docker Compose

เริ่มเฉพาะ Service:

docker compose up -d database

Restart เฉพาะ Service:

docker compose restart web

เข้า Shell ของ Service:

docker compose exec web sh

เข้า MySQL:

docker compose exec database \
  mysql -u root -p

รันคำสั่งด้วย Container ชั่วคราว:

docker compose run --rm web nginx -v

สร้าง Image ใหม่:

docker compose build

สร้างใหม่โดยไม่ใช้ Build Cache:

docker compose build --no-cache

ดาวน์โหลด Image รุ่นใหม่:

docker compose pull

อัปเดตและเริ่มระบบใหม่:

docker compose pull
docker compose up -d

#การ Scale Service

เพิ่มจำนวน Worker เป็น 3 Container:

docker compose up -d --scale worker=3

ไม่ควรกำหนด container_name ให้ Service ที่ต้องการ Scale เพราะแต่ละ Container ต้องมีชื่อไม่ซ้ำกัน


#การตรวจสอบและแก้ไขปัญหา

#Container หยุดทำงานทันที

ตรวจสอบสถานะ:

docker ps -a

ดู Log:

docker logs <container-name>

หรือสำหรับ Compose:

docker compose logs <service-name>

สาเหตุที่พบบ่อย ได้แก่:

  • คำสั่งเริ่มต้นของ Application ทำงานผิดพลาด
  • Environment Variable ไม่ครบ
  • เชื่อมต่อ Database ไม่ได้
  • Port ถูกใช้งานอยู่แล้ว
  • สิทธิ์ของไฟล์หรือโฟลเดอร์ไม่ถูกต้อง

#Port ถูกใช้งานอยู่แล้ว

หากพอร์ต 8080 ถูกใช้งานอยู่ ให้เปลี่ยนพอร์ตฝั่ง Host:

ports:
  - "8081:80"

จากนั้นเข้าผ่าน:

http://localhost:8081

#Application เชื่อมต่อ Database ไม่ได้

ตรวจสอบว่า:

  • ทั้งสอง Service อยู่ใน Network เดียวกัน
  • ใช้ชื่อ Service เป็น Database Host
  • Database ผ่าน Health Check แล้ว
  • Username, Password และ Database Name ถูกต้อง

ตัวอย่างค่าที่ถูกต้องภายใน Compose:

DB_HOST=database
DB_PORT=3306

#ตรวจสอบ Compose Configuration

docker compose config

คำสั่งนี้ช่วยตรวจสอบโครงสร้าง YAML และแสดงค่าหลังจากแทนที่ Environment Variable แล้ว แต่ควรระวังเพราะผลลัพธ์อาจแสดงข้อมูลลับ

#ตรวจสอบ Resource

docker stats
docker system df

ดู Event ที่เกิดขึ้นใน Docker:

docker events

#การทำความสะอาด Docker

ตรวจสอบพื้นที่ที่ Docker ใช้งาน:

docker system df

ลบ Container ที่หยุดแล้ว:

docker container prune

ลบ Image ที่ไม่ถูกใช้งาน:

docker image prune

ลบ Network ที่ไม่ถูกใช้งาน:

docker network prune

ลบ Volume ที่ไม่ถูกใช้งาน:

docker volume prune

ลบ Resource ที่ไม่ถูกใช้งาน:

docker system prune

รวมถึง Image ที่ไม่ได้ถูกใช้งานโดย Container:

docker system prune -a

คำสั่งกลุ่ม prune สามารถลบ Resource ของโครงการอื่นได้ ควรอ่านรายการยืนยันและสำรองข้อมูลสำคัญก่อนใช้งาน โดยเฉพาะเมื่อเกี่ยวข้องกับ Volume


#Docker Command Cheat Sheet

#Docker

งาน คำสั่ง
ดูเวอร์ชัน docker --version
ดาวน์โหลด Image docker pull <image>:<tag>
แสดง Image docker images
สร้าง Image docker build -t <name>:<tag> .
รัน Container docker run -d --name <name> <image>
เชื่อมต่อพอร์ต docker run -d -p 8080:80 <image>
แสดง Container ที่ทำงาน docker ps
แสดง Container ทั้งหมด docker ps -a
ดู Log docker logs -f <container>
เข้า Container docker exec -it <container> sh
หยุด Container docker stop <container>
เริ่ม Container docker start <container>
Restart Container docker restart <container>
ลบ Container docker rm <container>
ลบ Image docker rmi <image>
ดูการใช้ทรัพยากร docker stats
ดูการใช้พื้นที่ docker system df

#Docker Compose

งาน คำสั่ง
เริ่มระบบ docker compose up -d
Build และเริ่มระบบ docker compose up -d --build
ดูสถานะ docker compose ps
ดู Log docker compose logs -f
ดู Log เฉพาะ Service docker compose logs -f <service>
เข้า Container docker compose exec <service> sh
หยุดระบบชั่วคราว docker compose stop
เริ่มระบบที่เคยหยุด docker compose start
Restart ระบบ docker compose restart
ตรวจสอบ Configuration docker compose config
ปิดและลบ Container docker compose down
ปิดและลบ Volume docker compose down -v

#ขั้นตอนที่ใช้เป็นประจำในการพัฒนา

เริ่มหรือ Build ระบบ:

docker compose up -d --build

ตรวจสอบสถานะ:

docker compose ps

ติดตาม Log:

docker compose logs -f

เข้าไปตรวจสอบภายใน Service:

docker compose exec web sh

หยุดระบบหลังใช้งาน:

docker compose down

หากแก้ไข Source Code ที่เชื่อมผ่าน Bind Mount โดยทั่วไปไม่จำเป็นต้อง Build Image ใหม่ แต่ถ้าแก้ไข Dockerfile, Dependency หรือขั้นตอน Build ควรรัน:

docker compose up -d --build

#สรุป

Docker ช่วยให้การติดตั้งและรันแอปพลิเคชันมีมาตรฐานเดียวกัน ส่วน Docker Compose ช่วยลดความซับซ้อนของระบบที่ประกอบด้วยหลายบริการ นักพัฒนาสามารถกำหนด Application, Database, Cache และ Worker ไว้ใน compose.yaml แล้วจัดการทั้งระบบผ่านคำสั่งเพียงไม่กี่คำสั่ง

คำสั่งสำคัญที่ควรจดจำ ได้แก่:

docker ps
docker logs -f <container>
docker exec -it <container> sh
docker compose up -d --build
docker compose ps
docker compose logs -f
docker compose down

เมื่อเข้าใจเรื่อง Image, Container, Volume, Network และ Compose แล้ว จะสามารถนำ Docker ไปประยุกต์ใช้กับการพัฒนา การทดสอบ CI/CD และการติดตั้งระบบบนเซิร์ฟเวอร์ได้อย่างมีประสิทธิภาพมากขึ้น