เปลี่ยน Jellyfin เป็นร้านวิดีโอ 90s ด้วย Halcyon
เปลี่ยนคลังสื่อ Jellyfin ให้เป็นร้านเช่าวิดีโอในยุค 90 เดินเลือกชมได้ผ่านเบราว์เซอร์ พร้อมวิธีตั้งค่าผ่าน Docker การทำ Reverse Proxy และข้อควรระวังก่อนใช้งานจริง
สิ่งที่ Halcyon ทำกับคลังสื่อ Jellyfin ของคุณ
Halcyon Video จะจำลองคลังสื่อ Jellyfin ของคุณให้กลายเป็นร้านวิดีโอในยุค 1990 ที่คุณสามารถเดินเลือกชมได้ผ่านเว็บเบราว์เซอร์ ภาพยนตร์ทุกเรื่องที่คุณมีจะถูกเปลี่ยนเป็นตลับวิดีโอวางอยู่บนชั้นวาง คุณสามารถเดินไปตามทางเดินภายใต้แสงไฟนีออน หยิบกล่องวิดีโอลงมา พลิกดูรายละเอียดที่ด้านหลัง แล้วนำไปที่เคาน์เตอร์เพื่อเริ่มเล่นวิดีโอ ระบบจะรายงานสถานะการเริ่มเล่น ความคืบหน้า และการหยุดเล่นกลับไปยัง Jellyfin เพื่อให้จุดที่รับชมค้างไว้และประวัติการรับชมมีความถูกต้องเสมอ
Halcyon จะอ่านข้อมูลจากเซิร์ฟเวอร์ Jellyfin ที่มีอยู่ผ่านทาง Jellyfin API โดยไม่ได้สร้างคลังข้อมูลเป็นของตนเอง คู่มือนี้ตั้งสมมติฐานว่า Jellyfin ของคุณทำงานและสแกนข้อมูลได้อย่างถูกต้องเรียบร้อยแล้ว หากยังไม่เป็นเช่นนั้น ให้ตั้งค่า Jellyfin ในฐานะสื่อบันเทิงบน VPS ให้เรียบร้อยก่อน แล้วจึงกลับมาดำเนินการต่อเมื่อคลังสื่อของคุณแสดงผลในเว็บไคลเอนต์ปกติได้อย่างถูกต้อง นี่คือซอฟต์แวร์ที่คุณควรติดตั้งก็ต่อเมื่อคุณมีคลังสื่อพร้อมใช้งานอยู่แล้ว ไม่ใช่เพราะคุณต้องการเพิ่มบริการอื่นเข้าไปใน รายการบริการที่คุณโฮสต์เอง
โครงการนี้อยู่ภายใต้สัญญาอนุญาต GPL-3.0 และพัฒนาโดยบุคคลเพียงคนเดียว โดยในไฟล์ README ระบุไว้อย่างชัดเจนว่าจะไม่รับ pull request การพัฒนาดำเนินไปอย่างรวดเร็วและไม่มีผู้ดูแลคนอื่นคอยตรวจสอบข้อผิดพลาดที่อาจเกิดขึ้น ดังนั้นควรระบุเวอร์ชันของ image ให้คงที่ (pin) ก่อนที่จะเปิดให้ผู้อื่นเข้าใช้งานร้านวิดีโอของคุณ โดยส่วนสุดท้ายของคู่มือนี้จะอธิบายวิธีการดำเนินการดังกล่าว
การเรนเดอร์เกิดขึ้นที่ไหน?
เกิดขึ้นในเบราว์เซอร์ Halcyon เป็นแอปพลิเคชัน Vite และ TypeScript ที่สร้างขึ้นบน three.js ซึ่งเป็นไลบรารี JavaScript สำหรับวาดกราฟิก 3D ผ่าน WebGL (web graphics library ซึ่งเป็นอินเทอร์เฟซของเบราว์เซอร์ที่เชื่อมต่อกับ GPU) โดยรูปทรงของร้านค้าและภาพหน้าปกกล่องจะถูกนำมาประกอบกันโดยเครื่องที่แสดงผลหน้าจอนั้น
คอนเทนเนอร์ทำหน้าที่เพียงเล็กน้อยเท่านั้น โดยจะรัน npm run serve ซึ่งก็คือ vite preview --port 1420 --strictPort --host และทำหน้าที่ให้บริการไฟล์ที่ build แล้ว รวมถึง route ของ middleware ขนาดเล็กอีกจำนวนหนึ่ง Halcyon ไม่มีการแปลงรหัส (transcoding) และไม่มีการรัน engine ใดๆ บนเซิร์ฟเวอร์
ดังนั้น คำถามเรื่อง GPU จึงขึ้นอยู่กับฝั่งไคลเอนต์ VPS ขนาดเล็กสามารถให้บริการส่วนนี้ได้อย่างราบรื่น เพราะการให้บริการหมายถึงการส่งไฟล์แบบ static ผ่าน HTTP ส่วนแล็ปท็อป แท็บเล็ต หรือโทรทัศน์ที่รันเบราว์เซอร์จะเป็นตัวตัดสินว่าร้านค้าจะแสดงผลได้อย่างลื่นไหลหรือกระตุก
มีฟีเจอร์หนึ่งที่ขัดกับกฎดังกล่าว คือ Remote Play ซึ่งจะสร้าง instance ของ Chromium แบบ headless บนเซิร์ฟเวอร์ และสตรีมร้านค้าที่เรนเดอร์แล้วไปยังโทรศัพท์หรือ set top box ผ่าน WebRTC (web real time communication) เส้นทางนั้นจะเรนเดอร์บนเซิร์ฟเวอร์ โดยจำกัดไว้ที่สอง instance เป็นค่าเริ่มต้นและสามารถปรับเปลี่ยนได้ด้วย REMOTE_PLAY_MAX_INSTANCES หากไม่มีการแมปอุปกรณ์ /dev/dri instance เหล่านั้นจะเรนเดอร์บน CPU ดังนั้น VPS ที่มีสองคอร์จะได้รับผลกระทบทุกครั้งที่มีผู้ชมเพิ่มขึ้น
สิ่งที่ร้านค้าอ่านจากคลังข้อมูลของคุณ
ชั้นวางสินค้ามาจากโครงสร้างของ Jellyfin โดยตรง Halcyon จะจัดวางส่วนต่างๆ ตามคลังข้อมูลและประเภทสื่อของคุณ และจัดกลุ่มภาคต่อจาก BoxSets ของคุณ ข้อมูลจำเพาะที่พิมพ์อยู่ด้านหลังกล่องแต่ละกล่องมาจาก metadata ของ MediaStreams ที่ Jellyfin จัดเก็บไว้อยู่แล้ว ซึ่งหมายความว่าหากข้อมูลใดขาดหายไปใน Jellyfin ข้อมูลนั้นก็จะขาดหายไปบนชั้นวางด้วยเช่นกัน
สิ่งนี้ทำให้ร้านค้าเป็นภาพสะท้อนที่แม่นยำของ metadata ของคุณ คลังข้อมูลที่จัดการผ่าน an arr stack ใน Docker Compose ซึ่งมีการใส่ภาพปกและประเภทสื่อไว้ครบถ้วนแล้ว จะดูดีกว่าโฟลเดอร์ที่มีไฟล์กระจัดกระจายและตั้งชื่อแบบทั่วไปมาก คลังรูปภาพก็มีความขึ้นตรงต่อสิ่งที่ทำดัชนีข้อมูลเหล่านั้นเช่นเดียวกัน ซึ่งเป็นสิ่งที่ควรคำนึงถึงเมื่อคุณเปรียบเทียบ PhotoPrism กับ Immich สำหรับภาพนิ่งที่เก็บอยู่บนเซิร์ฟเวอร์เดียวกัน
ทดลองใช้งานเดโมร้านค้าวิดีโอก่อนทำการติดตั้ง
โปรเจกต์นี้เผยแพร่ตัวอย่างร้านค้าที่ทำงานร่วมกับคลังข้อมูลจำลองไว้ที่ เดโมออนไลน์ การเพิ่ม ?demo=1 ต่อท้าย URL ของ Halcyon ใดๆ จะให้ผลลัพธ์แบบเดียวกันบนการติดตั้งของคุณเอง
ใช้เดโมนี้เพื่อทดสอบฮาร์ดแวร์ โดยมีข้อควรระวังคือ เดโมจะปรับขนาดตัวเองตามอุปกรณ์ที่ใช้ เบราว์เซอร์ที่มีประสิทธิภาพ GPU เหลือเฟือจะแสดงรายการสินค้าเต็มจำนวนประมาณ 2,000 รายการ GPU ระดับกลางจะแสดงประมาณ 800 รายการ ส่วนโทรศัพท์หรือเบราว์เซอร์ที่รายงานหน่วยความจำอุปกรณ์ 4 GB หรือน้อยกว่า จะแสดงประมาณ 300 รายการ หากเดโมทำงานได้อย่างราบรื่นบนอุปกรณ์ประสิทธิภาพต่ำ แสดงว่าระบบได้ลดขนาดตัวเองลงแล้ว จึงไม่สามารถใช้ประเมินประสิทธิภาพของคลังข้อมูลฉบับเต็มของคุณได้ การทดสอบที่มีประโยชน์คือการใช้อุปกรณ์ที่สามารถโหลดรายการสินค้าได้เต็มจำนวน หากการแสดงผลกระตุก คลังข้อมูลของคุณที่มีขนาดใกล้เคียงกันก็จะกระตุกเช่นกัน และวิธีแก้ไขคือการใช้โหมด 2.5D ตามที่อธิบายไว้ด้านล่าง แทนการอัปเกรด VPS ให้มีขนาดใหญ่ขึ้น
การรันด้วย Docker
นี่คือคำสั่งที่เอกสารต้นทางระบุไว้
docker run -d --name halcyon --network host --restart unless-stopped \
ghcr.io/halcyon-video/halcyon-videoจากนั้นให้ตรวจสอบว่าบริการเริ่มทำงานแล้ว
docker logs halcyon
curl -I http://127.0.0.1:1420Log ควรแสดงว่า preview server กำลังฟังอยู่ที่พอร์ต 1420 และ curl ควรตอบสนองต่อ HTTP/1.1 200 OK หากคอนเทนเนอร์หยุดทำงานภายในไม่กี่วินาที มักเกิดจากปัญหาพอร์ต --strictPort หมายความว่าเซิร์ฟเวอร์ปฏิเสธที่จะเปลี่ยนไปใช้พอร์ต 1421 เมื่อพอร์ต 1420 ถูกใช้งานอยู่ จึงหยุดทำงานแทน
--network host มีไว้สำหรับ Remote Play ไม่ใช่สำหรับ store โดย WebRTC จำเป็นต้องประกาศที่อยู่จริงของเครื่องให้กับอุปกรณ์ที่ต้องการรับสตรีม ภายใต้ Docker bridge เริ่มต้น คอนเทนเนอร์จะรู้จักเพียงที่อยู่ 172.x ของตัวเองเท่านั้น ซึ่งโทรศัพท์ในเครือข่ายของคุณไม่สามารถเข้าถึงได้ ทำให้การสตรีมไม่สามารถเชื่อมต่อได้ หากคุณต้องการเพียงแค่ใช้งาน store ผ่านเบราว์เซอร์ ให้ใช้วิธี publish พอร์ตแทน
docker run -d --name halcyon -p 1420:1420 --restart unless-stopped \
ghcr.io/halcyon-video/halcyon-videoนั่นเป็นค่าเริ่มต้นที่ดีกว่าบน VPS เนื่องจาก host networking จะนำคอนเทนเนอร์ไปวางไว้บนทุกอินเทอร์เฟซที่เครื่องมี รวมถึงอินเทอร์เฟซสาธารณะด้วย การรัน Docker บน VPS ครอบคลุมรายละเอียดส่วนที่เหลือของข้อแลกเปลี่ยนนี้ --restart unless-stopped คือสิ่งที่ทำให้ store กลับมาทำงานได้หลังจากรีบูต ซึ่งเป็นแนวคิดเดียวกับ การจัดการ Compose services ให้เริ่มทำงานตอนบูต
การโคลน repository และรัน docker compose up -d จะเป็นการ build image ในเครื่องแทน ไฟล์ Compose ที่ให้มาจะ build จาก source เป็นค่าเริ่มต้น และมีบรรทัด image: ที่ถูก comment ไว้ ดังนั้นให้เอา comment ออกหากคุณต้องการใช้ image ที่เผยแพร่ผ่าน Compose
Image ที่เผยแพร่นั้นครอบคลุมทั้ง linux/amd64 และ linux/arm64 จากการตรวจสอบเมื่อวันที่ 9 ตุลาคม 2026 รุ่น 0.25.0 ปัจจุบันได้ระบุ digest แยกสำหรับแต่ละแพลตฟอร์ม ดังนั้น VPS แบบ arm64 จึงสามารถดึง image ด้วยคำสั่งเดียวกับโฮสต์อื่น ๆ ช่วงเวลาที่รองรับเฉพาะ amd64 นั้นสั้นมาก โดย changelog ได้ถอด image arm64 ออกใน v0.2.1 เมื่อวันที่ 8 สิงหาคม 2026 และนำกลับมาใหม่โดย build บน native runners ใน v0.4.0 เมื่อวันที่ 11 สิงหาคม 2026 มีเพียงโฮสต์ที่ล็อกเวอร์ชันไว้กับ tag ในช่วงเวลาดังกล่าวเท่านั้นที่จำเป็นต้อง build จากการโคลน
ชี้เป้าไปยังเซิร์ฟเวอร์ Jellyfin ของคุณ
เปิด http://<host>:1420 แล้วเข้าสู่ระบบด้วยที่อยู่เซิร์ฟเวอร์ Jellyfin ชื่อผู้ใช้ และรหัสผ่านของคุณ ไฟล์ .env.local.example ใน repository มีไว้สำหรับการพัฒนาในเครื่องเท่านั้น Vite จะเปิดเผยตัวแปรที่มีคำนำหน้าว่า VITE_ ให้กับโค้ดฝั่งไคลเอ็นต์ ดังนั้นรหัสผ่าน Jellyfin ที่เขียนไว้ในนั้นจะถูกคอมไพล์รวมเข้าไปใน JavaScript bundle ที่ผู้เข้าชมทุกคนดาวน์โหลดไป หากเป็นเซิร์ฟเวอร์ที่ผู้อื่นเข้าถึงได้ ให้เข้าสู่ระบบผ่านอินเทอร์เฟซแทน
เบราว์เซอร์จะสื่อสารกับ Jellyfin โดยตรง คอนเทนเนอร์ของ Halcyon ไม่ได้ทำหน้าที่เป็นพร็อกซีให้กับ Jellyfin API ซึ่งมีผลลัพธ์สองประการที่ควรทราบก่อนเริ่มการดีบั๊ก
ประการแรก Jellyfin ต้องสามารถเข้าถึงได้จากเบราว์เซอร์ ไม่ใช่แค่จาก VPS ที่ให้บริการ Halcyon เท่านั้น การผูก Jellyfin ไว้กับ 127.0.0.1:8096 นั้นใช้ได้สำหรับการทดสอบในเครื่อง แต่จะทำให้ชั้นวางข้อมูลว่างเปล่าสำหรับผู้ใช้คนอื่น
ประการที่สอง การเรียกใช้งานเป็นการข้ามแหล่งที่มา (cross origin) จากที่อยู่ของ Halcyon ไปยังที่อยู่ของ Jellyfin โดยปกติแล้ว Jellyfin จะตอบกลับคำขอ API ด้วย Access-Control-Allow-Origin: * เป็นค่าเริ่มต้น จึงสามารถทำงานได้โดยไม่ต้องตั้งค่าเพิ่มเติม หากคุณจำกัดการตั้งค่านั้นไว้ หรือวาง authentication proxy ไว้หน้า Jellyfin API คอนโซลของเบราว์เซอร์จะรายงาน blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource และหน้าจอร้านค้าจะโหลดขึ้นมาโดยไม่มีข้อมูลแสดงผล
วางไว้หลัง reverse proxy พร้อมการยืนยันตัวตนที่ด้านหน้า
vite preview เป็นเซิร์ฟเวอร์สำหรับดูตัวอย่าง มันไม่ได้ทำ TLS (transport layer security) termination และไม่มีระบบควบคุมการเข้าถึงในตัว ดังนั้นจึงควรวางไว้หลัง nginx หรือ Caddy หากต้องเปิดใช้งานบนเครือข่ายสาธารณะ
server {
listen 443 ssl;
server_name halcyon.example.com;
location / {
proxy_pass http://127.0.0.1:1420;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}ชื่อโดเมนที่อยู่หน้าคอนเทนเนอร์จำเป็นต้องมีการตั้งค่าเพิ่มเติมอีกหนึ่งอย่าง Halcyon จะตอบสนองต่อ localhost, IP address โดยตรง และชื่อของเครื่องที่มันรันอยู่ เพื่อป้องกันการทำ DNS rebinding เมื่ออยู่ในคอนเทนเนอร์ เครื่องที่มันรันอยู่คือตัวคอนเทนเนอร์เอง ดังนั้น hostname ของมันจึงไม่ใช่ของคุณ คำขอที่เข้ามาในชื่อ halcyon.example.com จะถูกปฏิเสธ และการตอบกลับจะระบุชื่อโฮสต์ที่ถูกปฏิเสธ ให้เพิ่มชื่อนั้นเข้าไป
docker run -d --name halcyon -p 127.0.0.1:1420:1420 --restart unless-stopped \
-e HALCYON_ALLOWED_HOSTS=halcyon.example.com \
ghcr.io/halcyon-video/halcyon-videoค่านี้คั่นด้วยเครื่องหมายจุลภาค การใส่จุดนำหน้าเช่น .example.com จะครอบคลุมถึง subdomain ทั้งหมด และ all จะเป็นการปิดการตรวจสอบนี้ ให้เลือกใช้ all เฉพาะบนเครื่องที่ไม่มีใครจากภายนอกเข้าถึงได้เท่านั้น
เมื่อ store ถูกให้บริการผ่าน https:// แล้ว ที่อยู่ของ Jellyfin ที่คุณพิมพ์ตอนล็อกอินจะต้องเป็น https:// ด้วยเช่นกัน เบราว์เซอร์จะบล็อกการเรียกใช้ API แบบ plain http:// ที่มาจากหน้า HTTPS และคอนโซลจะแสดงข้อความ Mixed Content: The page at 'https://halcyon.example.com/' was loaded over HTTPS, but requested an insecure resource การล็อกอินจะล้มเหลวโดยไม่มีคำอธิบายใดๆ ภายใน Halcyon ดังนั้นควรให้บริการทั้งคู่ผ่าน TLS หรือคงไว้เป็น plain HTTP ทั้งคู่ภายในเครือข่ายส่วนตัว
จากนั้นคือเรื่องการยืนยันตัวตน store จะถามหาข้อมูลประจำตัวของ Jellyfin ดังนั้นคนแปลกหน้าที่พบ URL นี้จะพบกับหน้าล็อกอิน แต่มีฟีเจอร์หนึ่งที่เปลี่ยนเรื่องนี้ การเปิดใช้งาน Remote Play ในเมนู Settings แล้วไปที่ Connection จะเป็นการส่งมอบเซสชัน Jellyfin ของคุณให้กับเซิร์ฟเวอร์ เพื่อให้ผู้ที่เข้ามาที่ /remote.html ได้ใช้งาน instance ของคลังสื่อจริงของคุณ นี่คือจุดประสงค์ของฟีเจอร์นี้ ซึ่งหมายความว่าความลับของ URL คือสิ่งที่กั้นระหว่างอินเทอร์เน็ตกับภาพยนตร์ของคุณ หากคุณเปิดใช้งาน Remote Play ให้ติดตั้ง single sign on ไว้หน้าเว็บไซต์ทั้งหมดด้วย Authentik ในฐานะเกตเวย์ SSO แบบ self-hosted หรือเลิกใช้ชื่อโฮสต์สาธารณะแล้วเข้าถึง store ผ่าน WireGuard tunnel ที่จัดการด้วย wg-easy
มีรายละเอียดสองประการที่ต้องทำควบคู่กันไป reverse proxy จะนำพาเฉพาะข้อมูลของ store เท่านั้น: สตรีมของ Remote Play เป็น WebRTC ผ่าน UDP ซึ่งไม่ผ่าน HTTP proxy ดังนั้นจึงต้องเปิดเส้นทางของตัวเองที่พอร์ต 3478/udp และช่วง 49200 ถึง 49260/udp เมื่อมีการใช้งาน TURN relay ที่มาพร้อมกัน และค่า docker run แบบ plain ด้านบนนั้นไม่ได้เก็บ volume ไว้ ดังนั้น seed ของ Remote Play จะไม่คงอยู่หลังจากการทำ docker rm ไฟล์ Compose จึงต้อง mount volume halcyon-data ไว้ที่ /data และตั้งค่า REMOTE_PLAY_SEED เป็น /data/remote-play-seed.json ด้วยเหตุผลนี้โดยเฉพาะ
สิ่งที่ควรทำเมื่อร้านค้าทำงานได้ไม่ดี
Halcyon จะแสดงผลตามความต้องการ ร้านค้าที่ไม่ได้ใช้งานจะไม่มีการรวมเฟรม (composite) และการสูญเสียโฟกัสของหน้าต่างจะหยุดลูปการแสดงผล ซึ่งเป็นเหตุผลว่าทำไมการเปิดแท็บทิ้งไว้จึงไม่ทำให้แบตเตอรี่แล็ปท็อปหมด สิ่งนี้ช่วยเครื่องที่มีประสิทธิภาพจำกัดได้บ้าง แต่ไม่มีผลกับเครื่องที่ไม่สามารถวาดร้านค้าได้เลย
สำหรับไคลเอนต์เหล่านั้นจะมีโหมด 2.5D ซึ่งเป็น HTML และ CSS ธรรมดาที่ไม่มี WebGL ออกแบบมาสำหรับฮาร์ดแวร์ขนาดเล็กอย่าง Raspberry Pi คุณสามารถสลับระหว่าง 3D และ 2.5D ได้จากเมนูการตั้งค่าหรือเมนูพลังงานโดยไม่ต้องโหลดหน้าเว็บใหม่ ดังนั้นการทดสอบทั้งสองโหมดบนอุปกรณ์เดียวกันจึงใช้เวลาเพียงไม่กี่วินาที โปรดมองความเป็นจริงเกี่ยวกับสิ่งที่คุณจะได้รับ: ผู้เขียนอธิบายว่าโหมดแบนราบนี้ยังมีความหยาบและอยู่ในระหว่างการพัฒนา ให้ถือว่าเป็นทางเลือกสำรองสำหรับไคลเอนต์ที่มีประสิทธิภาพต่ำ
เมื่อไคลเอนต์มีประสิทธิภาพต่ำเกินกว่าจะแสดงผลร้านค้าแบบ 3D ความล้มเหลวจะเกิดขึ้นอย่างชัดเจน แท็บจะโหลดตัวเองใหม่ หรือเบราว์เซอร์จะรายงานว่า WebGL context สูญหาย โดยปกติจะเกิดขึ้นในขณะที่ชั้นวางกำลังโหลดข้อมูล ให้เปลี่ยนอุปกรณ์นั้นไปใช้โหมด 2.5D แทนการลดขนาดคลังข้อมูลของคุณ
ตรึงเวอร์ชันของอิมเมจและตรวจสอบก่อนทำการ pull
ให้ความสำคัญกับส่วนนี้อย่างจริงจัง แท็ก v0.1.0 ถึง v0.3.1 ทั้งหมดถูกปล่อยออกมาภายในเวลาไม่กี่วัน และ v0.2.1 มีอยู่เพียงเพราะการ push อิมเมจสำหรับ v0.2.0 ล้มเหลว อัตราการปล่อยอัปเดตไม่ได้ช้าลงเลยนับตั้งแต่นั้นมา โดย v0.25.0 ถูกเผยแพร่เมื่อวันที่ 7 ตุลาคม 2026 ซึ่งเป็นเวลาสามวันหลังจาก v0.23.0 ทางต้นน้ำยินดีรับรายงานข้อผิดพลาด แต่ไม่รับ patch ดังนั้น release stream นี้จึงเป็นเพียงสถานะการทำงานของบุคคลคนเดียวเท่านั้น
การรัน latest ด้วยความเคยชินในการใช้ docker pull หมายความว่าที่เก็บข้อมูลอาจเปลี่ยนแปลงไปโดยที่คุณไม่รู้ตัวในวันอังคารปกติวันใดวันหนึ่ง ให้ตรึงเวอร์ชันด้วย digest ซึ่งเป็นข้อมูลอ้างอิงเดียวที่ไม่สามารถเปลี่ยนแปลงได้
docker buildx imagetools inspect ghcr.io/halcyon-video/halcyon-video:0.25.0คำสั่งนี้จะแสดงค่า digest ที่อยู่เบื้องหลังแท็ก ให้ใช้ค่านี้แทนการใช้แท็ก
docker run -d --name halcyon -p 1420:1420 --restart unless-stopped \
ghcr.io/halcyon-video/halcyon-video@sha256:7fc00e619a30004d275faa79ad36d810e5a8530757132603065ba4e848dd67dedigest ดังกล่าวคือ 0.25.0 ณ วันที่ 9 ตุลาคม 2026 ให้ตรวจสอบค่าปัจจุบันด้วยตนเองแทนการคัดลอก และอ่านบันทึกประจำรุ่น (release notes) ก่อนที่คุณจะทำการย้ายเวอร์ชัน เนื่องจาก patch release ในที่นี้อาจมีการเปลี่ยนแปลงโครงสร้างที่เก็บข้อมูลควบคู่ไปกับการแก้ไขข้อผิดพลาดได้
FAQ
Halcyon จำเป็นต้องใช้ GPU บน VPS ของฉันหรือไม่?
ไม่จำเป็นสำหรับการใช้งานทั่วไป หน้าร้านถูกเรนเดอร์ด้วย three.js ในเบราว์เซอร์ ดังนั้นเครื่องของผู้ใช้งานจะเป็นผู้ประมวลผลการแสดงผล และคอนเทนเนอร์ทำหน้าที่เพียงเสิร์ฟไฟล์สแตติกผ่านพอร์ต 1420 เท่านั้น ข้อยกเว้นคือฟีเจอร์ Remote Play ซึ่งจะรัน headless Chromium บนเซิร์ฟเวอร์และสตรีมผลลัพธ์ออกมา กระบวนการนี้จะเรนเดอร์บน CPU เว้นแต่คุณจะแมป /dev/dri เข้าไปในคอนเทนเนอร์เพื่อใช้การเร่งความเร็วด้วยฮาร์ดแวร์
ฉันสามารถนำ Halcyon ไปวางบนอินเทอร์เน็ตสาธารณะได้หรือไม่?
ทำได้ต่อเมื่อมีการป้องกันด้วยการยืนยันตัวตนเท่านั้น หน้าร้านจะเรียกขอข้อมูลรับรองของ Jellyfin แต่การเปิดใช้งาน Remote Play จะเป็นการส่งมอบเซสชัน Jellyfin ของคุณให้กับเซิร์ฟเวอร์ ดังนั้นใครก็ตามที่โหลด /remote.html จะได้รับอินสแตนซ์ของคลังสื่อจริงของคุณโดยไม่ต้องล็อกอิน คุณควรติดตั้ง reverse proxy ที่มีระบบ single sign on ไว้ด้านหน้า หรือเก็บชื่อโฮสต์ไว้เป็นความลับไม่ให้ปรากฏบน public DNS และเข้าถึงหน้าร้านผ่าน VPN แทน
ทำไมชั้นวางสื่อถึงว่างเปล่าหลังจากที่ฉันล็อกอินแล้ว?
เบราว์เซอร์จะเรียกใช้ Jellyfin API โดยตรง ดังนั้น Jellyfin จะต้องสามารถเข้าถึงได้จากเบราว์เซอร์ ไม่ใช่แค่จาก VPS เท่านั้น ให้เปิดคอนโซลของเบราว์เซอร์ดู หากพบ blocked by CORS policy หมายความว่า Jellyfin ไม่ยอมรับคำขอจากที่อยู่ของ Halcyon ส่วนข้อความ Mixed Content หมายความว่าหน้าเว็บรันอยู่บน HTTPS ในขณะที่ที่อยู่ Jellyfin ที่คุณระบุเป็น HTTP ธรรมดา
ฉันจำเป็นต้องใช้ --network host หรือไม่?
จำเป็นเฉพาะสำหรับการใช้งาน Remote Play เท่านั้น WebRTC จำเป็นต้องประกาศที่อยู่จริงของเครื่อง และเมื่ออยู่หลัง Docker bridge คอนเทนเนอร์จะเสนอได้เพียงที่อยู่ 172.x ซึ่งโทรศัพท์ในเครือข่ายของคุณไม่สามารถเข้าถึงได้ สำหรับการเรียกดูหน้าร้านในเบราว์เซอร์ทั่วไป การใช้ -p 1420:1420 ก็เพียงพอแล้วและมีความปลอดภัยต่อโฮสต์มากกว่า
ฉันควรใช้ image tag ใด?
ควรระบุเจาะจงที่ digest แทนการใช้ latest ให้ตรวจสอบ digest สำหรับเวอร์ชันที่มี docker buildx imagetools inspect ghcr.io/halcyon-video/halcyon-video:0.25.0 แล้วรันด้วย digest นั้น และค่อยอัปเดตหลังจากอ่านบันทึกการเปลี่ยนแปลง (release notes) แล้วเท่านั้น ณ วันที่ 9 ตุลาคม 2026 อิมเมจที่เผยแพร่รองรับทั้ง linux/amd64 และ linux/arm64 ดังนั้นโฮสต์ที่เป็น arm64 สามารถดึงอิมเมจไปใช้งานได้ทันทีโดยไม่ต้องทำการ build จาก source code ที่ clone มา