• Dokku คือโอเพนซอร์ส PaaS ที่ทำให้ใช้ VPS เครื่องเดียวได้เหมือน Heroku เหมาะกับงานส่วนตัวหรือทีมเล็กที่ต้องการ deploy หลายแอปบนโครงสร้างพื้นฐานที่เป็นของตัวเองในต้นทุนต่ำ
  • เวิร์กโหลดที่ไม่ใช้ GPU กำลังรันอยู่บน OVHcloud VPS ราคา 7 ดอลลาร์ต่อเดือน ซึ่งช่วยลดต้นทุนและความซับซ้อนของการ deploy ในสภาพแวดล้อมที่ต้องปล่อยแอปบ่อย ๆ เช่นงานที่ปรึกษา LLM
  • แอปที่อิง Dockerfile สามารถ deploy ได้เพียงสร้างแอปใน Dokku, เพิ่ม Git remote และ git push dokku main จากนั้นปรับจำนวนโปรเซสได้ด้วย dokku ps:scale
  • แม้แต่เว็บไซต์แบบสแตติกก็สามารถ deploy จาก GitHub repository แบบ private และป้องกันด้วยรหัสผ่านได้ โดยใช้ _site, .static, nginx buildpack และ dokku-http-auth ร่วมกัน
  • เมื่อนำ GitHub Actions, คำสั่ง SSH ระยะไกล, การล้าง Docker cache และการ rebuild โดยไม่ต้อง push มาเชื่อมกัน ก็สามารถเปลี่ยน PaaS ส่วนตัวให้กลายเป็นสภาพแวดล้อมการปฏิบัติการที่ทำซ้ำได้

Dokku: ใช้ VPS เครื่องเดียวให้เหมือน Heroku

  • Dokku คือ โอเพนซอร์ส PaaS ที่ทำงานอยู่บนเซิร์ฟเวอร์เดี่ยวที่ผู้ใช้เลือกเอง
  • มอบประสบการณ์การ deploy ที่คล้าย Heroku แต่โครงสร้างพื้นฐานเป็นของผู้ใช้เองทั้งหมด
  • เนื่องจากค่าใช้จ่ายของ Heroku อาจสูงขึ้นได้ การมีแพลตฟอร์ม deploy ที่คุ้มค่าจึงสำคัญสำหรับงานที่ปรึกษา LLM ซึ่งต้อง deploy หลายแอป
  • มีการรันเซิร์ฟเวอร์ Dokku บน OVHcloud VPS ราคา 7 ดอลลาร์ต่อเดือน สำหรับเวิร์กโหลดที่ไม่ใช้ GPU

ประสบการณ์ deploy แบบ Heroku และความสามารถด้านการปฏิบัติการ

  • Dokku มีขั้นตอนการ deploy ที่ใช้งานง่ายแบบ Heroku
  • รองรับ การจัดการใบรับรอง SSL อัตโนมัติ ผ่าน Let’s Encrypt
  • สามารถป้องกันเว็บไซต์ด้วยรหัสผ่านผ่าน Basic Auth ได้
  • scale up/down ได้ด้วยคำสั่งเดียว
  • รองรับแอปหลากหลายประเภท เช่น Node, Python และหากจำเป็นก็สามารถกำหนด Docker container เองได้
  • มี ปลั๊กอินทางการ จำนวนมาก ทำให้ขยายความสามารถที่ต้องการได้เกือบทั้งหมด
  • การ deploy ทำได้ด้วยคำสั่ง Git เพียงอย่างเดียว

Deploy แอปด้วย Docker container

  • หลังจาก ติดตั้ง Dokku บน VPS แล้ว หากวาง Dockerfile ไว้ที่รากของ repository ของแอป ก็สามารถ deploy เป็น Docker container ได้
  • ตัวอย่าง Dockerfile ใช้อิมเมจ python:3.10, คัดลอกโค้ดไปไว้ที่ /app แล้วรัน pip install .
  • entrypoint.sh ใช้เพื่อให้รันแอปได้สะดวกทั้งบนเครื่อง local และใน Docker container
    • ตัวอย่างนี้รันแอป FastAPI ด้วย uvicorn main:app --port "$PORT" --host 0.0.0.0
  • เริ่มจากสร้างแอปบนโฮสต์ Dokku ก่อน
dokku apps:create myapp
  • ฝั่ง local ให้ตั้งค่าข้อมูลการเข้าถึงโฮสต์ Dokku ใน ~/.ssh/config และตั้งชื่อโฮสต์นั้นเป็น dokku
  • จากนั้นเพิ่ม Dokku เป็น remote ใน Git repository บนเครื่อง local แล้ว push เพื่อ deploy
git remote add dokku dokku@dokku:myapp
git push dokku main
  • หลัง deploy แล้ว URL ของแอปจะถูกแสดงใน log บนเครื่อง local โดยค่าเริ่มต้นจะอยู่ในรูปแบบ myapp.yourdomain.com
  • สามารถปรับจำนวน worker ได้ด้วยคำสั่งต่อไปนี้
dokku ps:scale myapp web=2
  • ดูรายละเอียดเพิ่มเติมได้ที่ Dokku docs

เว็บไซต์สแตติกแบบ private และ Basic Auth

  • GitHub Pages ไม่สะดวกนักหากต้องการ deploy เว็บไซต์สแตติกแบบ private ได้ง่าย ๆ เพราะต้องใช้บัญชี Enterprise ที่มีราคาแพง
  • แต่ถ้าใช้ Dokku ก็สามารถ deploy เว็บไซต์สแตติกจาก GitHub repository แบบ private และป้องกันด้วยรหัสผ่านได้
  • สมมติว่าเว็บไซต์สแตติกอยู่ในโฟลเดอร์ _site ของ Git repository
  • บนโฮสต์ Dokku ให้สร้างแอปและตั้งค่า environment variable NGINX_ROOT เป็น _site
dokku apps:create mysite
dokku config:set static-site NGINX_ROOT=_site
  • ติดตั้ง basic auth บนโฮสต์ Dokku และตั้งค่า สิทธิ์ เพื่อให้ปลั๊กอินทำงานได้
sudo dokku plugin:install https://github.com/dokku/dokku-http-auth.git
sudo chmod +x /home/dokku
  • ที่รากของ Git repository ซึ่งเก็บเว็บไซต์สแตติกไว้ ให้ทำขั้นตอนต่อไปนี้
touch .static
echo BUILDPACK_URL=https://github.com/dokku/buildpack-nginx > .env
git remote add dokku dokku@dokku:mysite
  • .static ใช้บอก Dokku ว่านี่คือเว็บไซต์สแตติก
  • BUILDPACK_URL ใช้ระบุให้ใช้ nginx buildpack
    • ปกติระบบอาจตรวจจับอัตโนมัติได้ แต่ในโปรเจกต์ที่มีทั้งโค้ดและเว็บไซต์สแตติก การระบุ nginx buildpack ชัดเจนจะช่วยลดความสับสน
  • การ deploy ทำด้วย git push dokku main
  • เปิดใช้การยืนยันตัวตนได้บนโฮสต์ Dokku ด้วยคำสั่งนี้
dokku http-auth:enable mysite <username> <password>
  • สามารถเพิ่มชื่อผู้ใช้/รหัสผ่านได้หลายชุด และกรองตาม IP เฉพาะได้ด้วย
  • HTTPS สามารถตั้งค่าได้ด้วย Let’s Encrypt Plugin และรองรับการต่ออายุอัตโนมัติ
  • หากใช้ Cloudflare proxy จัดการ HTTPS อยู่แล้ว ก็สามารถปล่อยให้ Cloudflare รับหน้าที่แทนปลั๊กอิน Let’s Encrypt ได้

Deploy อัตโนมัติด้วย GitHub Actions

  • แอปบน Dokku สามารถ deploy อัตโนมัติด้วย GitHub Actions ได้
  • จึงไม่ต้องทำขั้นตอน push ตรงไปยังโฮสต์ Dokku ซ้ำ ๆ แบบ manual
  • ตัวอย่าง workflow จะทำงานเมื่อสั่ง workflow_dispatch และเมื่อมีการ push ไปยัง branch main
  • การตั้งค่า concurrency ใช้ยกเลิก job ก่อนหน้าเพื่อหลีกเลี่ยง deploy lock ของ Dokku
  • workflow จะ checkout โค้ด, สร้าง SSH private key จาก secrets.DOKKU_SSH_PRIVATE_KEY, เพิ่ม Git remote และ force push ไปยัง Dokku
name: CI
on:
  workflow_dispatch:
  push:
    branches: [main]

concurrency:
  group: ${{ github.ref }}
  cancel-in-progress: true

jobs:
  deploy-dokku:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Install SSH key
        run: |
          echo "${{ secrets.DOKKU_SSH_PRIVATE_KEY }}" > private_key.pem
          chmod 600 private_key.pem

      - name: Add remote and push
        run: |
          git remote add dokku dokku@rechat.co:llm-eval
          GIT_SSH_COMMAND="ssh -i private_key.pem -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" git push dokku main -f

คำสั่งปฏิบัติการระยะไกลและการ rebuild

  • ตัวอย่างชื่อแอปคือ llm-eval และโฮสต์คือ rechat.co
  • โดยไม่ต้อง SSH login เข้าโฮสต์ Dokku โดยตรง ก็สามารถรันคำสั่งระยะไกลในฐานะผู้ใช้ dokku ได้
ssh dokku@rechat.co apps:list
  • สามารถล้าง Docker cache เพื่อบังคับให้ build ใหม่ได้
ssh dokku@rechat.co repo:purge-cache llm-eval
  • หากต้องการ rebuild โดยไม่ต้อง push ก็มีหลายวิธี และหนึ่งในนั้นคือคำสั่งนี้
ssh dokku@rechat.co ps:rebuild llm-eval

บันทึกอ้างอิงส่วนตัวสำหรับการ deploy ซ้ำ ๆ

  • มีการรวบรวมข้อมูลนี้ไว้เพราะทุกครั้งที่ deploy แอปใหม่ ต้องกลับไปค้นหารายละเอียดเดิมซ้ำอีก
  • จึงเก็บไว้เป็นบันทึกอ้างอิงที่สามารถนำกลับมาใช้ซ้ำได้สำหรับการตั้งค่าแพลตฟอร์ม deploy ส่วนตัวด้วย Dokku

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น