3 คะแนน โดย GN⁺ 2024-11-15 | 6 ความคิดเห็น | แชร์ทาง WhatsApp
  • docker-compose เป็นเครื่องมือสำหรับจัดการคอนเทนเนอร์ Docker ซึ่งช่วยแก้ปัญหาการดีพลอยแอปพลิเคชันที่ซับซ้อน แต่ยังไม่เพียงพอสำหรับการ self-hosting แบบง่าย ๆ สำหรับตลาดมวลชน
  • จำเป็นต้องมี abstraction ระดับสูงกว่าที่รวมแนวคิดอย่างฐานข้อมูล SQL, local cache, persistent storage, service discovery และ resource management

บทบาทของ Docker

  • Docker เป็นเครื่องมือที่ทำให้คอนเทนเนอร์ได้รับความนิยมในวงกว้าง โดยสามารถเปรียบระบบโฮสต์ได้เหมือนเรือ
  • มีทั้งฮาร์ดแวร์ ระบบปฏิบัติการ และ container runtime โดยคอนเทนเนอร์จะรันอยู่ภายใน runtime และสื่อสารกับบริการอื่น ๆ เช่น ฐานข้อมูลหรือเว็บเซิร์ฟเวอร์

บทบาทของ Docker-compose

  • docker-compose เป็นเครื่องมือสำหรับกำหนดกลุ่มคอนเทนเนอร์ที่ทำงานร่วมกัน และช่วยให้การดีพลอยแอปพลิเคชันแบบ self-hosting ทำได้ง่ายขึ้น
  • อย่างไรก็ตาม มันทำลายอินเทอร์เฟซที่เป็นมาตรฐานและทำให้เกิดปัญหาแบบเดียวกับที่คอนเทนเนอร์พยายามแก้ไว้แต่แรก
  • ตัวอย่าง: Pihole
    • Pihole เป็น DNS server ที่ต้องใช้ไฟล์ docker-compose ที่ซับซ้อน
    • ต้องตั้งค่าชื่อคอนเทนเนอร์, image, port, environment variable, volume, ความสามารถเพิ่มเติม, restart policy และอื่น ๆ
    • ผู้ใช้ต้องจัดการการตั้งค่าที่ซับซ้อนเหล่านี้เอง ซึ่งเป็นข้อเสียของ Docker Compose
  • ตัวอย่าง: Jitsi Meet
    • Jitsi Meet เป็นซอฟต์แวร์ที่ซับซ้อน โดยสร้างคอนฟิก docker-compose ที่มี 4 คอนเทนเนอร์, 7 วอลุ่ม, 9 พอร์ต และการตั้งค่า environment มากกว่า 200 รายการ
  • ตัวอย่าง: แอป self-hosting ยอดนิยมอื่น ๆ ก็ประสบปัญหาแบบเดียวกัน
    • มีแอปหลากหลาย เช่น Authentik, Nextcloud, Immich, Jellyfin, Paperless NGX เป็นต้น และคอนฟิก docker-compose ของแต่ละแอปก็แทนที่คำสั่ง docker ตั้งแต่หลายสิบถึงหลายร้อยคำสั่ง
    • แต่ละแอปอาจมีฐานข้อมูล แคช และ HTTP handler ของตัวเอง ซึ่งนำไปสู่การใช้ทรัพยากรซ้ำซ้อน

ปัญหา

  • docker-compose ยืดหยุ่นเกินไป ละเอียดเกินไป และทำงานอยู่บนชั้น abstraction ที่ไม่เหมาะสม
  • แต่ละแอปมี process สำหรับจัดการ HTTP, แคช หรือฐานข้อมูลของตัวเอง และการสำรองข้อมูลฐานข้อมูลก็กลายเป็นภาระของผู้ดูแลระบบ
  • ตัวอย่าง: Reverse HTTP proxy
    • Reverse HTTP proxy คือโปรแกรมที่ส่งต่อคำขอ HTTP ที่เข้ามาไปยังโปรแกรมอื่น โดยแต่ละโปรแกรมต้องตัดสินใจเองว่าจะรวมเว็บเซิร์ฟเวอร์มาด้วยหรือไม่
    • รวมเว็บเซิร์ฟเวอร์
      • หากรวมเว็บเซิร์ฟเวอร์มา โปรแกรมก็จะทำงานได้ แต่จะทำงานได้เฉพาะบนพอร์ตที่กำหนด และถ้ามีหลายคอนเทนเนอร์ก็ต้อง remap พอร์ต
    • ไม่รวมเว็บเซิร์ฟเวอร์
      • หากไม่รวมเว็บเซิร์ฟเวอร์ก็จะไม่เปลืองทรัพยากร แต่ต้องคอนฟิกแอปพลิเคชันโดยไม่มีอินเทอร์เฟซสำหรับจัดการ
    • DNS
      • เว็บอินเทอร์เฟซต้องมีที่อยู่ และหากต้องการ TLS ก็ต้องมีชื่อด้วย หากรันหลายบริการบนโฮสต์เดียวกัน ก็ต้อง route คำขอด้วยชื่อโดเมนหรือ path
    • พอร์ต
      • docker-compose อนุญาตให้ expose และ remap พอร์ตได้ แต่ในทางปฏิบัติแล้วควรรองรับการตั้งค่าเครือข่ายที่ซับซ้อนกว่านั้น
  • ตัวอย่าง: ฐานข้อมูล
    • ฐานข้อมูลจะสูญเสียการเปลี่ยนแปลงทั้งหมดของไฟล์เมื่อคอนเทนเนอร์ถูกลบ ดังนั้นคอนเทนเนอร์ฐานข้อมูลจึงต้องเพิ่ม volume เพื่อเก็บเนื้อหาของฐานข้อมูลไว้
    • N+1=2 หรือมากกว่า
      • หากต้องการสำรองฐานข้อมูล ก็จำเป็นต้องมี offsite backup และถ้าแต่ละบริการ bundle database server process แยกของตัวเองมาด้วย ก็จะเป็นการสิ้นเปลืองทรัพยากรคอมพิวต์

ทางแก้

  • ย้ายไปยังชั้น abstraction ที่สูงขึ้น และเพิ่ม semantics ที่แยกประเภทคอนเทนเนอร์ เช่น ฐานข้อมูล, reverse web proxy, cache และ static web asset
  • ตัวอย่างของ semantics
    • แนะนำรูปแบบคอนฟิกใหม่สำหรับระบุชื่อแอปพลิเคชัน, การ build, HTTPS reverse proxy และบริการ cache
  • ทางแก้ #1
    • ให้แต่ละโปรแกรมร้องขอ reverse proxy เพื่อหลีกเลี่ยงความซ้ำซ้อนและความสิ้นเปลือง โดย reverse proxy จะให้ชื่อ DNS และส่งต่อทุก path ไปยังโปรแกรม
  • ทางแก้ #1.5
    • เพิ่มส่วนของฐานข้อมูลเพื่อให้สามารถร้องขอฐานข้อมูลที่เป็นไปตามมาตรฐาน SQL และให้โปรแกรมคาดหวังสิทธิ์แบบ "full"
  • ทางแก้สำหรับพอร์ต
    • แต่ละโปรแกรมจะได้รับ IPv6 address ของตัวเอง จึงสามารถใช้หมายเลขพอร์ตมาตรฐานได้ และเพื่อความปลอดภัย ให้ใช้ firewall เพื่อให้มีเพียง reverse proxy เท่านั้นที่เข้าถึงพอร์ตได้

Tealok - container runtime แบบใหม่

  • Tealok เป็น container runtime ใหม่ที่ให้ abstraction ระดับสูงขึ้นและอินเทอร์เฟซที่เป็นมาตรฐาน
    • จัดการ ใบรับรอง TLS, การตั้งค่า reverse proxy, ระเบียน DNS, การจัดการ backup และอื่น ๆ ให้อัตโนมัติ
    • ใช้ IPv6 เพื่อให้แต่ละคอนเทนเนอร์มี IP address ของตัวเอง และสามารถใช้หมายเลขพอร์ตมาตรฐานได้
    • นักพัฒนาแอปสามารถดีพลอยแอปผ่านอินเทอร์เฟซมาตรฐานได้โดยไม่ต้องตั้งค่าที่ซับซ้อน
  • สำหรับ ผู้ดูแลระบบ จะได้รับแนวปฏิบัติที่ดีอย่างสม่ำเสมอ ลดการสิ้นเปลืองทรัพยากร และลดภาระในการดูแลจัดการ
  • สำหรับ นักพัฒนา จะช่วยให้วิธีการดีพลอยง่ายขึ้นและลดภาระในการตัดสินใจ
  • ผู้ใช้จะได้รับการรับประกันเรื่อง ความเป็นเจ้าของข้อมูล และ ความเป็นอิสระจากคลาวด์คอมพิวติ้ง

6 ความคิดเห็น

 
luminance 2024-11-15

พอเข้าไปดู tealok แล้ว มันยังไม่อยู่ในสภาพที่จะเป็นทางเลือกทดแทนได้เลยนะ?

 
savvykang 2024-11-15

น่าเสียดาย ถ้าลบ runtime ออกไปด้วยได้ก็คงจะดีมาก

 
tujuc 2024-11-15

ฉันยังคิดว่า การใช้ docker-compose เพื่อสร้างสภาพแวดล้อมการใช้งานจริงและเข้าไปทดสอบนั้นยังคงจำเป็นอยู่...

แต่การบอกว่า จากประสบการณ์ในสภาพแวดล้อมเฉพาะของตัวเอง เลยสรุปว่าสิ่งนั้นผิดแล้วสร้างของใหม่ขึ้นมา... แบบนี้เห็นด้วยได้ยากนะครับ.. 5555

เป็นเนื้อหาที่ถ้าไม่ระวังก็อาจทำให้เข้าใจผิดได้ครับ 555555...

เพราะตอนเห็นแค่ชื่อก็คิดว่า 'เอ๊ะ ไม่ค่อยชอบที่เอาไปใช้ในสภาพแวดล้อมพัฒนาจริง ๆ เลยนะ....' น่ะครับ.. 555

 
ilbanin00 2024-11-15

ผมคิดว่าการพยายามใช้ docker compose เพื่อวัตถุประสงค์แบบเดียวกับในบทความตั้งแต่แรกนั้นเป็นแนวทางที่ผิด

 
tujuc 2024-11-15

ผมเห็นด้วยกับบางส่วน แต่ไม่คิดว่าแนวทางนั้นจะผิดไปเสียทีเดียว
มันน่าจะเป็นทางเลือกที่ดีที่สุดในสภาพแวดล้อมที่พวกเขาทำได้ :)

 
GN⁺ 2024-11-15
ความคิดเห็นจาก Hacker News
  • มีวิธีแก้ปัญหาเรื่องการแมปพอร์ตและการสำรองข้อมูลโวลุมแบบง่าย ๆ อยู่

    • สามารถใช้ไฟล์ docker-compose แยกสำหรับสภาพแวดล้อมการพัฒนา เพื่อกำหนดค่าที่ต่างกันตามแต่ละสภาพแวดล้อมได้
    • สามารถเขียนสคริปต์ Bash แบบง่ายเพื่ออัปโหลดไปยัง S3 สำหรับการสำรองข้อมูลได้
  • ในฐานะคนที่ใช้ Docker ทำ self-hosting บนเซิร์ฟเวอร์ส่วนตัว มองว่าความยืดหยุ่นของการตั้งค่า Docker เป็นข้อดี

    • การตั้งค่าเริ่มต้นใช้เวลาพอสมควร แต่หลังจากนั้นก็จัดการได้ง่าย
    • การเพิ่มบริการใหม่แทบไม่ใช้เวลา และเพื่อความปลอดภัยก็สร้างผู้ใช้ที่ไม่ใช่ root ให้แต่ละบริการ
    • ใช้เครือข่าย macvlan เพื่อกำหนด IP และ MAC address เฉพาะให้แต่ละคอนเทนเนอร์
    • ใช้ Nginx Proxy Manager จัดการ reverse proxy และไม่มีปัญหาแม้จะรันหลายอินสแตนซ์เป็นฐานข้อมูล
  • docker-compose มักใช้เป็นหลักในงานพัฒนาหรือการใช้งานส่วนตัว และ V2 เป็นปลั๊กอินที่รวมเข้ากับ Docker ต่างจาก V1

  • ในสภาพแวดล้อม production ควรใช้ Kubernetes ส่วน docker-compose เหมาะกับการพัฒนาแบบโลคัล

  • docker-compose เป็นผลิตภัณฑ์สำหรับ self-hosting ขนาดเล็ก โดยมุ่งเป้าไปที่คนที่ไม่มีพื้นฐานด้านเทคนิค

    • ยังสงสัยว่าการเปลี่ยนไปใช้ TOML จะทำให้ self-hosting ง่ายขึ้นจริงหรือไม่
  • การเขียนโปรแกรมเพื่อควบคุม Docker นั้นง่ายกว่าที่คิด และสามารถใช้สคริปต์ Python เพื่อแก้ปัญหาได้

  • กำลังพัฒนา canine.sh เพื่อให้ใช้งาน Kubernetes cluster ได้ง่ายเหมือน Heroku

    • ใช้อยู่กับโปรเจกต์ส่วนตัว และสามารถโฮสต์หลายแอปได้ด้วยต้นทุนต่ำ
  • น่าสนใจที่ Tealok กำลังพัฒนาทางเลือกแทน docker-compose

  • มองว่า docker-compose, Kubernetes และ Helm เป็นชั้นนามธรรมที่ผิดที่ผิดทาง

    • มีความพยายามมากมายในการพัฒนาวิธีรันและสื่อสารระหว่างคอนเทนเนอร์ในรูปแบบต่าง ๆ
  • รู้สึกสับสนกับคำกล่าวที่ว่า docker-compose เป็นชั้นนามธรรมที่ผิดที่ผิดทาง

    • ดูเหมือนคาดหวังอินเทอร์เฟซระดับสูงเพื่อแก้ปัญหาเฉพาะบางอย่าง
    • ปัญหาการสร้างอินสแตนซ์ซ้ำไม่ใช่เรื่องใหญ่สำหรับแอปพลิเคชันส่วนใหญ่
    • การบังคับให้ออกแบบแอปพลิเคชันในรูปแบบเฉพาะจะใช้ได้ดีแค่ในบางสถานการณ์เท่านั้น