Lyra

Lyra Kurulumu (detaylı)

Tek yol var: install.sh. Script sistemi hazırlar, systemd unit'i ve sudoers dosyalarını sihirbazdan önce kurar, sonra panele nasıl erişileceğini sorar ve sihirbazı ona göre yayına alır. Kısa özet için ../INSTALL.md'ye bak; bu dosya aynı akışı daha ayrıntılı anlatır.

1. Tek komut installer

git clone https://github.com/eminerolll/andromeda-lyra.git lyra
cd lyra
sudo ./install.sh

Repo'yu klonlamadan, tek satırda:

curl -fsSL https://raw.githubusercontent.com/eminerolll/andromeda-lyra/main/install.sh | sudo LYRA_REPO=https://github.com/eminerolll/andromeda-lyra.git bash

curl | sudo bash akışında stdin script'in kendisi olduğu için hiçbir soru sorulmaz — script otomatik olarak --non-interactive gibi davranır.

Script sırasıyla:

  1. Root / distro (apt + systemd) / mimari (x86_64 ya da aarch64) kontrolü, hedef Linux kullanıcısının tespiti.
  2. Sistem paketleri (git curl ca-certificates iproute2 build-essential sudo) + Node.js 20 (NodeSource) — eksikse kurar, varsa dokunmaz.
  3. Kaynak kodu /opt/lyra'ya alır (yerel checkout'tan kopya, git clone veya mevcut repo'yu git pull --ff-only ile günceller).
  4. npm ci --omit=dev (lock dosyası yoksa npm install --omit=dev).
  5. .env üretir (LYRA_HOME=/var/lib/lyra, LYRA_PORT, NODE_ENV) — dosya zaten varsa üzerine yazmaz. Veri dizinini oluşturur.
  6. DB migrasyonlarını çalıştırır.
  7. systemd unit'i ve kalıcı sudoers dosyasını (/etc/sudoers.d/lyra) yazar — bu adım kurulum sihirbazından önce gelir, bilinçli sıralama.
  8. Erişim yöntemi. Bulut metadata servisini (169.254.169.254) kısa bir timeout'la yoklar, sonra üç seçenekli menüyü gösterir (aşağıda).
  9. Seçime göre: kurulum modu drop-in'i (LYRA_SETUP_MODE=1 + ProtectSystem=off; bkz. Sandbox)
    • geçici sudoers dosyası (/etc/sudoers.d/lyra-setup) + gerekiyorsa UFW'de sihirbaz portu + systemctl enable --now lyra, ya da doğrudan terminal sihirbazı.
  10. Kurulum token'i üretir, adresi ve token'ı ekrana basar.

Kurulum daha önce tamamlanmışsa (yönetici hesabı zaten var), script menüyü ve sihirbazı atlar; sadece repo'yu güncelleyip servisi yeniden başlatır — yani sudo ./install.sh güncelleme komutu olarak da idempotenttir.

Erişim yöntemi menüsü (adım 8)

# Yöntem Ne olur
1 cf-api Cloudflare API token + domain istenir; sihirbazdan önce tunnel + ingress + DNS kurulur, cloudflared servis olur. Sihirbaz https://<panel-host> üzerinde açılır. Açılan port yok.
2 direct Bugünkü davranış: sihirbaz LYRA_SETUP_PORT (varsayılan 80) üzerinde 0.0.0.0'a bind olur.
3 cli Sihirbaz o terminalde başlar (scripts/setup-cli.js). Port gerekmez.

Neden var: Oracle Cloud, AWS, GCP ve Azure'da gelen portlar sağlayıcının Security List / Security Group / NSG katmanında varsayılan olarak kapalıdır. Instance içinde ufw pasif olsa bile port 80 dışarıdan erişilemez; lib/firewall.js doğru davranıp hiçbir şeye dokunmaz ama kullanıcı yine de açılmayan bir URL alır. Menü bu kararı en başa taşır.

Bulut tespiti src/lib/cloud-detect.js içinde, dört sağlayıcıyı ayırt eder:

Sağlayıcı Prob Doğrulama
Oracle GET /opc/v2/instance/, Authorization: Bearer Oracle gövdede compartmentId / regionInfo
AWS PUT /latest/api/token (IMDSv2) → GET /latest/meta-data/ listede instance-id / ami-id
GCP GET /computeMetadata/v1/, Metadata-Flavor: Google cevapta Metadata-Flavor: Google başlığı
Azure GET /metadata/instance?api-version=2021-02-01, Metadata: true gövdede compute

Prob'lar paralel çalışır ve timeout toplam bütçedir (varsayılan 1.5 sn): ağ yoksa veya adres yönlendirilmiyorsa modül sessizce null döner ve kurulum gecikmez. Bulut tespit edilirse 2. seçenek varsayılan olmaz; edilmezse bugünkü davranış korunur.

--access bayrağıyla menü atlanabilir; cf-api için --domain ve token (LYRA_CF_API_TOKEN env'i, --cf-api-token) zorunludur, eksikse kurulum hiç başlamadan hata verir.

Ortam değişkenleri

Değişken Varsayılan Amaç
LYRA_REPO — git repo URL'i (yerel checkout yoksa zorunlu)
LYRA_DIR /opt/lyra kurulum dizini
LYRA_BRANCH main git branch
LYRA_USER $SUDO_USER Lyra'nın çalışacağı Linux kullanıcısı
LYRA_HOME /var/lib/lyra veri dizini (SQLite DB, oturumlar)
LYRA_PORT 3000 panel portu
LYRA_SETUP_PORT 80 kurulum sihirbazı portu — yalnızca direct yönteminde
LYRA_CF_API_TOKEN — cf-api yönteminde Cloudflare API token'ı

Bayraklar: -y / --yes / --non-interactive (hiçbir şey sorma), --access <cf-api\|direct\|cli>, --domain, --cf-api-token, --cf-account-id, --cf-host-mode, --cf-panel-subdomain, --cf-overwrite-dns, --cf-tunnel-name, --cf-tunnel-existing, --replace-cloudflared, -h / --help.

Yeniden kurulumda iki çakışma çıkar ve ikisi de kurulum başlamadan yakalanır: sunucuda duran cloudflared servisi (--replace-cloudflared ile değiştirilir) ve Cloudflare hesabında aynı adda duran tunnel (--cf-tunnel-existing reuse|recreate, ya da --cf-tunnel-name <ad>). Aktif bağlantısı olan tunnel hiçbir ayarla devralınmaz — başka bir makinede canlı olabilir. Varsayılan fail: karar verilmeden hiçbir şey devralınmaz veya silinmez.

Token --cf-api-token ile verilirse install.sh onu çocuk process'in argümanına koymaz: 0600 geçici bir dosyaya yazıp yolunu geçirir (--cf-api-token-file) ve trap ... EXIT ile her durumda siler.

2. Tarayıcıdaki sihirbaz

Script bittiğinde ekrana adres(ler) ve 1 saat geçerli bir kurulum token'ı basar. Laptop tarayıcısında bu adresi aç, token'ı yapıştır. Sihirbaz adımları:

  1. Token doğrulama
  2. Erişim modu — Public / LAN / Localhost / CF Tunnel / Manuel. Tunnel kurulum sırasında (yöntem 1) hazırlandıysa bu adım atlanır; sihirbaz /api/setup/status cevabındaki cfProvisioned bayrağını görür, "Cloudflare: yapılandırıldı ✓" gösterir ve panel adresini yazar.
  3. Bağlantı + panel — moda göre domain+email ya da CF connector token'ı; ayrıca uygulama adı ve projeler dizini
  4. Yönetici hesabı — kullanıcı adı, şifre (≥12 karakter), TOTP QR
  5. Servisler — seç, Lyra kursun, panele bağlansın (code-server, filebrowser, dbgate, mongod). Kurulu olan tekrar kurulmaz; kurulamayan seçenek sebebiyle birlikte devre dışı kalır (bkz. Servis kurulumu)
  6. Entegrasyonlar (opsiyonel) — Telegram bot, GitHub token
  7. İlerleme — Caddy/cloudflared, seçilen servislerin kurulumu, firewall, restart; her adımın durumu /api/setup/progress üzerinden canlı gösterilir

Son adımda Lyra kurulum modu drop-in'ini ve geçici sudoers dosyasını kendisi siler, daemon-reload yapar ve kendini yeniden başlatır — tarayıcı bu sırada bağlantı kopmasını "yeniden başlıyor" olarak yorumlar ve yeni adreste /healthz yanıt verene kadar bekler.

Bir adım başarısız olursa kurulum modu açık bırakılır, ekranda ne yapılması gerektiği net şekilde yazar.

2.2 Servis kurulumu

Lyra bir geliştirici ortamı yöneticisi; yönettiği servisleri de kendisi kurar (lib/service-installer.js). Taze bir sunucuda sihirbazın servis adımı boş kalmaz.

Servis RAM Kurulum kaynağı arm64
code-server ~200 MB https://code-server.dev/install.sh (resmi .deb), unit: code-server@<kullanıcı> ✓
filebrowser ~30 MB github.com/filebrowser/filebrowser release tarball (linux-<arch>-filebrowser.tar.gz) + Lyra'nın yazdığı filebrowser.service ✓
dbgate ~150 MB docker.io/dbgate/dbgate imajı + Lyra'nın yazdığı dbgate.service ✓
mongod ~500 MB repo.mongodb.org/apt (mongodb-org 8.0; ubuntu focal/jammy/noble, debian bookworm) ✓

Kurallar:

Loopback değişmezi (pazarlık yok). Kurulan her servis yalnızca 127.0.0.1'e bind edilir. Servisler kendi auth'unu kapatır çünkü dışarıya tek kapı Lyra'nın login + 2FA + ban katmanıdır; bu yalnızca loopback'te doğrudur.

Servis Nasıl garanti ediliyor
code-server ~/.config/code-server/config.yaml → bind-addr: 127.0.0.1:8080, auth: none, cert: false
filebrowser unit ExecStart=… -a 127.0.0.1 -p 8082 … --noauth
dbgate docker run … -p 127.0.0.1:8081:3000 (host'suz -p üretilmez)
mongod varsayılan zaten loopback; değiştirilmez, doğrulanır. bindIp loopback dışındaysa servis başlatılmaz ve hata bildirilir

Yapılandırmaları üreten fonksiyonlar saf ve test altındadır (test/service-installer.test.js → "loopback degismezi"): 0.0.0.0 içeren bir direktif üretilirse test kırılır.

Sandbox: neden kurulum modu drop-in'i gerekli

Bu servisler /usr ve /usr/local altına yazar (code-server .deb, filebrowser binary'si /usr/local/bin'e, mongod apt paketi). Lyra'nın systemd unit'inde ProtectSystem=full var: systemd /usr, /boot ve /etc'yi bu servis için salt-okunur mount eder. Kurulum Lyra'nın process ağacında çalıştığı için o mount namespace'ini miras alır — bu bir izin sorunu değil, sudo da kurtarmaz:

dpkg: unable to create '/usr/bin/code-server.dpkg-new': Read-only file system
install: cannot create regular file '/usr/local/bin/filebrowser': Read-only file system

Bu yüzden install.sh'in yazdığı geçici drop-in (lyra.service.d/setup-mode.conf) her iki erişim yönteminde de ProtectSystem=off taşır. Yol yol ReadWritePaths açmak yerine bu seçildi: dpkg'nin yazma kümesi açık uçlu ve üçüncü parti kurucular her sürümde yeni yol ekleyebilir; liste kaçınılmaz olarak eksik kalır. Gevşeme yalnızca kurulum fazındadır — drop-in sihirbaz bitince silinir.

Değişmez test/scripts.test.js ile kilitli: drop-in yazan her dal /usr yazma iznini vermeli, normal-mode unit'i ise ProtectSystem=full kalmalı.

Kurulum sonrası servis eklemek

Kurulum bittikten sonra sandbox tekrar devrededir, yani panelden servis kurulamaz. Kurulum, Lyra'nın process ağacının dışında ayrı bir root process olarak yapılır:

lyra install-service --list              # kurulabilirler + kurulamama sebepleri
sudo lyra install-service code-server
sudo lyra install-service filebrowser
lyra status                              # "Kayitli servisler" altında görünür

Komut aynı lib/service-installer.js'i çağırır (loopback değişmezi korunur), başarılı kurulumu services tablosuna kendisi yazar ve ~/.config altına root olarak yazdığı dosyaların sahipliğini servis kullanıcısına devreder. Kurulum yine "Read-only file system" derse lyra.service üzerinden çalışıyorsun demektir — komutu doğrudan kabuktan sudo ile çalıştır.

3. Erişim katmanları

Kurulumdan sonra üç servis (code-server, dosya yöneticisi, veritabanı arayüzü) ve dev server portları her zaman path-tabanlı olarak erişilebilir, domain olsun olmasın:

Bu, domain gerektirmeyen Katman 1'dir (lib/path-proxy.js). Sihirbazda bir base_domain girilirse, ek olarak host-tabanlı subdomain katmanı (lib/proxy.js) devreye girer: code.<domain>, files.<domain>, db.<domain> gibi. Domain katmanı path katmanını devre dışı bırakmaz — ikisi birlikte çalışır.

dev-<port> subdomain'leri hiçbir modda üretilmez (port sayısı sınırsız olabileceğinden); dev server önizlemesi her zaman /dev/<port>/ path'inden servis edilir.

4. Setup wizard'ın sorduğu değerler

Terminal sihirbazı (headless)

src/scripts/setup-cli.js yukarıdaki aynı soruları terminalde sorar. İki arayüz de src/lib/setup-core.js üzerinden çalışır:

Ortak fonksiyon Ne yapar
validateFinalize Alan doğrulaması (mod, şifre uzunluğu, moda özel zorunlular, 2FA)
ensureProjectsDir Projeler dizinini yaratır ve gerçekten yazma denemesi yapar
cfPlanFromBody / cfPreflight Cloudflare token/zone/hesap doğrulaması, mevcut DNS kayıtlarını okuma, apex-mi-subdomain önerisi
applyFinalize Settings + admin + servisler + entegrasyonlar + system_ports / lyra_service_name seed'i. Kurulacak servisleri installServices olarak döner
servicesToInstall / runServiceInstalls Seçilenlerden hangileri kurulacak; kurulum döngüsü (biri patlarsa diğerleri devam eder)
buildSteps / createProgress / runPostSetup Caddy / cloudflared / servis kurulumları / firewall / kurulum modundan çıkış adımları
provisionCloudflare Tunnel'ı sihirbazdan önce kurar (install.sh yöntem 1). runCfApiSteps ile aynı zinciri çalıştırır, sonra access_mode / base_domain / panel_host / public_access ve cf_provisioned ayarlarını yazar
isCfProvisioned / cfProvisionedInfo "Cloudflare zaten kuruldu mu?" — üç yer de (HTTP, CLI, buildSteps) buna bakar

routes/setup.js bu fonksiyonların HTTP sarmalayıcısıdır; CLI ise terminal sarmalayıcısı. Doğrulama veya seed kuralı değişirse ikisi birden değişir — kopya yok (test/setup-core.test.js bunu doğrular).

install.sh de kendi Cloudflare mantığını yazmaz: yöntem 1'de scripts/setup-cli.js --provision-tunnel çağırır, o da askCfApi + cfPreflight + provisionCloudflare ile aynı çekirdeği kullanır. Bash tarafında ne Cloudflare API çağrısı ne de DNS çakışma mantığı vardır.

cf_provisioned bayrağı ayarlandıktan sonra:

Tek gerçek fark, kurulum modundan çıkışın kim tarafından tetiklendiğidir (runPostSetup'ın transition seçeneği):

2FA'da QR yerine TOTP secret'ı ve otpauth:// URI'si terminale basılır; interaktif modda kod doğrulanmadan 2FA açılmaz. Non-interactive modda --2fa verilirse secret ekrana basılır (kaybedilirse lyra reset-admin --disable-2fa); --2fa/--no-2fa'dan biri zorunludur, varsayılana kaçılmaz.

Bayrakların tam listesi: node scripts/setup-cli.js --help ve ../INSTALL.md → "Headless kurulum".

5. Sudoers — iki dosya

sudo rm -f /etc/sudoers.d/lyra-setup

İçeriği yeniden üretmek istersen:

node /opt/lyra/src/scripts/generate-sudoers.js --print   # icerigi gor
sudo node /opt/lyra/src/scripts/generate-sudoers.js --user <kullanici>

6. Ban yönetimi

Başarısız girişlerden sonra otomatik IP ban devreye girer. Banlı IP'leri görmek, elle ban eklemek/kaldırmak ve ban ayarlarını (eşik, süre) değiştirmek için SSH ya da DB erişimi gerekmez — Lyra dashboard'da Ayarlar > Güvenlik sekmesinden panelden yönetilir.

7. systemd servisi

sudo systemctl status lyra
sudo systemctl restart lyra
sudo journalctl -u lyra -f

Unit'i elden geçirmek istersen:

sudo node /opt/lyra/src/scripts/generate-systemd.js --print   # icerigi gor
sudo node /opt/lyra/src/scripts/generate-systemd.js \
  --user <kullanici> --workdir /opt/lyra/src \
  --home /var/lib/lyra --port 3000 --projects-dir /home/<kullanici>/projects
sudo systemctl daemon-reload && sudo systemctl restart lyra

8. lyra komutu

install.sh kurulumun sonunda /usr/local/bin/lyra symlink'ini src/bin/lyra.js'e kurar. Komut yeni bir işlev eklemez; var olan script'leri ve modülleri çağırır:

Komut Ne yapar Nereye bağlanır
lyra status Servis durumu, sürüm, erişim modu, panel adresi, bind, DB boyutu, caddy/cloudflared durumu, kayıtlı servisler lib/health.js + db/repos/settings
sudo lyra update [--skip-pull] git pull --ff-only + npm ci --omit=dev + npm run migrate + systemctl restart + doğrulama git / npm / db/migrate.js
sudo lyra uninstall [--keep-data] [--yes] Kaldırma uninstall.sh
lyra reset-admin [...] Şifre / 2FA / ban sıfırlama scripts/reset-admin.js
lyra logs [args] Servis logları (varsayılan -f) journalctl -u lyra
lyra connect [...] Laptop tarafı SSH tunnel yardımcısı lyra-connect

Root gerektiren alt komutlar (update, uninstall) root olmadan çalıştırılırsa ne yapılması gerektiğini söyleyip çıkar; yarım iş yapmaz.

reset-admin, root olarak çağrılsa bile servis kullanıcısına düşerek çalışır — aksi hâlde SQLite'ın -wal/-shm yan dosyaları root'a ait oluşup servisin yazmasını engellerdi.

Güncelleme

sudo lyra update

Git deposunu --ff-only çeker, bağımlılıkları kurar, migrasyonları çalıştırır, servisi yeniden başlatır ve ayağa kalktığını doğrular. .env ve veritabanına dokunmaz.

Git deposu yoksa (kod elle kopyalanmışsa) lyra update bunu fark eder ve sessizce yarım iş yapmak yerine durur:

✗ /opt/lyra bir git deposu degil — kod otomatik guncellenemez.
    Bu kurulum elle kopyalanmis (tar/scp/rsync).
    Yeni surumu ayni dizine kopyala, sonra:
      sudo lyra update --skip-pull

--skip-pull yalnızca kod çekme adımını atlar; npm ci, migrasyon ve restart yine çalışır.

install.sh ile güncelleme de mümkün (unit ve sudoers dosyalarını da yeniler):

cd /opt/lyra
sudo ./install.sh -y

Elle:

cd /opt/lyra && sudo -u <kullanici> git pull --ff-only
cd src && sudo -u <kullanici> npm ci --omit=dev
sudo -u <kullanici> npm run migrate          # idempotent
sudo systemctl restart lyra

Kaldırma

sudo lyra uninstall               # listeler + onay ister
sudo lyra uninstall --keep-data   # /var/lib/lyra kalsın
sudo lyra uninstall --yes         # onay sorma
# lyra komutu yoksa:
sudo bash /opt/lyra/uninstall.sh

uninstall.sh silmeden önce ne silineceğini listeler ve onay ister (--yes ile atlanır). Kaldırdıkları:

Bilerek dokunmadıkları (silmiş gibi yapmak yerine listeler):

Ayrıca LYRA_DIR / LYRA_HOME /, /etc, /usr, /var, /home, /opt gibi bir yola işaret ediyorsa script hiçbir şey silmeden durur.

Tamamen elle:

sudo systemctl disable --now lyra
sudo rm -f /etc/systemd/system/lyra.service
sudo rm -rf /etc/systemd/system/lyra.service.d
sudo rm -f /etc/sudoers.d/lyra /etc/sudoers.d/lyra-setup
sudo rm -f /usr/local/bin/lyra
sudo systemctl daemon-reload
sudo rm -rf /opt/lyra /var/lib/lyra