ApexHuasคู่มือช่างเว็บ GitHub repo

บทที่ 9 — Docker: ห่อเว็บให้ยกไปรันที่ไหนก็ได้

ปัญหาที่ Docker มาแก้

เว็บที่รันได้ในเครื่องคุณ ไม่ได้แปลว่าจะรันได้บน server เพราะ server อาจมี Node.js คนละเวอร์ชัน ไม่มี library ที่คุณติดตั้งไว้ หรือตั้งค่าระบบไว้คนละแบบ

Docker แก้ด้วยการห่อ ทุกอย่างที่ต้องใช้รัน ไว้ในกล่องเดียว — โค้ด + Node.js + library + การตั้งค่า ยกกล่องนี้ไปวางที่ไหนก็ทำงานเหมือนกันเป๊ะ

สองคำที่ต้องแยกให้ออก

Image กับ Container ต่างกันยังไง

Image = แม่พิมพ์

  • ไฟล์ก้อนหนึ่ง ไม่ทำงานเอง
  • สร้างครั้งเดียว ใช้ซ้ำได้ตลอด
  • ก๊อปไปเก็บ/ส่งต่อได้
  • ของโปรเจกต์นี้หนัก 85 MB
  • เหมือนไฟล์ติดตั้งโปรแกรม

Container = ของที่กำลังรัน

  • เกิดจากการเอา image มารัน
  • จาก image เดียวเปิดกี่ container ก็ได้
  • ปิด/เปิด/ลบได้ ไม่กระทบ image
  • ของโปรเจกต์นี้ชื่อ apexhuas-app-1
  • เหมือนโปรแกรมที่เปิดอยู่

การ deploy เวอร์ชันใหม่ = สร้าง image ใหม่ → หยุด container เก่า → เปิด container ใหม่จาก image นั้น

Dockerfile: สูตรสร้าง image

Dockerfile คือไฟล์สูตรที่บอกว่าจะห่อยังไง ของโปรเจกต์นี้ใช้เทคนิค multi-stage คือแบ่งเป็น 3 ช่วง แล้วเก็บเฉพาะของที่จำเป็นจริงลงกล่องสุดท้าย

Dockerfile 3 ช่วงของโปรเจกต์นี้

1. deps

ก๊อปแค่ package.json กับ package-lock.json เข้ามาแล้วติดตั้ง — แยกขั้นนี้ออกมาเพราะถ้าโค้ดเปลี่ยนแต่ library ไม่เปลี่ยน Docker จะข้ามขั้นนี้ ทำให้ build ครั้งต่อไปเร็วมาก

FROM node:24-alpine AS deps
COPY package.json package-lock.json ./
RUN npm ci
1 / 3

ถ้าไม่แบ่ง stage กล่องจะติดทั้ง source code และเครื่องมือ build ไปด้วย ใหญ่กว่านี้หลายเท่า

จุดที่คนมักพลาด

รายละเอียดใน Dockerfile ที่มีเหตุผลอยู่เบื้องหลัง (คลิกดู)

คลิกชั้นใดก็ได้เพื่อดูรายละเอียด

คำสั่ง Docker ที่ได้ใช้จริง

docker build -t apexhuas:uat .        # สร้าง image จาก Dockerfile ในโฟลเดอร์นี้
docker image ls                        # ดู image ที่มีในเครื่อง
docker ps                              # ดู container ที่กำลังรัน
docker logs <ชื่อ container>            # ดู log ว่าเว็บพ่นอะไรออกมา
docker compose up -d                   # เปิดทุก service ตามไฟล์ compose.yaml
docker compose pull && docker compose up -d   # ดึงเวอร์ชันใหม่มาแล้วรีสตาร์ท

compose.yaml คือไฟล์ที่บอกว่า "ระบบนี้ประกอบด้วย container อะไรบ้าง" ของเราบน server มี 2 ตัวคือเว็บกับ Caddy (ตัวรับ request) — รายละเอียดบทหน้า

registry: โกดังเก็บ image

สร้าง image เสร็จแล้วจะส่งไป server ยังไง? คำตอบคือฝากไว้ที่ registry แล้วให้ server ไปดึงเอา

โปรเจกต์นี้ใช้ GHCR (GitHub Container Registry) ซึ่งมาพร้อม GitHub อยู่แล้ว

image เดินทางยังไง (คลิกดูแต่ละจุด)

GitHub Actions

GHCR

Server

คลิกกล่องด้านบนเพื่อดูคำอธิบาย

เช็คความเข้าใจ

บทหน้า: server จริง โดเมน และ HTTPS — ตามรอย request หนึ่งอันตั้งแต่คนพิมพ์ URL จนได้หน้าเว็บ