สารบัญ — บทที่ ๗ / ๑๖
PART 1 · รู้จัก
๑ · BOMLLM คืออะไร
๒ · สถาปัตยกรรม 4 เครื่อง
๓ · ฮาร์ดแวร์ที่ต้องมี
PART 2 · ติดตั้ง
๔ · เตรียมเครือข่าย
๕ · Mac Mini = สมอง
๖ · VPS = หน้าบ้าน
▸ ๗ · .env และ litellm.yaml
๘ · Virtual keys และงบประมาณ
PART 3 · ใช้งาน
๙ · Open WebUI ครั้งแรก
๑๐ · ลงโมเดลเพิ่มและส่วนเสริม
๑๑ · ภาพและเสียง (optional)
๑๒ · สูตรภาษาไทย
PART 4 · ต่อช่องทาง
๑๓ · LINE และ Telegram bot
๑๔ · MT5 EA อ่านอย่างเดียว และ content pipeline
PART 5 · ดูแล
๑๕ · ความปลอดภัยและ monitoring
๑๖ · อัปเกรดและแก้ปัญหา
PART 2 · ติดตั้ง

07.env และ litellm.yaml

Config walkthrough

TL;DR — สรุปใน 30 วินาทีtldr

บทนี้คือบทที่ "เฉลยทุกบรรทัด" — ไฟล์ความลับ .env และไฟล์ประตู litellm.yaml ทั้งสองไฟล์นี้กำหนดว่าระบบปลอดภัยแค่ไหน เร็วแค่ไหน และพังยังไง เราจะไล่ทีละบรรทัดพร้อมคำอธิบายภาษาไทย

กฎข้อที่ 1: ค่าจริงอยู่ใน .env เท่านั้น (gitignored, chmod 600) — ไฟล์ example มีแต่ค่า CHANGE_ME ที่ต้องแทนที่หมด

เมื่อไหร่ควรใช้ / When to usewhen to use

ทำหลัง bootstrap (บทที่ ๖) — bootstrap จะไม่ยก stack ให้จนกว่า .env จะสะอาด (ไม่มี CHANGE_ME เหลือ)

  • เปิดไฟล์ .env ด้วย editor บน VPS แล้วไล่แทนที่ทีละบล็อกตามด้านล่าง
  • ตั้งชื่อ key ตามรูปแบบ: สุ่มด้วย openssl rand -hex 16 แล้วเติมหน้า sk-

วิธีทำ / How-tohow to

ไฟล์ .env — ฉบับเต็มพร้อมคำอธิบายไทย (จาก configs/.env.example):

# ---------- LiteLLM ----------
# กุญแจหลัก (master key) = กุญแจของเจ้าของบ้าน สร้างครั้งเดียว เก็บดี ๆ
LITELLM_MASTER_KEY=sk-CHANGE_ME   # openssl rand -hex 16 แล้วเติมหน้า sk-
LITELLM_UI_USERNAME=admin
LITELLM_UI_PASSWORD=CHANGE_ME     # รหัสผ่านแข็ง ๆ สำหรับหน้า /ui

# ---------- Postgres ----------
POSTGRES_USER=litellm
POSTGRES_PASSWORD=CHANGE_ME       # ฐานข้อมูลอยู่ใน container network ไม่เปิดออก
DATABASE_URL=postgresql://litellm:...@postgres:5432/litellm

# ---------- Open WebUI ----------
WEBUI_SECRET_KEY=CHANGE_ME        # ใช้เซ็น session ของผู้ใช้เว็บแชท

# ---------- Mac ผ่าน Tailscale ----------
# รูปแบบ: http://100.x.y.z:11434  (Tailscale IP ของ Mac จากบทที่ ๔)
# กฎเหล็ก: ห้ามใส่ IP สาธารณะเด็ดขาด
MAC_OLLAMA_BASE_URL=http://100.CHANGE_ME.CHANGE_ME.CHANGE_ME:11434

# ---------- Tier 3 (คลาวด์ fallback) ----------
# ไม่อยากมีคลาวด์เลย = เว้นว่างไว้ (hard-local 100%)
CLOUD_FALLBACK_API_KEY=CHANGE_ME_or_leave_empty

# ---------- กุญแจรายช่องทาง ----------
# สร้างทีหลังผ่าน /key/generate แล้วค่อยมาแปะ (บทที่ ๘)
BOM_KEY_LINE=sk-CHANGE_ME
BOM_KEY_TELEGRAM=sk-CHANGE_ME
BOM_KEY_MT5=sk-CHANGE_ME
BOM_KEY_WRITER=sk-CHANGE_ME
BOM_KEY_SMOKE=sk-CHANGE_ME

จำไว้: บ้านเราพูดแต่ "โหลดคีย์แล้ว ยาว N ตัว" ใน log/รายงาน — ห้ามพิมพ์ค่าจริงเด็ดขาด

หลังแก้เสร็จ ตรวจนาทีละ 30 วินาที: chmod 600 .env และ docker compose up -d แล้วดูว่า LiteLLM parse config ผ่าน ถ้าติดตรงไหน → บทที่ ๑๖

ตัวอย่างการตั้งค่า / Config exampleconfig example

ไฟล์ litellm.yaml — ฉบับย่อส่วนที่สำคัญที่สุด (ฉบับเต็ม 134 บรรทัดอยู่ใน repo):

general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY   # อ้างจาก env เท่านั้น
  max_budget: 5.0        # เพดานใช้จ่ายคลาวด์รวม $5/วัน — ตัวกันบิลระเบิด
  budget_duration: 1d

litellm_settings:
  drop_params: True      # [บทเรียนจริง] พารามิเตอร์ที่ proxy ไม่รู้จักจะถูก "ตัดทิ้งเงียบ ๆ"
                         # เคยมี probe พิสูจน์ repeat_penalty=8.0 ผ่านไปได้ แต่ presence_penalty หายไป
  fallbacks: [{ "thai-chat": ["thai-chat-cpu", "thai-chat-cloud"] }]  # บันได 3 ชั้นจากบทที่ ๒

model_list:
  # Tier 1 — Mac (ฟรี หลัก)
  - model_name: thai-chat
    litellm_params:
      model: ollama_chat/qwen38-chat
      api_base: os.environ/MAC_OLLAMA_BASE_URL   # Tailscale เท่านั้น
      num_ctx: 32768        # พื้นระบับ context
      num_predict: 2048     # เพดานคำตอบ chat

  # เส้นทางบอท: ปิด think + เพดานตอบกระชับ
  # [บทเรียนจริง] เปิด think + num_predict น้อย = โมเดลเผาโควตาคำตอบไปกับ "ความคิดในใจ" แล้วตอบเปล่า
  - model_name: thai-chat-rt
    litellm_params:
      model: ollama_chat/qwen38-chat
      extra_body: { "think": false }
      num_predict: 1024
      timeout: 51

  # เส้นทางนักเขียน (pipeline บทความ): เพดานสูงเพื่อไม่ให้รายงานยาวโดนตัด
  - model_name: bom-writer
    litellm_params:
      num_ctx: 32768
      num_predict: 8192    # พื้นระบับความปลอดภัยของ completion (บทที่ ๑๒)

โครงทั้งไฟล์ = route ต่อการใช้งาน หนึ่ง route หนึ่งพฤติกรรม แลกกันที่นี่ ไม่ใช่ที่ Modelfile ของ Mac

Pro tip — เคล็ดลับจากสนามจริงpro tip

★ PROD LESSON
ค่าที่เคยพังเพราะพิมพ์ผิด — repeat_penalty 8.0 (พิมพ์ผิดจาก 1.05) ทำลายคำตอบทั้งก้อน และมัน "ผ่าน" มาได้เพราะ proxy ส่งต่อทุกอย่าง — บทเรียนคืออย่าเชื่อว่า config ที่ไม่ error = config ที่ถูก ต้องรัน bench ยืนยันเสมอ (บทที่ ๑๒)
★ PRO TIP
อยาก hard-local 100%? — ลบทิ้งเฉพาะบล็อก thai-chat-cloud ใน model_list และเว้น CLOUD_FALLBACK_API_KEY ว่าง — ระบบจะไม่มีทางส่งข้อมูลออกนอกบ้านเลย แลกกับความเสี่ยงที่บอทจะเงียบช่วง Mac ล่ม

คำถามที่พบบ่อย / FAQfaq

ถาม: ใส่ค่าผิดแล้วลงมือไปแล้ว ต้องเริ่มใหม่ไหม? — ไม่ต้อง แก้ .env แล้ว docker compose up -d ใหม่ ตัวเดียวที่แก้ยากคือ master key เพราะต้องไปอัปเดตทุกที่ที่อ้างถึง

ถาม: เก็บ .env ไว้ที่ไหนดี? — บน VPS อย่างเดียว อย่า copy ลงเครื่องพกพา/Drive ส่วนสำรองจริงใช้ตู้เซฟ (เช่น Vaultwarden บน NAS)

คำถามอื่น ๆ ดูที่ FAQ

ดูเพิ่ม / See alsosee also

ภาพประกอบ / Figuresfigures

เส้นทาง request ของบอทผ่าน litellm.yaml
route thai-chat-rt คือเส้นทางกลางของแผนภาพนี้

วิดีโอ / Videovideo

🎬
วิดีโอกำลังผลิต — ติดตามที่ YouTube @icafefx
คลิปสาธิตทีละขั้นของบทนี้จะอัปโหลดที่ youtube.com/@icafefx เร็ว ๆ นี้