แผนการเรียนรู้
/

สัปดาห์ที่ 3: Introduction to Containerization

การจัดการสภาพแวดล้อมด้วย Docker และการใช้ Modern Python Tools (uv)

หัวข้อการเรียนรู้

  • ปัญหา "It works on my machine"
  • Container vs Virtual Machine
  • Docker Architecture & Workflow
  • Dockerfile & Basic Commands
  • แนะนำ uv: เครื่องมือจัดการ Python Package ยุคใหม่

ปัญหาโลกแตก: "It works on my machine"

ทำไมโค้ดรันได้ที่เครื่องเรา แต่พังเมื่อไปรันที่เครื่องเพื่อนหรือ Server?

สาเหตุ (Causes)

  • OS ต่างกัน (Windows vs Mac vs Linux)
  • Library คนละเวอร์ชัน
  • การตั้งค่า Environment Variables ไม่เหมือนกัน
  • Dependency หาย (Missing Dependencies)

ทางแก้ (Solution)

"ห่อ" (Package) ทุกอย่างที่แอปพลิเคชันต้องใช้รวมไปด้วยกันเลย นั่นคือที่มาของ Container

Containerization คืออะไร?

เทคโนโลยีที่ช่วยให้เราสามารถรันแอปพลิเคชันในสภาพแวดล้อมที่แยกขาดจากกัน (Isolated) โดยใช้ทรัพยากรของ OS ร่วมกัน

  • 📦 Portable: ย้ายไปรันที่ไหนก็ได้ที่รองรับ Container Runtime
  • 🚀 Lightweight: กินทรัพยากรน้อยกว่า VM มาก เพราะไม่ต้องลง OS ใหม่ทั้งตัว
  • Fast: เริ่มทำงาน (Start up) ได้ในระดับวินาที

Virtual Machine vs Container

Virtual Machine (VM)

App A + Libs
Guest OS
Hypervisor
Infrastructure

หนัก (GBs), Boot ช้า, เปลืองทรัพยากรเพราะต้องจำลอง Hardware และ OS

Container (Docker)

App A + Libs
Container Engine
Host OS (Kernel)

เบา (MBs), Boot เร็วมาก, ใช้ Kernel ร่วมกับ Host OS

Docker คืออะไร?

🐳

แพลตฟอร์ม Open Source ยอดนิยมที่สุดสำหรับการสร้าง (Build), ส่งมอบ (Ship), และรัน (Run) แอปพลิเคชันในรูปแบบ Container

"Docker ช่วยให้นักพัฒนาแพ็คแอปฯ และ Dependencies ทั้งหมดใส่กล่องเดียว แล้วเอาไปรันที่ไหนก็ได้"

docker architecture

สถาปัตยกรรมของ Docker

Client-Server Architecture

1. Docker Client

เครื่องมือที่เราใช้สั่งงาน (CLI) เช่นคำสั่ง docker build, docker run

2. Docker Host (Daemon)

ตัวทำงานเบื้องหลัง (dockerd) ทำหน้าที่สร้าง, รัน, และจัดการ Container

3. Registry

ที่เก็บ Image (เช่น Docker Hub) เหมือน GitHub แต่เก็บ Docker Image

Concept 1: Docker Image

💿

"แบบแปลน" (Blueprint)

  • เป็นไฟล์แบบ Read-only แก้ไขไม่ได้หลังจากสร้างแล้ว
  • ประกอบด้วย Code, Runtime, Libraries, Environment Variables และ Config Files
  • สร้างมาจากไฟล์คำสั่งที่ชื่อว่า Dockerfile
  • เปรียบเสมือน: Class ในการเขียนโปรแกรม

Concept 2: Docker Container

📦

"สิ่งที่รันอยู่จริง" (Runnable Instance)

  • เกิดขึ้นเมื่อนำ Image มาสั่ง Run
  • สามารถ Start, Stop, Move, หรือ Delete ได้
  • แยกขาดจากกัน (Isolated) แต่ละ Container มี Filesystem ของตัวเอง
  • เปรียบเสมือน: Object (Instance) ที่ถูกสร้างจาก Class

The Docker Workflow

🔨
Build

Dockerfile → Image

🚢
Ship

Upload to Registry

🏃
Run

Image → Container

เครื่องมือใหม่: รู้จักกับ `uv`

An extremely fast Python package installer and resolver, written in Rust.

ทำไมต้อง uv?

  • 🚀 เร็วมาก: เร็วกว่า pip และ pip-tools 10-100 เท่า
  • 📦 All-in-one: จัดการทั้ง Python version, Virtualenv, และ Dependencies
  • 🔒 Reliable: มีระบบ Lock file ที่แม่นยำ

# สร้าง Project ใหม่

$ uv init my-project

# เพิ่ม Package

$ uv add django

# รันคำสั่ง

$ uv run manage.py runserver

Dockerfile คืออะไร?

ไฟล์ Text ที่บรรจุชุดคำสั่งสำหรับสร้าง Docker Image

FROM python:3.13-slim

WORKDIR /app

COPY . /app

RUN pip install -r requirements.txt

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

Docker จะอ่านบรรทัดเหล่านี้จากบนลงล่างเพื่อสร้าง Image Layer

คำสั่งใน Dockerfile (1/4)

FROM <image>

กำหนด Base Image ที่จะใช้เป็นรากฐาน

FROM python:3.13-slim

WORKDIR <path>

กำหนด Directory ทำงานภายใน Container (เหมือน cd เข้าไป)

WORKDIR /app

คำสั่งใน Dockerfile (2/4)

COPY <src> <dest>

คัดลอกไฟล์จากเครื่องเรา (Host) เข้าไปใน Image

# Copy ไฟล์ requirements.txt เข้าไปก่อน

COPY requirements.txt .

# Copy โค้ดทั้งหมด (. คือ current dir) เข้าไปใน workdir

COPY . .

💡 Tip: ควร Copy ไฟล์ requirements ก่อน code เพื่อใช้ประโยชน์จาก Docker Cache

คำสั่งใน Dockerfile (3/4)

RUN <command>

รันคำสั่ง Linux ในขณะที่กำลัง สร้าง (Build) Image

มักใช้สำหรับติดตั้ง Package หรือ Setup Environment

RUN pip install --no-cache-dir -r requirements.txt

# หรือถ้าใช้ uv

RUN uv sync

คำสั่งใน Dockerfile (4/4)

CMD ["executable", "param1"]

คำสั่งที่จะรันเมื่อ เริ่ม (Start) Container

ต่างจาก RUN ตรงที่ CMD ทำงานตอน Run time, RUN ทำงานตอน Build time

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

⚠️ Dockerfile ควรมี CMD เดียว (ถ้ามีหลายอัน อันสุดท้ายจะถูกใช้)

คำสั่ง Build Image

เปลี่ยน Dockerfile ให้กลายเป็น Image

# รูปแบบ

$ docker build -t <name>:<tag> <path>

# ตัวอย่าง

$ docker build -t mysite:v1 .

  • -t : ตั้งชื่อ Tag ให้ Image (Naming)
  • . : ตำแหน่งของ Dockerfile (Current Directory)

คำสั่ง Run Container

นำ Image มาสร้างเป็น Process ที่ใช้งานได้จริง

$ docker run -d -p 8080:8000 --name myapp mysite:v1

-d (Detach): รันแบบ Background (ไม่ยึดหน้าจอ)
-p (Port): HostPort:ContainerPort (Map พอร์ต)
--name: ตั้งชื่อให้ Container
mysite:v1: ชื่อ Image ที่จะใช้

คำสั่งจัดการพื้นฐาน

docker ps ดู Container ที่กำลังรันอยู่
docker ps -a ดู Container ทั้งหมด (รวมที่หยุดไปแล้ว)
docker stop <id> หยุด Container
docker rm <id> ลบ Container
docker images ดู Image ทั้งหมดในเครื่อง

การส่งค่า Environment Variables

การตั้งค่า Configuration โดยไม่ต้องแก้โค้ด (เช่น SECRET_KEY, DEBUG Mode)

# ใช้ flag -e

$ docker run -e DEBUG=False -e SECRET_KEY=1234 mysite:v1

ทำไมต้องใช้?

เพื่อความปลอดภัย (Security) และความยืดหยุ่น (Flexibility) ทำให้ Image เดียวกัน รันได้ทั้ง Dev, Staging, และ Production แค่เปลี่ยน Env Vars

ไฟล์ .dockerignore

อย่าลืมไฟล์นี้! สำคัญเหมือน .gitignore

ใช้ระบุไฟล์ที่ไม่ต้องการ Copy เข้าไปใน Image เพื่อ:

  • ลดขนาด Image
  • เพิ่มความปลอดภัย (ไม่เอา Secrets เข้าไป)
  • Build เร็วขึ้น

# .dockerignore

__pycache__

*.pyc

.git

.env

venv/

.venv/

ทำไมต้องใช้ uv ใน Docker?

การรวมพลังของ Docker และ uv

⚡ Build Speed

uv ติดตั้ง dependencies ได้เร็วกว่า pip มาก ทำให้ระยะเวลา build docker ลดลง

📦 Smaller Image

จัดการ Virtualenv ได้ดี และมี Cache management ที่มีประสิทธิภาพ

🔒 Deterministic

uv.lock file ช่วยให้มั่นใจว่า Dependencies ใน Container ตรงกับที่เครื่อง Dev เป๊ะๆ

เตรียมพร้อมสำหรับ Lab

🛠️

ภารกิจวันนี้

  1. สร้าง Django Project ด้วย uv
  2. เขียน Dockerfile และรัน Container บนเครื่องตัวเอง
  3. เตรียมไฟล์สำหรับ Deployment
  4. Deploy ขึ้น PythonAnywhere.com

หมายเหตุ: PythonAnywhere ไม่รองรับ Docker Custom Image ในแพ็คเกจฟรี เราจะใช้ uv เพื่อจัดการ Environment และ Deploy แบบ Traditional

Lab Week 3: Modern Django Deployment

สร้างโปรเจกต์ Django ด้วย uv, ทดลอง Dockerize, และ Deploy จริงบน Cloud

Prerequisites (สิ่งที่ต้องมี)

  • VS Code & Git
  • Docker Desktop (ติดตั้งแล้ว)
  • บัญชี PythonAnywhere.com
  • บัญชี GitHub

Step 1: Init Project with uv

เปิด Terminal ใน VS Code แล้วทำตามขั้นตอน

# 1. ติดตั้ง uv (ถ้ายังไม่มี)

pip install uv

# 2. สร้างโปรเจกต์ใหม่

uv init week3_lab

cd week3_lab

# 3. เพิ่ม Django (uv จะสร้าง venv ให้เอง)

uv add django

Step 2: Create Django App

# 1. สร้าง Django Project ชื่อ mysite

uv run django-admin startproject mysite .

*อย่าลืมจุด (.) ข้างหลัง เพื่อสร้างใน folder ปัจจุบัน

# 2. ทดลองรัน (Local)

uv run manage.py migrate

uv run manage.py runserver

ตรวจสอบที่ http://127.0.0.1:8000 ว่าเว็บขึ้นหรือไม่

Step 3: Dockerize (Local Test)

สร้างไฟล์ชื่อ Dockerfile (ไม่มีนามสกุล) ในโฟลเดอร์หลัก:

FROM python:3.12-slim

# ติดตั้ง uv ใน image

COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv

WORKDIR /app

# Copy ไฟล์ config ของ uv

COPY pyproject.toml uv.lock ./

# Install dependencies

RUN uv sync --frozen

# Copy โค้ด

COPY . .

# รัน server

CMD ["uv", "run", "manage.py", "runserver", "0.0.0.0:8000"]

Step 4: Build & Run Container

# 1. Build Image

docker build -t django-uv-lab .

# 2. Run Container

docker run -p 8000:8000 django-uv-lab

✅ ถ้าเข้า localhost:8000 ได้ แสดงว่า Docker ทำงานถูกต้อง

กด Ctrl+C ใน terminal เพื่อหยุด Container

Step 5: Prepare for PythonAnywhere

PythonAnywhere ไม่รองรับ Docker (Free Tier) เราต้อง Export requirements เพื่อไปใช้กับ pip แบบดั้งเดิม

# 1. Export requirements.txt ด้วย uv

uv export > requirements.txt

# 2. แก้ไข mysite/settings.py

ALLOWED_HOSTS = ['*'] # หรือใส่ชื่อ domain ของ pythonanywhere

# 3. Push ขึ้น GitHub (Repo ใหม่)

git init

git add .

git commit -m "Ready for deploy"

git push ...

Step 6: Deploy on Cloud

1. Bash Console: Clone Repo ของคุณ git clone https://github.com/User/Repo.git
2. Setup Venv: สร้าง Virtualenv และลงของ mkvirtualenv --python=/usr/bin/python3.10 myenv pip install -r requirements.txt
3. Web Tab:
  • Source code: /home/username/repo_name
  • Virtualenv: /home/username/.virtualenvs/myenv
  • WSGI Config: แก้ไฟล์ให้ชี้ไปที่ mysite.settings

การส่งงาน (Submission)

ส่ง 2 ลิงก์:

🐙 GitHub Repository (ต้องมี Dockerfile และ requirements.txt)
☁️ PythonAnywhere URL (เว็บต้องเข้าใช้งานได้จริง)

รู้จักกับ Podman (Pod Manager)

Podman คือ Container Engine แบบ Open Source ที่ไม่มี Daemon (Daemonless) และเน้นความปลอดภัย

จุดเด่นสำคัญ

  • Daemonless: ไม่ต้องมี Service ตัวกลาง (Daemon) รอรับคำสั่ง ลดจุดที่อาจเกิดความล้มเหลว (Single Point of Failure) [2], [5]
  • Rootless by Default: รัน Container ได้โดยไม่ต้องใช้สิทธิ์ Root ของเครื่อง ช่วยเพิ่มความปลอดภัยสูงสุด [6], [7]
  • OCI Compliant: รองรับมาตรฐาน Open Container Initiative ทำให้ใช้ Image ร่วมกับ Docker ได้ทันที [8]
  • Pods: รองรับแนวคิด "Pod" (กลุ่มของ Container) แบบเดียวกับ Kubernetes [9]

https://podman.io/

สถาปัตยกรรม: Docker vs Podman

Docker (Client-Server)

ใช้ CLI ส่งคำสั่งไปหา Docker Daemon (dockerd) ที่รันเป็น Background Process ด้วยสิทธิ์ Root

CLI ➔ REST API ➔ Daemon (Root) ➔ Container

⚠️ ถ้า Daemon ล่ม Container ทั้งหมดจะดับไปด้วย [10]

Podman (Fork/Exec)

ทำงานแบบ Process ปกติของ Linux (Direct Process) ไม่ต้องผ่าน Daemon ตัวกลาง

CLI ➔ Process (User) ➔ Container

✅ ปลอดภัยกว่า และแยกการทำงานอิสระต่อกัน [11]

Podman Desktop คืออะไร?

เครื่องมือจัดการ Container แบบ GUI (Graphical User Interface) ที่ใช้งานฟรีและ Open Source

คุณสมบัติหลัก [3]

  • 🖥️ จัดการง่าย: ดูแล Containers, Images, Volumes และ Pods ผ่านหน้าจอ UI
  • ☸️ Kubernetes Ready: สามารถสร้าง YAML file จาก Container เพื่อนำไป Deploy บน Kubernetes ได้ทันที
  • 🔄 Docker Compatible: ทำงานร่วมกับ Docker Extension และ Docker CLI ได้
💸 ฟรี!

ทางเลือกทดแทน Docker Desktop (ที่เริ่มมีการคิดค่าบริการสำหรับองค์กรขนาดใหญ่) [12]

รองรับ Windows, macOS, Linux

การติดตั้ง (Installation)

🪟 Windows (Requirements) [13], [14]

  • ต้องเปิดใช้งาน WSL2 (Windows Subsystem for Linux)
  • Windows 10 Build 19043+ หรือ Windows 11
  • RAM ขั้นต่ำ 6 GB
  • วิธีติดตั้ง: ดาวน์โหลด Installer จาก podman-desktop.io โปรแกรมจะช่วยติดตั้ง WSL2 ให้

🍎 macOS & 🐧 Linux

  • macOS: ติดตั้งผ่าน brew: brew install podman-desktop หรือโหลด dmg file
  • Linux: ติดตั้งผ่าน Flatpak หรือ Binary โดยตรง

ย้ายจาก Docker มา Podman ยากไหม?

"แทบไม่ต้องเปลี่ยนอะไรเลย"

# สร้าง Alias เพื่อใช้คำสั่ง docker เหมือนเดิม [15]

$ alias docker=podman


# คำสั่งใช้งานเหมือนกัน 99%

$ docker run -d -p 80:80 nginx

➔ $ podman run -d -p 80:80 nginx

Dockerfile: ใช้ไฟล์เดิมได้เลย ไม่ต้องแก้โค้ด [16]
Docker Compose: ใช้ podman-compose ทดแทน หรือใช้ฟีเจอร์ Pods ของ Podman [17]

ฟีเจอร์พิเศษ: Pods

Podman สามารถจัดการ "Pod" ได้เหมือน Kubernetes (ซึ่ง Docker ปกติทำไม่ได้)

Pod A (Shared Namespace)

Container 1 (Web)
Container 2 (DB)

Container ใน Pod เดียวกัน คุยกันผ่าน localhost ได้เลย!

# สร้าง Pod ว่างๆ

$ podman pod create --name my-pod -p 8080:80

# รัน Container เข้าไปใน Pod นั้น

$ podman run -dt --pod my-pod nginx

Lab: ติดตั้งและใช้งาน Podman

ภารกิจ (Mission)

  1. ดาวน์โหลดและติดตั้ง Podman Desktop
  2. ทำการ Initialize Podman Machine (ในหน้า Settings)
  3. ทดลองรัน Container ผ่าน GUI:
    • Pull image: docker.io/library/httpd [18]
    • Start Container และ map port 8080:80
  4. ทดลองสร้างไฟล์ Kubernetes YAML จาก Container ที่รันอยู่ (ฟีเจอร์เด็ดของ Podman)

*หมายเหตุ: บน Windows การรัน Podman ครั้งแรกอาจใช้เวลาสักพักในการสร้าง WSL2 VM