SSD Nodes Learn Hosting plans →
Rehberler Matt ConnorYazan Matt Connor · Güncellendi 2026-08-27

Halcyon ile Jellyfin Kutuphanesini Video Magazasi Yapma

Halcyon kullanarak Jellyfin kütüphanenizi 90'lar video mağazasına dönüştürün. Docker kurulumu, reverse proxy yapılandırması ve tek kişilik geliştirme sürecinin kısıtları.

Halcyon'un Jellyfin kütüphaneniz üzerindeki etkisi

Halcyon Video, Jellyfin kütüphanenizi tarayıcı üzerinde gezilebilir bir 1990'lar video mağazasına dönüştürür. Sahip olduğunuz her film, raftaki bir kutu haline gelir. Floresan ışıkların altında koridorlarda yürür, bir kutuyu raftan çeker, teknik özellikleri okumak için arkasını çevirir ve oynatmayı başlatmak için kasaya götürürsünüz. Oynatma durumu, ilerleme ve durdurma bilgileri Jellyfin'e geri raporlanır; böylece kaldığınız yerden devam etme noktaları ve izleme geçmişi doğru kalır.

Halcyon, mevcut bir Jellyfin sunucusunu Jellyfin API üzerinden okur ve kendine ait bir kütüphane tutmaz. Bu kılavuz, Jellyfin'in halihazırda çalıştığını ve düzgün bir şekilde tarama yaptığını varsayar. Eğer durum böyle değilse, önce bir VPS üzerinde medya sunucusu olarak Jellyfin kurulumunu yapın ve kütüphaneniz normal web istemcisinde düzgün göründüğünde geri dönün. Bu, kütüphaneniz zaten hazır olduğu için kuracağınız türden bir yazılımdır; self-hosting listenize yeni bir servis eklemeniz gerektiği için değil.

Proje GPL-3.0 lisanslıdır ve tek bir kişi tarafından yazılmıştır; README dosyası, pull request kabul edilmediğini açıkça belirtir. Geliştirme süreci hızlı ilerlemektedir ve bir gerilemeyi (regression) fark edecek ikinci bir bakım sorumlusu yoktur; bu nedenle mağazayı başkasına göstermeden önce imaj sürümünü sabitleyin. Son bölüm bunun nasıl yapılacağını açıklamaktadır.

İşleme (rendering) nerede gerçekleşir?

Tarayıcıda. Halcyon, GPU'ya erişim sağlayan tarayıcı arayüzü WebGL aracılığıyla 3D grafikler çizen bir JavaScript kütüphanesi olan three.js üzerine inşa edilmiş bir Vite ve TypeScript uygulamasıdır. Mağaza geometrisi ve kutu görselleri, ekranı barındıran makine tarafından birleştirilir.

Container çok az işlem yapar. npm run serve komutunu çalıştırır, bu da vite preview --port 1420 --strictPort --host anlamına gelir ve derlenmiş dosyalar ile birkaç küçük ara katman (middleware) rotasını sunar. Halcyon sunucu tarafında herhangi bir kod dönüştürme (transcoding) yapmaz ve herhangi bir motor çalıştırmaz.

Dolayısıyla GPU sorusu istemciyi ilgilendirir. Küçük bir VPS bunu rahatlıkla sunabilir, çünkü sunum işlemi HTTP üzerinden statik dosya aktarımından ibarettir. Mağazanın akıcı bir şekilde hareket edip etmeyeceğine veya takılıp takılmayacağına tarayıcıyı çalıştıran dizüstü bilgisayar, tablet veya televizyon karar verir.

Bir özellik bu kuralı bozar. Remote Play, sunucuda başsız (headless) Chromium örnekleri oluşturur ve işlenen mağaza görüntüsünü WebRTC (web real time communication) üzerinden bir telefona veya set üstü kutuya aktarır. Bu yol, sunucu üzerinde işleme yapar; varsayılan olarak iki örnekle sınırlıdır ve REMOTE_PLAY_MAX_INSTANCES ile ayarlanabilir. Eşlenmiş bir /dev/dri cihazı olmadığında bu örnekler CPU üzerinde işlenir, bu nedenle iki çekirdekli bir VPS her ek izleyiciyi ciddi şekilde hisseder.

Mağazanın kütüphanenizden okudukları

Reyonlar, Jellyfin'in kendi yapısından gelir. Halcyon, kütüphanelerinizden ve türlerinizden bölümler oluşturur ve devam filmlerini BoxSets öğelerinizden gruplandırır. Her kutunun arkasında yazılı olan teknik özellikler, Jellyfin'in halihazırda tuttuğu MediaStreams meta verilerinden gelir; bu da Jellyfin'de eksik olan herhangi bir bilginin rafta da eksik olacağı anlamına gelir.

Bu durum, mağazayı meta verilerinizin adil bir yansıması haline getirir. Docker Compose üzerinde bir arr yığını ile beslenen, görselleri ve türleri önceden doldurulmuş bir kütüphane, burada genel isimlere sahip dağınık dosya klasörlerinden çok daha iyi görünür. Fotoğraf kütüphaneleri de onları indeksleyen her ne ise ona aynı bağımlılığa sahiptir; aynı sunucuda duran fotoğraflar için PhotoPrism ile Immich'i karşılaştırırken bunu göz önünde bulundurmakta fayda vardır.

Herhangi bir kurulum yapmadan önce video mağazası demosunu deneyin

Proje, tüm mağazayı sentetik bir kütüphane üzerinde çalışacak şekilde barındırılan demo adresinde yayınlamaktadır. Herhangi bir Halcyon URL'sinin sonuna ?demo=1 eklemek, kendi kurulumunuzda da aynı işlemi gerçekleştirir.

Bunu bir donanım testi olarak kullanın. Demo kütüphanesi yaklaşık 2.000 başlık barındırır ve tarayıcı belleğinde kabaca 2 GB yer kaplar; bu, çoğu kişisel kütüphaneden daha ağırdır. Eğer demo, tarayıcıyı kullanmayı planladığınız cihazda takılıyorsa, kendi kütüphaneniz de takılacaktır. Bu durumda çözüm, daha büyük bir VPS değil, aşağıda açıklanan 2.5D modudur.

Docker ile çalıştırma

Upstream belgelerinde belirtilen komut budur.

docker run -d --name halcyon --network host --restart unless-stopped \
  ghcr.io/halcyon-video/halcyon-video

Ardından servisin ayağa kalktığını doğrulayın.

docker logs halcyon
curl -I http://127.0.0.1:1420

Log kayıtları, önizleme sunucusunun 1420 numaralı portu dinlediğini ve curl adresinin HTTP/1.1 200 OK yanıtını verdiğini göstermelidir. Birkaç saniye içinde kapanan bir container, neredeyse her zaman port çakışması yaşıyordur. --strictPort hatası, 1420 numaralı port dolu olduğunda sunucunun 1421 numaralı porta geçmeyi reddedip doğrudan durduğunu gösterir.

--network host parametresi mağaza için değil, Remote Play içindir. WebRTC, makinenin gerçek adresini yayını almak isteyen cihaza bildirmek zorundadır. Varsayılan Docker bridge arkasında container yalnızca kendi 172.x adresini bilir; ağınızdaki hiçbir telefon bu adrese erişemeyeceği için yayın bağlantısı kurulamaz. Eğer mağazayı yalnızca tarayıcı üzerinden kullanmak istiyorsanız, portu yayınlamanız yeterlidir.

docker run -d --name halcyon -p 1420:1420 --restart unless-stopped \
  ghcr.io/halcyon-video/halcyon-video

VPS üzerinde varsayılan olarak tercih edilmesi gereken yöntem budur; çünkü host networking, container'ı makinenin sahip olduğu tüm arayüzlere (genel ağ arayüzü dahil) bağlar. VPS üzerinde Docker çalıştırma rehberi bu konudaki diğer detayları ele almaktadır. --restart unless-stopped parametresi, mağazanın yeniden başlatma sonrasında tekrar ayağa kalkmasını sağlar; bu, Boot sırasında başlayan Compose servisleri ile aynı mantıktır.

Depoyu klonlayıp docker compose up -d komutunu çalıştırmak, imajı yerel olarak derler. Mevcut Compose dosyası varsayılan olarak kaynak koddan derleme yapar ve image: satırı yorum satırı olarak gelir; eğer yayınlanmış imajı Compose ile kullanmak isterseniz bu satırı aktif hale getirin.

Ağustos 2026 itibarıyla katı bir kısıtlama mevcuttur: yayınlanan imaj yalnızca linux/amd64 mimarisini desteklemektedir. Çoklu mimari (multi-architecture) gönderiminin arm64 kısmı emülasyon altında başarısız olmuştur ve yerel arm çalıştırıcıları beklenmektedir. Bir arm64 VPS üzerinde çekme işlemi no matching manifest for linux/arm64/v8 in the manifest list entries hatası ile başarısız olur; bu durumda çözüm, depoyu klonlayarak yerel derleme yapmaktır.

Jellyfin sunucunuzu işaretleyin

http://<host>:1420 uygulamasını açın ve Jellyfin sunucu adresiniz, kullanıcı adınız ve parolanızla giriş yapın. Depodaki .env.local.example dosyası yalnızca yerel geliştirme içindir. Vite, VITE_ ön ekiyle başlayan değişkenleri istemci tarafındaki koda dahil eder; bu nedenle buraya yazılan bir Jellyfin parolası, her ziyaretçinin indirdiği JavaScript paketinin içine derlenir. Başkalarının erişebildiği bir sunucuda, arayüz üzerinden giriş yapın.

Tarayıcı, Jellyfin ile doğrudan iletişim kurar. Halcyon container'ı Jellyfin API'sini proxy'lemez; hata ayıklamaya başlamadan önce bilinmesi gereken iki sonuç doğurur.

Birincisi, Jellyfin'in yalnızca Halcyon'u sunan VPS'ten değil, tarayıcıdan da erişilebilir olması gerekir. 127.0.0.1:8096 adresine bağlı bir Jellyfin yerel test için uygundur ancak diğer herkes için rafların boş görünmesine neden olur.

İkincisi, çağrı Halcyon adresinden Jellyfin adresine çapraz kökenli (cross origin) bir istektir. Jellyfin, API isteklerini varsayılan olarak Access-Control-Allow-Origin: * ile yanıtlar, bu nedenle ek bir yapılandırma gerekmeden çalışır. Eğer bu ayarı kısıtladıysanız veya Jellyfin API'sinin önüne bir kimlik doğrulama proxy'si koyduysanız, tarayıcı konsolu blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource hatası verir ve mağaza boş raflarla yüklenir.

Bir reverse proxy arkasına alın ve önüne kimlik doğrulama ekleyin

vite preview bir önizleme sunucusudur. TLS (transport layer security) sonlandırması yapmaz ve kendi erişim kontrol mekanizmasına sahip değildir; bu nedenle herkese açık herhangi bir ortamda nginx veya Caddy arkasında çalıştırılmalıdır.

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;
  }
}

Konteynerin önündeki alan adı için bir ayar daha gereklidir. Halcyon, DNS rebinding saldırılarına karşı bir önlem olarak localhost, ham IP adresleri ve üzerinde çalıştığı makinenin isimlerine yanıt verir. Konteyner içinde makine ismi konteynerin kendisidir, yani sizin belirlediğiniz alan adı değildir. halcyon.example.com olarak gelen bir istek reddedilir ve yanıt içerisinde reddedilen ana bilgisayar ismi belirtilir. Bu ismi ekleyin.

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

Değer virgülle ayrılır; .example.com gibi başında nokta olan bir ifade alt alan adlarıyla eşleşir, all ise kontrolü devre dışı bırakır. all seçeneğine yalnızca dışarıdan erişilemeyen bir makinede başvurun.

Mağaza https:// üzerinden sunulduğunda, giriş yaparken yazdığınız Jellyfin adresi de https:// olmalıdır. Tarayıcı, HTTPS sayfasından yapılan düz bir http:// API çağrısını engeller ve konsolda Mixed Content: The page at 'https://halcyon.example.com/' was loaded over HTTPS, but requested an insecure resource hatası görünür. Giriş işlemi, Halcyon içinde herhangi bir açıklama olmaksızın başarısız olur. Her ikisini de TLS üzerinden sunun veya özel bir ağ içerisinde her ikisini de düz HTTP üzerinde tutun.

Sırada kimlik doğrulama var. Mağaza, Jellyfin kimlik bilgilerinizi ister; bu sayede URL'yi bulan yabancılar bir giriş ekranıyla karşılaşır. Bir özellik bunu değiştirir. Ayarlar ve ardından Bağlantı altında Uzaktan Oynatma (Remote Play) özelliğini açmak, Jellyfin oturumunuzu sunucuya aktarır; böylece /remote.html adresini ziyaret edenler kendi gerçek kütüphane örneğinize erişebilir. Özelliğin amacı budur ve bu, URL'nin gizliliğinin internet ile filmleriniz arasındaki tek engel olduğu anlamına gelir. Uzaktan Oynatma özelliğini etkinleştirirseniz, sitenin tamamının önüne Authentik ile self-hosted SSO ağ geçidi kurarak tek oturum açma (SSO) ekleyin veya genel alan adını kaldırıp mağazaya wg-easy ile yönetilen bir WireGuard tüneli üzerinden erişin.

Bununla ilgili iki ayrıntı mevcuttur. Reverse proxy yalnızca mağaza trafiğini taşır: Uzaktan Oynatma akışı UDP üzerinden WebRTC'dir ve HTTP proxy üzerinden geçmez; bu nedenle 3478/udp portunda ve yerleşik TURN rölesi kullanımdayken 49200 ile 49260/udp port aralığında kendi yoluna ihtiyaç duyar. Ayrıca yukarıdaki düz docker run herhangi bir birim (volume) tutmaz, bu yüzden Uzaktan Oynatma verisi docker rm sonrasında kalıcı olmaz. Compose dosyası, tam da bu nedenle /data yoluna bir halcyon-data birimi bağlar ve REMOTE_PLAY_SEED değerini /data/remote-play-seed.json olarak ayarlar.

Mağaza kötü çalıştığında ne yapılmalı

Halcyon, isteğe bağlı olarak render işlemi gerçekleştirir. Boşta duran bir mağaza hiçbir kareyi birleştirmez ve pencere odağının kaybedilmesi animasyon döngüsünü durdurur; bu nedenle açık bırakılan bir sekme dizüstü bilgisayar pilini tüketmez. Bu durum, sınırda performans gösteren bir makineye yardımcı olur. Ancak mağazayı hiç çizemeyen bir makine için bir etkisi yoktur.

Bu tür istemciler için, Raspberry Pi kadar küçük donanımlar düşünülerek tasarlanmış, WebGL içermeyen düz HTML ve CSS yapısındaki 2.5D modu mevcuttur. 3D ve 2.5D arasında, sayfa yenilemeye gerek kalmadan ayarlar veya güç menüsü üzerinden geçiş yapabilirsiniz; bu nedenle her iki modu aynı cihazda test etmek saniyeler sürer. Elde edeceğiniz sonuç konusunda gerçekçi olun: yazar, düz modu kaba ve geliştirilmekte olan bir aşama olarak tanımlamaktadır. Bunu zayıf istemciler için bir yedek çözüm olarak değerlendirin.

Bir istemci 3D mağaza için çok yetersiz kaldığında, hata belirgin şekilde ortaya çıkar. Sekme kendini yeniden yükler veya tarayıcı, genellikle raflar henüz dolarken, WebGL bağlamının kaybedildiğini bildirir. Kütüphanenizi küçültmek yerine, bu cihazı 2.5D moduna geçirin.

İmajı sabitleyin ve çekmeden önce kontrol edin

Bu konuyu ciddiye alın. v0.1.0 ile v0.3.1 arasındaki tüm etiketler birkaç gün arayla yayınlandı ve v0.2.1 sadece v0.2.0 için yapılan imaj gönderimi başarısız olduğu için var. Hata bildirimleri upstream tarafında kabul edilir, yamalar ise kabul edilmez; bu nedenle sürüm akışı tek bir kişinin çalışma durumunu yansıtır.

latest komutunu docker pull alışkanlığıyla çalıştırmak, herhangi bir sıradan Salı günü deponun altınızda değişebileceği anlamına gelir. Değiştirilemez tek referans olan digest değerini kullanarak sabitleme yapın.

docker buildx imagetools inspect ghcr.io/halcyon-video/halcyon-video:0.3.1

Bu komut, etiketin arkasındaki digest değerini yazdırır. Etiket yerine bu değeri kullanın.

docker run -d --name halcyon -p 1420:1420 --restart unless-stopped \
  ghcr.io/halcyon-video/halcyon-video@sha256:747dcc821a3d2fa318b50e76024783c1835609047e84f502e23d021bc1898b20

Söz konusu digest değeri 10 Ağustos 2026 tarihinde 0.3.1 idi. Kopyalamak yerine güncel değeri kendiniz okuyun ve geçiş yapmadan önce sürüm notlarını inceleyin; çünkü buradaki bir yama sürümü, düzeltmelerin yanı sıra depo düzeni değişikliklerini de içerebilir.

FAQ

Halcyon VPS üzerinde GPU gerektirir mi?

Normal kullanım için gerekmez. Mağaza arayüzü tarayıcıda three.js ile çizilir; bu nedenle render işlemi istemci makinede gerçekleşir ve container yalnızca 1420 numaralı port üzerinden statik dosyaları sunar. İstisna durum olan Remote Play, sunucuda başsız (headless) Chromium çalıştırır ve sonucu yayınlar. Donanım hızlandırma için /dev/dri container içine eşlenmediği sürece bu yol CPU üzerinde render edilir.

Halcyon'u genel internete açabilir miyim?

Yalnızca kimlik doğrulama arkasında tutulmalıdır. Mağaza, Jellyfin kimlik bilgilerinizi ister ancak Remote Play özelliğini açmak, Jellyfin oturumunuzu sunucuya aktarır. Bu durumda /remote.html adresini yükleyen herkes, giriş yapmadan gerçek kütüphanenize erişebilir. Önüne tek oturum açma (SSO) özellikli bir reverse proxy yerleştirin veya ana makine adını genel DNS kayıtlarından gizleyerek mağazaya bir VPN üzerinden erişin.

Giriş yaptıktan sonra raflar neden boş görünüyor?

Tarayıcı, Jellyfin API'sini doğrudan çağırır; bu nedenle Jellyfin'in yalnızca VPS'ten değil, tarayıcıdan da erişilebilir olması gerekir. Tarayıcı konsolunu açın. blocked by CORS policy hatası, Jellyfin'in Halcyon adresinden gelen isteği kabul etmediği anlamına gelir. Mixed Content mesajı ise sayfanın HTTPS üzerinde çalıştığını, ancak girdiğiniz Jellyfin adresinin düz HTTP olduğunu belirtir.

--network host kullanmam gerekiyor mu?

Yalnızca Remote Play için gereklidir. WebRTC, makinenin gerçek adresini duyurmak zorundadır; Docker köprüsü arkasında ise container, ağınızdaki hiçbir telefonun ulaşamayacağı bir 172.x adresi sunabilir. Mağazayı tarayıcıda görüntülemek için -p 1420:1420 yeterlidir ve ana makineyi çok daha az riske atar.

Hangi image etiketini kullanmalıyım?

latest yerine bir digest değerini sabitleyin. docker buildx imagetools inspect ghcr.io/halcyon-video/halcyon-video:0.3.1 içeren bir sürümün digest değerini okuyun, bu digest ile çalıştırın ve yalnızca sürüm notlarını okuduktan sonra güncelleyin. Ağustos 2026 itibarıyla yayınlanan imaj yalnızca linux/amd64 mimarisi içindir; bu nedenle bir arm64 ana makinesi, docker compose up -d kullanarak klondan derleme yapmalıdır.