Deploy + Maintain
งานบนเครื่องของคุณ ≠ งานที่คนอื่นใช้ได้ · สัปดาห์นี้ครอบคลุม 5 deployment targets — Cloud · Desktop · 📱 Mobile · 🤖 IoT/Edge · Hybrid · เลือก target ผิด = user ไม่ใช้ · เลือกถูก = ของ "อยู่กับ user ตลอด"
เป้าหมายสัปดาห์นี้
- เลือก deployment target ที่ตรงกับ user (เพื่อนใช้มือถือ vs IoT lab)
- ☁️ Deploy Cloud (Streamlit, Cloud Run, Render)
- 💻 Package เป็น Desktop App (.exe) ด้วย PyInstaller
- 📱 Make mobile-accessible — PWA, LINE bot, mobile-responsive web
- 🤖 Deploy ลง IoT / Edge — Raspberry Pi, ESP32 (MicroPython)
- 📊 Monitor production — logs, errors, uptime, cost
- 💰 Cost management — free tier, budget alert, kill switch
- เลือก Local LLM vs Cloud LLM
- ใช้ Git workflow + CI/CD ดูแลระบบในระยะยาว
🗺 Deployment Decision — เลือก target จาก user
ก่อนเลือก tech · ตอบคำถามนี้ก่อน: "user ของฉันใช้อะไรอยู่?"
ใช้อะไร?"] user --> q1{ต้องใช้
ออฟไลน์?} q1 -->|Yes| q2{อุปกรณ์?} q1 -->|No| q3{อุปกรณ์?} q2 -->|PC| desk["💻 Desktop App
PyInstaller .exe"] q2 -->|Phone| pwa["📱 PWA
(installable web)"] q2 -->|Sensor / Motor| iot["🤖 IoT / Edge
Raspberry Pi · ESP32"] q3 -->|PC| cloud["☁️ Cloud Web
Streamlit · Flask"] q3 -->|Phone| mobile["📱 Mobile Web
+ LINE bot"] q3 -->|ทั้งคู่| hybrid["🔄 Hybrid
Cloud + LINE bot"] classDef question fill:#3b2962,stroke:#8b5cf6,color:#fff classDef desk fill:#1e3a5f,stroke:#3776ab,color:#fff classDef mob fill:#0d3f3a,stroke:#2dd4bf,color:#fff classDef iot fill:#5c2618,stroke:#ff7a18,color:#fff classDef cloud fill:#064e3b,stroke:#34d399,color:#fff class user,q1,q2,q3 question class desk desk class pwa,mobile,hybrid mob class iot iot class cloud cloud
🎯 5 Deployment Targets — สรุป
| Target | เหมาะกับ | ราคา | ยาก | User เห็นแบบ |
|---|---|---|---|---|
| ☁️ Cloud Web | app สาธารณะ · dashboard · API | ฟรี-$5/เดือน | ⭐⭐ | browser URL |
| 💻 Desktop App | tool ออฟไลน์ · ใช้ส่วนตัว · sensitive data | ฟรี | ⭐⭐ | .exe icon บน desktop |
| 📱 Mobile (PWA / LINE / Web) | user อยู่บนมือถือ | ฟรี | ⭐⭐ | icon บน home screen / LINE chat |
| 🤖 IoT / Edge | เซ็นเซอร์ · controller · ห่างจาก network | ค่า hardware | ⭐⭐⭐⭐ | กล่องอยู่ในที่ |
| 🔄 Hybrid | มี user หลาย channel | ผสม | ⭐⭐⭐⭐ | หลายแบบพร้อมกัน |
📊 ทางเลือก 1: Streamlit Cloud (ง่ายที่สุด)
Streamlit = library ที่ทำให้ Python กลายเป็น web app ใน 50 บรรทัด · เหมาะมากสำหรับนักศึกษา
# app.py
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
st.title("📊 PM2.5 Dashboard")
df = pd.read_csv("data.csv")
st.dataframe(df.tail(10))
city = st.selectbox("เลือกเมือง", df["city"].unique())
data = df[df["city"] == city]
fig, ax = plt.subplots()
ax.plot(data["date"], data["pm25"])
ax.set_title(f"PM2.5 — {city}")
st.pyplot(fig)
รัน local: streamlit run app.py → เปิดที่ localhost:8501
Deploy ขึ้น Streamlit Cloud
- push code ขึ้น GitHub (public repo)
- ไปที่ share.streamlit.io
- Login ด้วย GitHub
- เลือก repo + ไฟล์
app.py→ Deploy - รอ 2-3 นาที → ได้ URL ของตัวเองเช่น
username-app.streamlit.app
🐳 ทางเลือก 2: Cloud Run (สำหรับ API)
Cloud Run = Google service ที่รัน Docker container · scale ตาม traffic · pay-per-request
เตรียม Dockerfile
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "main.py"]
Deploy steps
- ติดตั้ง gcloud CLI (Google Cloud SDK)
gcloud auth login+gcloud config set project YOUR_PROJECT- ใน folder project:
gcloud run deploy - ตอบคำถาม (region, port, allow unauthenticated)
- ได้ URL เช่น
https://my-app-xxxxx.asia-southeast1.run.app
💻 ทางเลือก 3: Desktop App (.exe)
เปลี่ยน Python script เป็น .exe ที่ double-click รันได้ · ไม่ต้องลง Python
# ติดตั้ง
pip install pyinstaller
# build
pyinstaller --onefile --windowed app.py
# ผลลัพธ์ใน dist/app.exe
| Flag | ทำอะไร |
|---|---|
--onefile | รวมทุกอย่างเป็น .exe เดียว |
--windowed | ไม่เปิด terminal (เหมาะกับ GUI) |
--icon=app.ico | ใส่ icon |
--add-data "data.csv;." | รวม data file |
GUI Library
- tkinter — built-in, ง่าย, ไม่สวยมาก
- customtkinter — สวยกว่า, modern
- PyQt6 / PySide6 — แอป production, learning curve สูง
- Streamlit / Gradio — web-based, ทำง่ายแต่ต้อง open browser
📱 ทางเลือก 4: Mobile — user อยู่บนมือถือ
เพื่อนคุณ "อยู่กับมือถือทั้งวัน" · ของที่ต้องเปิด laptop จะถูกใช้ "แค่ตอน demo" · ของที่อยู่บนมือถือจะใช้ "จริง" · นี่คือ 5 ทางที่ทำได้ โดยไม่ต้องเขียน Swift / Kotlin
📱 5 ทางลง Mobile
| วิธี | ทำยังไง | เหมาะกับ | ความยาก |
|---|---|---|---|
| 1. Mobile-responsive Web | Streamlit / Flask + CSS media queries | data dashboard, form | ⭐ |
| 2. PWA (Progressive Web App) | Web + manifest.json + service worker → "Install" บน home screen |
web app ที่ user อยากเปิดบ่อย | ⭐⭐ |
| 3. LINE Bot | LINE Messaging API (W12) — chat = UI | notifications, simple workflows, แจ้งเตือน | ⭐⭐ |
| 4. Telegram Bot | python-telegram-bot library |
กลุ่ม international, automation | ⭐⭐ |
| 5. Native (BeeWare/Kivy) | Python → Android/iOS native bundle | app ที่ต้อง access camera/sensor | ⭐⭐⭐⭐ |
📲 วิธี 1: Mobile-Responsive Streamlit
# Streamlit auto-responsive อยู่แล้ว · เพิ่ม config สำหรับ phone:
# .streamlit/config.toml
[theme]
primaryColor = "#3776ab"
base = "light"
[browser]
gatherUsageStats = false
# app.py
import streamlit as st
st.set_page_config(
page_title="My App",
page_icon="🐰",
layout="centered", # ✅ centered = phone-friendly · wide = desktop-only
initial_sidebar_state="collapsed", # ✅ ซ่อน sidebar บนมือถือ
)
# ใช้ st.columns + responsive — ดูในมือถือเสมอตอนทดสอบ
📲 วิธี 2: PWA — Install บน Home Screen
เปลี่ยน web app ให้ user "ติดตั้ง" ได้บนมือถือ — เห็น icon เหมือน native app
<!-- index.html (ถ้าใช้ Flask) -->
<link rel="manifest" href="/static/manifest.json">
<meta name="theme-color" content="#3776ab">
<link rel="apple-touch-icon" href="/static/icon-192.png">
// static/manifest.json
{
"name": "Smart Lab Monitor",
"short_name": "Lab Mon",
"start_url": "/",
"display": "standalone", // ทำให้ดูเหมือน native app
"background_color": "#0b1020",
"theme_color": "#3776ab",
"icons": [
{"src": "/static/icon-192.png", "sizes": "192x192", "type": "image/png"},
{"src": "/static/icon-512.png", "sizes": "512x512", "type": "image/png"}
]
}
หลังจาก deploy + เปิดบนมือถือ → Safari/Chrome → "Add to Home Screen" → ได้ icon บน phone
📲 วิธี 3: LINE Bot — UI คือ Chat
ทบทวนจาก W12 · นี่คือ "the Thai-friendly mobile app" · ทุกคนมี LINE อยู่แล้ว
📲 วิธี 5: BeeWare / Kivy (Advanced)
ถ้าจำเป็นต้อง "native มือถือจริง ๆ" (เช่น ต้อง access camera ในแบบเฉพาะ)
# pip install briefcase
briefcase new # สร้าง project
briefcase create # สร้าง bundle สำหรับ Android
briefcase build # build .apk
briefcase run android # ทดสอบ
# → output: .apk ที่ลงในมือถือได้
# Kivy ก็ทำได้คล้ายกัน — ใช้ buildozer
# แต่ทั้งคู่ learning curve สูง · ทำเฉพาะถ้าจำเป็น
🤖 ทางเลือก 5: IoT / Edge — Deploy ลงอุปกรณ์
สำหรับ engineering students — "deploy ลงเซ็นเซอร์ / motor / controller" · ไม่ใช่ทุก app อยู่บน cloud · บางอันต้องอยู่ "ในที่" — แท่นบนโรงงาน · ในห้อง lab · บน drone
🔌 4 ระดับของ IoT / Edge
| ระดับ | อุปกรณ์ | Python ที่ใช้ | เหมาะกับ |
|---|---|---|---|
| 1. Microcontroller | ESP32, RP2040 (Pico) | MicroPython — Python subset · จำกัด RAM/ROM | เซ็นเซอร์เดี่ยว · LED · simple control · battery-powered |
| 2. Single-Board Computer | Raspberry Pi 4/5, Orange Pi | Python เต็ม + Linux | edge gateway · multi-sensor · camera · lightweight server |
| 3. Edge AI | Coral TPU, Jetson Nano | Python + TensorFlow Lite | vision · NLP บน edge · real-time inference |
| 4. Industrial PLC | FX5U, Siemens S7 | ไม่ใช้ Python · ใช้ ladder logic + Modbus | safety-critical · factory · จาก W12 (Modbus API) |
🥧 Raspberry Pi — Full Linux + Python
Pi 5 ($80) = mini computer · ติดตั้ง Python · เซ็นเซอร์ผ่าน GPIO · run Flask · ทำได้ทุกอย่างที่ Cloud Run ทำได้
# 1. Flash Raspberry Pi OS
# 2. SSH เข้า
ssh pi@192.168.1.10
# 3. Setup Python project
git clone https://github.com/you/lab-monitor.git
cd lab-monitor
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# 4. รัน background ด้วย systemd service
sudo nano /etc/systemd/system/lab-monitor.service
# /etc/systemd/system/lab-monitor.service
[Unit]
Description=Lab Monitor
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/lab-monitor
ExecStart=/home/pi/lab-monitor/.venv/bin/python main.py
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
# Enable + start
sudo systemctl daemon-reload
sudo systemctl enable lab-monitor
sudo systemctl start lab-monitor
# Check status
sudo systemctl status lab-monitor
sudo journalctl -u lab-monitor -f # ดู log สด
🔧 MicroPython บน ESP32 — Python บน Microcontroller
ESP32 ($5) รัน Python ได้ผ่าน MicroPython · เซ็นเซอร์ · WiFi · ไม่ต้องมี Linux
# main.py (รันอัตโนมัติเมื่อ ESP32 boot)
import network
import time
from machine import Pin, ADC
import urequests as requests # MicroPython มี subset
# 1) WiFi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("MyWiFi", "password")
while not wlan.isconnected():
time.sleep(0.5)
print("Connected:", wlan.ifconfig())
# 2) อ่านเซ็นเซอร์ temperature (LM35) ผ่าน ADC
sensor = ADC(Pin(34))
sensor.atten(ADC.ATTN_11DB)
def read_temp():
voltage = sensor.read() * 3.3 / 4095
return voltage * 100 # LM35: 10mV/°C
# 3) Loop: อ่าน + ส่งขึ้น cloud
while True:
t = read_temp()
print(f"Temp: {t:.1f}°C")
try:
requests.post("https://my-api.run.app/temp", json={"temp": t})
except Exception as e:
print("Send fail:", e)
time.sleep(30)
💡 Upload: ใช้ ampy หรือ Thonny IDE · 1 ครั้งแล้วทำงานตลอด — battery + solar = ยืนได้เป็นเดือน
📡 MQTT — Protocol มาตรฐาน IoT
Sensor → broker → dashboard · ใช้แทน HTTP เมื่อมีเซ็นเซอร์ หลายตัว
# pip install paho-mqtt
import paho.mqtt.client as mqtt
# Publish (ESP32 ส่งค่า)
client = mqtt.Client()
client.connect("broker.hivemq.com", 1883)
client.publish("lab/temp/sensor1", "25.3")
# Subscribe (Cloud server รับค่า)
def on_message(client, userdata, msg):
print(f"{msg.topic}: {msg.payload.decode()}")
sub = mqtt.Client()
sub.connect("broker.hivemq.com", 1883)
sub.subscribe("lab/temp/+") # + = wildcard ทุก sensor
sub.on_message = on_message
sub.loop_forever()
🛡 IoT Production Checklist
- ✅ Auto-restart เมื่อพัง — systemd บน Pi / watchdog บน ESP32
- ✅ Auto-reconnect WiFi เมื่อ network ตก
- ✅ Local logging — เก็บ log ในเครื่อง · ส่งขึ้น cloud เมื่อมี internet
- ✅ OTA (Over-The-Air) update — อัพเดต code โดยไม่ต้องต่อสาย
- ✅ Health check endpoint — cloud check ว่า device ยังมีชีวิต
- ✅ Power management — sleep mode สำหรับ battery
🧠 Local LLM vs Cloud LLM
หลังจาก 14 สัปดาห์ที่ใช้ AI เป็นเครื่องมือ · ในงานจริงต้องตัดสินใจ: เรียก API หรือรัน LLM ในเครื่องเอง?
☁️ Cloud LLM
Claude API, OpenAI API, Gemini API
- ✅ เก่งที่สุด (GPT-4, Claude Opus)
- ✅ ไม่ต้องมี GPU
- ✅ scale ได้ทันที
- ❌ จ่ายตาม token (~$0.001-0.03/req)
- ❌ ส่งข้อมูล "นอกองค์กร"
- ❌ ต้อง internet
- ❌ rate limit
🖥️ Local LLM (Ollama)
Llama 3, Qwen, Phi, Mistral
- ✅ ฟรี · ไม่มี per-request cost
- ✅ ข้อมูล "ไม่ออกจากเครื่อง"
- ✅ ไม่ต้อง internet (หลัง download)
- ✅ ไม่มี rate limit
- ❌ ต้องการ RAM ≥ 16 GB + GPU 8GB+ ดี
- ❌ ความสามารถน้อยกว่า GPT-4/Claude
- ❌ ช้ากว่าเมื่อใช้แค่ CPU
ใช้ Ollama (Local LLM)
# ติดตั้ง Ollama (Win/Mac/Linux): ollama.com
# Download model
ollama pull llama3.2:3b # 2 GB, ใช้ใน CPU ได้
ollama pull qwen2.5:7b # 4 GB, ต้องการ GPU
# เรียกจาก Python
pip install ollama
import ollama
response = ollama.chat(model="llama3.2:3b", messages=[
{"role": "user", "content": "อธิบาย if statement ในภาษาไทยให้คนเริ่มต้น"}
])
print(response["message"]["content"])
ใช้ Cloud LLM (Claude API)
import os
from anthropic import Anthropic
client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
msg = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content": "อธิบาย if statement..."}]
)
print(msg.content[0].text)
เลือกอันไหน?
| สถานการณ์ | เลือก |
|---|---|
| Final Project demo | Cloud LLM (เร็ว · เก่ง) |
| ระบบเก็บข้อมูลส่วนตัว (health, finance) | Local LLM (privacy) |
| App ที่รันบน Raspberry Pi / Edge | Local LLM (offline) |
| Batch processing 10,000 รายการ | Local LLM (cost) |
| ต้องการความเข้าใจสูง / reasoning | Cloud LLM (Claude/GPT) |
| Auto-grading นักศึกษา 200 คน | Local LLM (cost + privacy) |
📊 Monitoring + Crash Reporting — รู้ก่อน user บ่น
Deploy แล้ว "ไม่จบ" · ของพังกลางคืน · ของเร็วลง · ของกินเงิน · ต้องมี ตา ดู · ไม่ใช่ "รอ user มาบ่นใน LINE"
🩺 4 อย่างที่ต้อง Monitor
| เรื่อง | ทำไม | เครื่องมือฟรี |
|---|---|---|
| 1. Uptime — ของยังเปิดอยู่มั้ย? | ของพังตอนตี 2 · ตื่นมา 8 โมง = user เจอครั้งแรก | UptimeRobot · ฟรี 50 monitor |
| 2. Errors — มี exception มั้ย? | "ทำงานได้" ≠ "ไม่มี bug" · user 1 คนเจอ error 10 คน | Sentry · ฟรี 5K errors/เดือน |
| 3. Performance — ช้ามั้ย? | app ช้า 3 วินาที = user ใช้ครั้งเดียวแล้วไม่กลับ | Cloud Run dashboard · Streamlit Cloud metrics |
| 4. Usage — ใครใช้ ใช้ตรงไหน? | เพื่อปรับ feature ที่ใช้จริง | Plausible · privacy-friendly |
🛡 Sentry — Crash Reporter (Free 5K errors/month)
# pip install sentry-sdk
import sentry_sdk
import os
sentry_sdk.init(
dsn=os.getenv("SENTRY_DSN"),
traces_sample_rate=0.1, # 10% สำหรับ performance
)
# หลังจากนี้ทุก exception ที่ไม่ catch จะถูกส่งไป Sentry
def my_function():
try:
risky_operation()
except Exception as e:
sentry_sdk.capture_exception(e) # ส่งให้ Sentry
raise # ยัง propagate เหมือนเดิม
# Sentry dashboard:
# - กราฟ error rate
# - stack trace + user context
# - email/Slack alert เมื่อ spike
💓 UptimeRobot — Heartbeat / Health Check
UptimeRobot ping URL ของคุณทุก 5 นาที · ถ้าตอบ > 30 วินาที หรือ status ≠ 200 → email/SMS เตือน
# เพิ่ม endpoint /health ใน Flask
@app.route("/health")
def health():
# ตรวจ subsystem ทุกตัวที่สำคัญ
db_ok = check_database()
api_ok = check_external_api()
if db_ok and api_ok:
return {"status": "ok", "db": "ok", "api": "ok"}, 200
else:
return {"status": "degraded", "db": db_ok, "api": api_ok}, 503
📝 Structured Logging — Log เป็น JSON
Log แบบ "ข้อความ" ค้นยาก · Log แบบ JSON = search ได้
import json, logging, sys
from datetime import datetime
class JSONFormatter(logging.Formatter):
def format(self, record):
return json.dumps({
"time": datetime.utcnow().isoformat() + "Z",
"level": record.levelname,
"msg": record.getMessage(),
"module": record.module,
**getattr(record, "extra", {}),
})
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(JSONFormatter())
log = logging.getLogger()
log.addHandler(handler)
log.setLevel(logging.INFO)
log.info("user_action", extra={"extra": {"user_id": "U123", "action": "login"}})
# → {"time":"2026-05-15T...","level":"INFO","msg":"user_action","user_id":"U123","action":"login"}
# Cloud Run / Google Cloud Logging รู้จัก format นี้ · search ตาม field ได้
💰 Cost Management — ไม่ให้ "bill ช็อก"
ตำนานของ developer: "loop ผิด → AWS bill $5000 ใน 1 คืน" · เรื่องจริง · เกิดทุกปีกับนักศึกษา · ตั้งกฎ "safety net" ตั้งแต่วันแรก
🎯 Free Tier — รู้ขีดจำกัด
| Service | Free Tier | เมื่อเกิน |
|---|---|---|
| Streamlit Cloud | 1 app · public | ไม่มี paid tier · ต้องย้าย |
| Cloud Run | 2M req/เดือน · 180K vCPU-sec | $0.40/M req หลังจากนั้น |
| Render Web | Free instance · sleep หลัง 15 นาที | $7/เดือน เพื่อ always-on |
| Anthropic Claude | $5 credit แรก | $0.25-$15 / M tokens (Haiku-Opus) |
| OpenAI | $5 credit แรก | $0.15-$10 / M tokens |
| IQAir API | 10K calls/เดือน | $$ ต้องอัพเกรด |
| GitHub Actions | 2000 minutes/เดือน (private) | $0.008/นาที |
| Sentry | 5K errors/เดือน | $26/เดือน |
🚨 Budget Alert — ตั้งก่อน Deploy ทุกครั้ง
| Service | วิธีตั้ง alert |
|---|---|
| Google Cloud | Console → Billing → Budgets → "$5 alert at 50%, 90%, 100%" |
| Anthropic | console.anthropic.com → Settings → Limits → Monthly spend cap |
| OpenAI | platform.openai.com → Billing → Usage limits |
| AWS / Azure | Billing alerts ใน console (อย่าใช้ AWS ถ้าไม่ได้บังคับ — bill surprises เกิดบ่อย) |
- Recursive API call — function เรียกตัวเอง · 1 ล้าน calls ใน 1 ชั่วโมง
- Infinite loop on LLM — for loop ไม่ break · streaming + cost = $1000/ชม.
- Open public endpoint — bot scraper เจอ → ping ทุก 100ms · เกิน rate limit · เกิน bill
--max-instances=10 ใน Cloud Run · rate limit ใน Flask
🛑 Kill Switch — ปิดเร็วเมื่อเกิดเหตุ
# Cloud Run — ปิดทันที
gcloud run services update my-service --max-instances=0
# หรือลบทั้ง service
gcloud run services delete my-service
# Anthropic — disable key ที่ console
# https://console.anthropic.com → API Keys → Delete
# GitHub Actions — disable workflow
# Settings → Actions → "Disable Actions for this repository"
🌳 Git Workflow ขั้นพื้นฐาน
คำสั่งที่ใช้ทุกวัน
git status # ดูสถานะ
git add . # stage ทุกอย่าง
git commit -m "message" # commit
git push # ส่งขึ้น GitHub
git pull # ดึงล่าสุด
git log --oneline # ดูประวัติย่อ
git diff # ดูที่เปลี่ยน
git branch feature-x # สร้าง branch ใหม่
git checkout feature-x # สลับไป branch
git checkout -b feature-x # สร้าง + สลับ
# rollback
git reset --hard HEAD # ทิ้งการเปลี่ยนทั้งหมด
git revert <hash> # ทำ commit ใหม่ที่ undo อันเก่า
Pull Request Workflow (สำหรับทีม)
git checkout -b feature-grade-export- แก้ code + commit หลายครั้ง
git push -u origin feature-grade-export- เปิด GitHub → สร้าง Pull Request ขอ merge เข้า main
- เพื่อน/อาจารย์ review · comment
- แก้ตาม feedback · push เพิ่ม
- กด Merge เมื่อทุกคนยอมรับ
🔁 CI/CD — GitHub Actions
"ทุก push → รัน test อัตโนมัติ" · ฟรีบน public repo
สร้าง .github/workflows/test.yml:
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install -r requirements.txt
- run: pytest
หลังจากนี้ทุก push จะเห็น ✅ หรือ ❌ บน GitHub
📈 Maintenance — ระบบที่อยู่ได้นาน
Checklist ก่อน "ปล่อย" ระบบให้คนอื่นใช้
- ✅ README ครบ — install + usage + screenshot
- ✅ requirements.txt มี version
- ✅ .env.example สำหรับ secret
- ✅ tests pass
- ✅ มี error handling สำหรับ network / file
- ✅ log ทุก action สำคัญ
- ✅ backup data ทุกวัน
- ✅ มี changelog เริ่มต้น
Changelog template
# Changelog
## [Unreleased]
- ...
## [1.1.0] - 2026-05-20
### Added
- LINE notification เมื่อ PM2.5 > 100
- /status endpoint
### Changed
- เปลี่ยน DB จาก SQLite เป็น PostgreSQL
### Fixed
- Timezone bug ในการเก็บ timestamp
## [1.0.0] - 2026-05-15
- Initial release
🧪 Workshop — Deploy ไป 3 Targets
เอา project ของคุณ (เลือก 1 จาก W07/W10/W12) · deploy ใน 3 channel ที่ user เข้าถึงได้
- ☁️ Target 1: Cloud Web — Streamlit Cloud หรือ Render — เพื่อน open URL บน laptop ได้
-
📱 Target 2: Mobile
เลือก 1 ใน 3:
- 2a) Mobile-responsive Streamlit + PWA manifest → install บน home screen
- 2b) LINE bot · webhook คุยกับ logic เดิม
- 2c) Telegram bot (option ที่ 3)
-
💻 Target 3: เลือก 1
- 3a) Desktop .exe (PyInstaller) สำหรับ Windows user
- 3b) Raspberry Pi + systemd service (ถ้าคุณมี Pi)
- 3c) ESP32 MicroPython (ถ้าทำ IoT)
- 📊 ตั้ง Monitoring — Sentry สำหรับ errors · UptimeRobot สำหรับ uptime · log ผ่าน Cloud Run console
- 💰 ตั้ง Budget Alert ทุก service — $5 alert ที่ 50%, 90%, 100% · ตั้งทุกตัวที่ใช้ (Claude, OpenAI, GCP, ...)
- 🔁 เพิ่ม CI/CD — GitHub Actions รัน pytest + deploy auto บน push main
-
📝 Changelog v1.0.0
— เริ่มที่ v1.0.0 · log แต่ละ deploy ใน
CHANGELOG.md - 🧪 "Fresh clone" test — ขอเพื่อน 1 คน clone repo บนเครื่องเขา · ทำตาม README · ต้องรันได้
- 📱 User test บน mobile จริง — ส่ง LINE/URL ให้เพื่อน 3 คน · เปิดบนมือถือ · 2 ใน 3 ต้อง "ใช้สำเร็จ"
- Bonus — เปรียบเทียบ Local vs Cloud LLM — Ollama llama3.2:3b vs Claude Haiku · เปรียบเทียบ output + speed + cost ใน task เดียวกัน
ข้อผิดที่พบบ่อย
.env ขึ้น GitHub
— secret หลุดทันที · rotate key + ใช้ git-secrets ป้องกัน
staging branch ก่อนเสมอ · ผ่านแล้วค่อย merge main
--max-instances=10
ส่งงานสัปดาห์นี้
- 🌐 URL ของ Cloud target (Streamlit / Cloud Run)
- 📱 URL/QR ของ Mobile target (LINE bot ID หรือ PWA URL ที่ install ได้)
- 💻/🤖 ไฟล์/วิดีโอ ของ Desktop หรือ IoT target
- 📊 screenshot Sentry + UptimeRobot dashboard
- 💰 screenshot budget alert ของทุก service ที่ใช้
- 📁 GitHub repo มี Dockerfile, .github/workflows, CHANGELOG.md
- 🎤 user feedback จาก 3 คนที่ทดสอบบนมือถือจริง
- 📝 รายงาน 1 หน้า — เปรียบเทียบ Local LLM vs Cloud LLM ที่ลอง
Reference จาก slide เดิม
เนื้อหานี้เป็น Mainidea Foundation 14 (Cloud + Deployment) + 20 (Version + Change) ที่ไม่อยู่ใน slide เดิม — เป็นทักษะที่ขาดไม่ได้สำหรับ Final Project