VPS uzerinde dsh servisi nasil calistirilir
dsh aracini bir VPS uzerinde systemd servisi olarak calistirarak SSH oturumu kapandiginda islemin kesilmesini engelleyin. Ozel kullanici, Restart kurallari ve log kaydi icin adimlar.
dsh aracını bir terminal yerine VPS üzerinde headless olarak çalıştırma
dsh aracını bir VPS üzerinde headless olarak çalıştırmak için bir systemd birim dosyası ve bu dosyaya sahip özel bir kullanıcı hesabı gerekir. dsh, DeepSeek'in Ağustos 2026'da geliştirici önizlemesi olarak MIT lisansı altında yayınlanan ajan çalışma zamanı DeepSeek Harness için komut satırı başlatıcısıdır. Hızlı başlangıç kılavuzu npx @deepseek-ai/dsh web komutunu girmenizi söyler; bu komut doğrudur ancak SSH (secure shell) oturumunuzu kapattığınız anda sonlanır.
Bir birim dosyası aynı anda dört sorunu çözer. Servis, yeniden başlatma sonrasında otomatik olarak ayağa kalkar. Çıktısı, ekranınızdan akıp gitmek yerine journal içerisine kaydedilir. root olmayan bir hesapla çalışır. Ayrıca çalıştırılan sürüm, sizin seçtiğiniz sürüm olur; bu durum, geliştiricilerin büyük harflerle belirttiği üzere burada her zamankinden daha önemlidir:
DeepSeek Harness şu anda geliştirici önizlemesi aşamasındadır ve hızla güncellenmektedir. GERİYE DÖNÜK UYUMLULUĞU BOZAN DEĞİŞİKLİKLER OLACAKTIR.
Bu kılavuz, dsh aracının manuel olarak zaten çalıştığını varsayar. Eğer çalışmıyorsa, önce DeepSeek Harness aracının bir VPS üzerine kurulması adımlarıyla başlayın ve npx @deepseek-ai/dsh web bir sayfa sunduğunda geri dönün.
Önce Node, çünkü npm sizi uyarmayacaktır
node -vUbuntu 24.04'ün kendi paketi olan Node 18 (Ağustos 2026 itibarıyla 18.19.1), bu yıl yayınlanan bir paket için eskidir. @deepseek-ai/dsh herhangi bir engines alanı yayınlamaz, bu nedenle Node sürümünüz çok eski olduğunda npm herhangi bir EBADENGINE uyarısı vermez. Hata, çalışma zamanında söz dizimi hatası veya eksik bir yerleşik işlev olarak ortaya çıkar; bu da hatayı tespit etmek için çok daha kötü bir durumdur. NodeSource üzerinden güncel bir uzun süreli destek (LTS) sürümü yükleyin:
curl -fsSL https://deb.nodesource.com/setup_22.x -o /tmp/nodesource_setup.sh
less /tmp/nodesource_setup.sh
sudo -E bash /tmp/nodesource_setup.sh
sudo apt install -y nodejs
node -vnode -v artık v22 bir sürüm çıktısı vermelidir. less satırı oradadır çünkü uzak bir betiği doğrudan bash içine yönlendirmek, hiç okumadığınız bir kodu çalıştırmanıza neden olur.
Unit dosyasını yazmadan önce çalıştığını doğrulayın
npx @deepseek-ai/dsh@0.1.0-rc.7 webBu süreci çalışır durumda bırakın. İkinci bir SSH oturumundan şunları yapın:
curl -fsS http://127.0.0.1:3080/ -o /dev/null && echo upup, web profilinin varsayılan olarak bağlandığı loopback arayüzünü dinlediği anlamına gelir. curl: (7) Failed to connect to 127.0.0.1 port 3080: Connection refused ise dinlemediğini gösterir; bu durumda ilk terminal size nedenini bildirecektir. İlerlemeden önce manuel çalıştırmayı Ctrl+C ile durdurun: başka bir sürecin halihazırda kullandığı bir portu bağlamaya çalışan bir unit, Error: listen EADDRINUSE: address already in use 127.0.0.1:3080 hatası ile başarısız olur.
0.1.0-rc.7, 18 Ağustos 2026 tarihinde yayınlanan sürümdür. npm view @deepseek-ai/dsh version komutu ile güncel sürümü kontrol edin ve çalıştırmaya karar verdiğiniz sürümü sabitleyin.
Sabitlediğiniz sürümü global olarak yükleyin
npx, unit dosyası içinde kullanmak için yanlış bir araçtır. Süreç başladığında paket sürümünü çözümler; bu nedenle üç ay sonra yapılacak bir yeniden başlatma, sizin tarafınızda hiçbir değişiklik olmasa bile önizleme aşamasındaki bir aracın farklı bir derlemesini çalıştırabilir. Ayrıca önyükleme sırasında npm kayıt defterine erişilebilmesi gerekir; bu durum, kayıt defterinin yavaş olduğu bir günde çalışan bir makineyi başarısız bir unit haline getirir. Not ettiğiniz bir sürümü bir kez yükleyin:
sudo npm install -g @deepseek-ai/dsh@0.1.0-rc.7
command -v dsh
npm ls -g --depth=0 @deepseek-ai/dshcommand -v dsh, npm NodeSource'tan geldiğinde /usr/bin/dsh, Ubuntu'nun kendi paketinden geldiğinde ise /usr/local/bin/dsh çıktısını verir. Unit dosyası içinde gerçekten yazdırdığı yolu kullanın. npm ls -g, davranış değiştiğinde ve ne yüklediğinizi hatırlayamadığınızda altı hafta sonra ihtiyacınız olan cevap olan tam sürümü yazdırır.
Servisin sahibi olan ve başka hiçbir yetkisi bulunmayan bir kullanıcı
Aracı, shell komutlarını çalıştırır. Görevi budur. Aracı root olarak çalıştırmak, her araç çağrısını bir root çağrısı haline getirir; bu nedenle araca, giriş shell'i olmayan özel bir hesap tanımlayın.
sudo useradd --system --create-home --home-dir /var/lib/dsh --shell /usr/sbin/nologin dsh
sudo install -d -o dsh -g dsh -m 750 /var/lib/dsh/harness /var/lib/dsh/workspace
id dsh/var/lib/dsh/harness, dsh'nin profilleri tuttuğu dizin olan DSH_HOME haline gelir. Bir profil, kendi yama katmanınızın üzerinde yer alan adlandırılmış bir eklenti paketleri yığınıdır ve web ile headless profilleri, ilk kez başlattığınızda gönderilen şablonlardan kendilerini oluşturur. Bu ilk başlatma işlemi dosyaları yazar ve paketleri indirebilir, bu yüzden süreci izleyebileceğiniz bir ortamda manuel olarak gerçekleştirin.
sudo -u dsh env HOME=/var/lib/dsh DSH_HOME=/var/lib/dsh/harness /usr/bin/dsh --profile websudo'ün bu konuda ne yaptığına güvenmek yerine HOME değerini açıkça ayarlayın; çünkü sudo'in giriş yapmayan bir komut için HOME'yı yeniden yazıp yazmayacağı, /etc/sudoers içindeki set_home ayarına bağlıdır. Bu ayarı yanlış yaparsanız, ilk çalıştırma sırasında önbellek dizinleri dsh tarafından sahiplenilen sizin ev dizininize düşer ve servis daha sonra kendi durumunu bulamaz. curl kontrolü up döndürdüğünde Ctrl+C ile işlemi durdurun.
Unit dosyası
/etc/systemd/system/dsh.service dosyasını oluşturun:
[Unit]
Description=DeepSeek Harness (dsh) web profile
Documentation=https://github.com/deepseek-ai/deepseek-harness
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=5
[Service]
Type=exec
User=dsh
Group=dsh
WorkingDirectory=/var/lib/dsh/workspace
Environment=HOME=/var/lib/dsh
Environment=DSH_HOME=/var/lib/dsh/harness
ExecStart=/usr/bin/dsh --profile web
Restart=on-failure
RestartSec=5s
TimeoutStopSec=30s
SyslogIdentifier=dsh
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
[Install]
WantedBy=multi-user.targetExecStart=, command -v dsh komutundan elde ettiğiniz mutlak yolu alır. systemd, yalın bir komut ismi için sabit bir yol listesinde arama yapar; ancak bu liste kabuğunuzun PATH değişkeni ile aynı değildir, bu nedenle mutlak yol kullanmak belirsizliği ortadan kaldırır.
WorkingDirectory=, göreli yolların çözümlendiği yerdir ve herhangi bir argüman almadan ls komutunu çalıştıran bir araç çağrısının başladığı dizindir. Burayı, aracı teslim ettiğiniz çalışma alanına yönlendirin. Dizin eksikse veya servis kullanıcısı dizine erişemiyorsa, servis status=200/CHDIR hatasıyla başarısız olur ve dsh hiç çalışmaz.
ProtectHome=true, /home ve /root dizinlerini süreçten gizler. Servisin eriştiği her şey /var/lib/dsh altında bulunduğu için bu yapı güvenlidir. Çalışma alanını /home altında bir yola yönlendirirseniz, aracı dizinin mevcut olmadığını raporlar; bu durum, ilgili satırı hatırlayana kadar kafa karıştırıcı olabilir. ProtectSystem=full, /usr, /boot ve /etc dizinlerini salt okunur hale getirir; servisin bu dizinlere yazma ihtiyacı yoktur.
Daha ileri gitmek cazip gelse de genellikle yanlıştır. ProtectSystem=strict, çekirdek sözde dosya sistemleri (pseudo-filesystem) haricinde tüm dosya sistemini salt okunur yapar; bu durumda dosya yazmaya çalışan ilk araç çağrısı EROFS: read-only file system hatasıyla başarısız olur. Bu seviyede bir kısıtlama istiyorsanız, aynı düzenleme içerisinde ReadWritePaths=/var/lib/dsh satırını ekleyin.
Buraya Hangi Type= Gelmeli
Type=exec, çünkü dsh ön planda kalır ve asla fork işlemi gerçekleştirmez. Bunun varsayılan ayara göre sağladığı avantaj, gerçek bir hata mesajı alabilmenizdir. Type=simple ile systemd, ikili dosyanın var olup olmadığını dahi bilmeden, fork işlemi gerçekleşir gerçekleşmez başlatma işlemini başarılı olarak işaretler; bu nedenle systemctl start dsh temiz bir şekilde döner ve hata yalnızca günlük kayıtlarında (journal) görünür. Type=exec ile systemd, execve() işleminin başarılı olmasını bekler; bu sayede ExecStart= içindeki bir yazım hatası, komutu girdiğiniz anda başarısız olur ve hatayı doğrudan görürsünüz.
Yanlış olan iki seçenek de askıda kalır. Type=forking, systemd'ye bir üst sürecin (parent process) sonlanmasını beklemesini söyler; dsh asla sonlanmadığı için başlatma işlemi TimeoutStartSec süresi dolana kadar (varsayılan olarak 90 saniye) engellenir ve ardından Job for dsh.service failed because a timeout was exceeded. raporlanır. Type=notify, sd_notify üzerinden bir READY=1 mesajı bekler; bu mesajı asla göndermeyen bir Node süreci de aynı şekilde takılı kalır. systemd servis türlerinin tam karşılaştırması, notify yapılandırmasının ne zaman zahmete değer olduğu da dahil olmak üzere geri kalan detayları kapsar.
Hata veren yeniden başlatma kuralları
Restart=on-failure, sıfır olmayan bir çıkış kodunda veya ölümcül bir sinyalde yeniden başlatma yapar; temiz bir çıkıştan sonra ise birimi olduğu gibi bırakır. Bir önizleme sürümü için istenen davranış budur. Eğer dsh, beğenmediği bir yapılandırmayı okuduğu için 0 koduyla çıkış yaparsa, birim durur ve durmuş halde kalır; systemctl status dsh ise bunu görebileceğiniz inactive (dead) durumunu gösterir. Restart=always ise aynı olayı, uzaktan bakıldığında sağlıklı görünen bir yeniden başlatma döngüsüne dönüştürür.
Hız sınırlaması, insanların göz ardı ettiği kısımdır. systemd varsayılanları on saniye içinde beş başlatmadır ve RestartSec=5s ile on saniyelik bir pencerede beş başlatmaya asla ulaşamazsınız; bu nedenle başlangıçta çöken bir birim sonsuza kadar yeniden başlar ve bunu yalnızca journal bilir. StartLimitIntervalSec=300 ve StartLimitBurst=5 kullanımı, beş dakika içinde beş başarısızlığın yeterli olduğu anlamına gelir: systemd pes eder ve birimi failed durumuna park ederek Start request repeated too quickly. günlüğünü tutar. Sorunun nedenini giderdikten sonra bu durumu sudo systemctl reset-failed dsh ile temizleyin. Her iki ayar da [Service] içinde değil, [Unit] içinde yer almalıdır; yanlış bölümde tanımlandıklarında systemd bunları sessizce görmezden gelir.
Başlatın ve kontrol edin
sudo systemctl daemon-reload
sudo systemctl enable --now dsh
systemctl status dshenable --now iki işlevi yerine getirir. enable, servisin yeniden başlatma sonrasında tekrar ayağa kalkmasını sağlar; --now ise servisi mevcut oturumda başlatır. Sadece systemctl start kullanıldığında yapılan işlem bir sonraki yeniden başlatmada kaybolur; çekirdek güncellemeleri ise yeniden başlatma gerektirir.
systemctl status dsh komutu; Active: active (running), bir Main PID ve bir Memory: satırı göstermelidir. Ardından servisin hangi adresi dinlediğini doğrulayın:
sudo ss -lntp | grep 3080127.0.0.1:3080 çıktısını görmeniz gerekir. Eğer 0.0.0.0:3080 ifadesini görüyorsanız, bir yapılandırma bind adresini değiştirmiştir ve ajanınız genel internete açıktır. Bu çıktıdaki süreç adı dsh değil, node olarak görünür; çünkü dsh ikili dosyası bir Node betiğidir ve bu nedenle pgrep -x dsh komutu hiçbir sonuç döndürmez. Bunun yerine systemctl show -p MainPID dsh kullanın.
Ardından sistemi bir kez yeniden başlatın. Yeniden başlatma sonrasında çalışmayan bir servis, henüz tam anlamıyla bir servis sayılmaz.
sudo rebootSunucuya tekrar bağlanın ve systemctl is-active dsh komutunu çalıştırın. Bu komut active çıktısını verecektir.
journalctl ile günlük kayıtlarını okuma
dsh tarafından stdout ve stderr'e yazılan her şey, birim adı altında journal içinde saklanır.
journalctl -u dsh -f
journalctl -u dsh -n 200 --no-pager
journalctl -u dsh --since "10 min ago" -p err-f yeni satırları takip eder, -n son N adet satırı gösterir, -p err ise önceliğe göre filtreleme yapar. Birim içindeki SyslogIdentifier=dsh, bu satırların neden node yerine dsh olarak etiketlendiğini açıklar; bu durum, birim bazında filtrelenmemiş journal çıktısını ilk kez okurken önem arz eder.
İhtiyaç duymadan önce journal'ın yeniden başlatmalardan sonra varlığını koruduğunu doğrulayın:
journalctl -u dsh -b -1Eğer bu komut Specifying boot ID or boot offset has no effect, no persistent journal was found çıktısını verirse, journal /run dizininde tutuluyor demektir ve her yeniden başlatmada silinir. İlgili dizini oluşturun ve servisi yeniden başlatın:
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journaldUI'ye genel bir port üzerinden değil, SSH tüneli üzerinden erişin
dsh, web arayüzünü (UI) 127.0.0.1:3080 üzerinde sunar ve başka herhangi bir yerde sunmayı reddeder. --host 0.0.0.0 istendiğinde şu hata ile durur:
error: --host 0.0.0.0 is intentionally not supported yet for safety: it would expose remote code execution to the network; use 127.0.0.1 insteadBu, aşılması gereken bir kısıtlama değildir. Web API (uygulama programlama arayüzü) ajanı yönetir ve ajan kabuk komutları çalıştırır; dolayısıyla erişilebilir bir port, onu bulan herkes için VPS'nizde bir kabuk anlamına gelir. Geliştiriciler, uzak kimlik doğrulama özelliğinin henüz inşa edilmemiş olmasını, bağlantının loopback ile sabitlenmesinin nedeni olarak belirtmektedir. Bunun yerine portu kendi makinenizden yönlendirin:
ssh -N -L 3080:127.0.0.1:3080 you@203.0.113.10-L 3080:127.0.0.1:3080, dizüstü bilgisayarınızda 3080 numaralı portu açar ve oraya gelen her şeyi VPS üzerinde çözümlendiği şekliyle 127.0.0.1:3080 adresine gönderir. -N, uzak komut çalıştırmayın anlamına gelir; böylece oturum yalnızca tüneli açık tutar. Çalışır durumda bırakın ve tarayıcınızda http://127.0.0.1:3080/ adresini açın. DeepSeek API anahtarını Settings ve ardından Models altında gireceğiniz ve çalışma alanı dizinini seçeceğiniz yer burasıdır. Çalışma alanını, servis kullanıcısının sahibi olduğu /var/lib/dsh/workspace dizinine yönlendirin; aksi takdirde ajanın dosya araçları EACCES: permission denied hatasıyla başarısız olur.
Eğer 3080 numaralı port dizüstü bilgisayarınızda meşgulse, ssh bunu şu şekilde bildirir:
bind [127.0.0.1]:3080: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 3080ssh -N -L 3081:127.0.0.1:3080 you@203.0.113.10 ile farklı bir yerel port seçin ve ardından http://127.0.0.1:3081/ adresine gidin. Kendi makinenizdeki ~/.ssh/config dosyasında yazma işlemini kaydedin:
Host dsh-vps
HostName 203.0.113.10
User you
LocalForward 3080 127.0.0.1:3080Bundan sonra, ssh -N dsh-vps komutun tamamıdır. Bu tünel artık ajanınıza açılan tek kapıdır, bu nedenle onu koruyan şey SSH daemon'dır: yalnızca anahtarlar, parola kimlik doğrulaması yok ve VPS'nizde SSH'ı güçlendirme konusundaki geri kalan kurallar her zamankinden daha güçlü bir şekilde geçerlidir.
Anahtar, unit dosyasında bulunmamalıdır. Environment= değerleri, sunucudaki herhangi bir kullanıcının çalıştırabileceği systemctl show dsh -p Environment tarafından yazdırılır. Yüklediğiniz bir eklenti ortamda bir anahtara ihtiyaç duyuyorsa, bunu root tarafından sahip olunan ve 600 moduna sahip /etc/dsh.env dosyasına koyun ve EnvironmentFile=/etc/dsh.env ile referans verin. systemd bu dosyayı yürütme anında root olarak okur ve systemctl show içeriğini yazdırmaz.
Çalıştırma maliyeti
Çıkarım işlemi sizin VPS'nizde değil, DeepSeek API üzerinde gerçekleşir. Sunucunuz Node sürecinin, sunduğu arayüzün ve ajanın çalıştırmaya karar verdiği her komutun maliyetini karşılar. İlk ikisi sabit ve düşüktür. Üçüncüsü ise bu birim dosyasında herhangi bir sınıra tabi değildir.
Başkasına ait bir rakama güvenmek yerine, kendi sunucunuzdaki alt sınırı kendiniz ölçün:
systemctl show dsh -p MemoryCurrent
systemd-cgtop -1 --depth 2MemoryCurrent bayt cinsindendir. Değeri, ajan boşta beklerken değil, çalışırken izleyin.
Araç çağrıları servisin alt süreçleridir; bu nedenle aynı kontrol grubuna dahil edilirler ve aynı sınırlara tabidirler. Çalışma alanı içinde npm install veya bir test paketi çalıştıran bir ajan, ana süreçten çok daha fazla bellek kullanabilir. 1 GB RAM'e sahip bir VPS'de sorun burada başlar: çekirdek bir süreci seçip sonlandırır ve journalctl -k | grep -i "out of memory", seçtiği süreci belirten Out of memory: Killed process satırını gösterir. Bu süreç genellikle soruna neden olan süreç değildir.
Çözüm, bilinçli olarak belirlediğiniz bir sınırdır. [Service] bölümündeki MemoryMax= ve CPUQuota= ayarları, hasarı birim içinde tutar; böylece kontrolden çıkan bir derleme işlemi tüm sunucuyu kilitlemek yerine sonlandırılır. systemd ile bellek ve CPU sınırlama bölümü, sayısal değerleri ve hata davranışlarını ele alır. Disk kullanımı da DSH_HOME altındaki oturum geçmişi ve ajanın çalışma alanına yazdığı veriler nedeniyle artar; bu yüzden du -sh /var/lib/dsh değerini disk izleme için kullandığınız araca ekleyin.
Eğer etkileşimli, bağlanıp ayrılabileceğiniz bir ajan istiyorsanız, servis yapısı uygun değildir; kalıcı bir tmux oturumunda ajan çalıştırma yöntemi daha uygundur. dsh aracını, her zaman ayakta kalmasını ve bir tünel üzerinden erişilebilir olmasını istediğiniz durumlarda birim olarak çalıştırın.
Hata modları ve karşılaşacağınız dizgeler
status=203/EXEC. systemd dosyayı çalıştıramadı ve Failed to locate executable /usr/local/bin/dsh: No such file or directory günlüklerini oluşturdu. ExecStart= içindeki yol, command -v dsh çıktısıyla eşleşmiyor. Bu, Type=exec tarafından gizlenmek yerine systemctl start anında bildirilen hatadır.
status=217/USER. User= içindeki hesap mevcut değil. id dsh ile doğrulayın.
status=200/CHDIR. WorkingDirectory= eksik veya servis kullanıcısı bu dizine erişemiyor. sudo -u dsh ls /var/lib/dsh/workspace bunu doğrudan yeniden üretir.
Error: listen EADDRINUSE: address already in use 127.0.0.1:3080. Bir şey portu zaten tutuyor; bu genellikle başka bir terminalde açık bırakılan npx çalışmasıdır. sudo ss -lntp | grep 3080 süreci adlandırır.
EACCES: permission denied ve ardından bir yol. /var/lib/dsh altındaki sahiplik hatalı; bu genellikle ilk çalıştırmanın root olarak veya yanlış HOME ile yapılmasından kaynaklanır. sudo chown -R dsh:dsh /var/lib/dsh bunu düzeltir.
Start request repeated too quickly. Birim, başlatma hızı sınırına ulaştı ve vazgeçti. Asıl hata bunun üzerindeki satırlardadır. Tekrar denemeden önce sudo systemctl reset-failed dsh komutunu çalıştırın.
Birim active (running) durumunda ancak tarayıcı hiçbir şey göstermiyor. VPS üzerinde kontrolü çalıştırın: Eğer curl -fsS http://127.0.0.1:3080/ -o /dev/null && echo up orada up çıktısını veriyorsa, servis sağlıklıdır ve sorun port yönlendirmesindedir.
Bilinçli yükseltme
Sürüm sabitleme (pinning), yükseltmenin sizin kontrolünüzde gerçekleşen bir işlem olduğu anlamına gelir. Yükseltme öncesinde sürüm notlarını mutlaka okuyun; yukarı akış (upstream) kaynaklı uyumluluk bozucu değişiklik uyarıları, sabitleme işleminin temel nedenidir. Durum dizinini (state directory) yedekleyin ve ardından sürümü değiştirin:
sudo systemctl stop dsh
sudo tar czf /root/dsh-home-$(date +%F).tgz -C /var/lib/dsh harness
sudo npm install -g @deepseek-ai/dsh@0.1.0-rc.7
sudo systemctl start dsh
journalctl -u dsh -n 50 --no-pagerGeri alma işlemi, eski sürümle npm install -g yapılması ve ardından yedeklenen tarball dosyasının geri yüklenmesiyle gerçekleştirilir; bu yöntem yalnızca yedekleme alındıysa çalışır. Önizleme aşamasındaki bir aracı çalışma zamanı (agent runtime), yükseltme sırasında yapılandırma formatının sizin bilginiz dışında yeniden yazıldığı bir yazılım türüdür.
FAQ
Neden SSH oturumumu kapattığımda dsh duruyor?
Çünkü npx @deepseek-ai/dsh web, oturumunuza bağlı bir ön plan sürecidir ve oturum sonlandığında süreç de sonlandırılır. Bir systemd birimi ise init sistemine aittir; bu nedenle bağlantıyı kestiğinizde çalışmaya devam eder ve yeniden başlatma sonrasında tekrar başlar. sudo systemctl enable --now dsh, size her ikisini de sağlayan iki adımlı bir işlemdir: yeniden başlatma için enable, bu açılış için --now.
dsh için Type=simple mı yoksa Type=exec mi kullanmalıyım?
Type=exec. dsh ön planda çalışır ve hiçbir zaman fork etmez, bu yüzden her ikisi de çalışır; ancak Type=exec, systemd'nin başlatmanın başarılı sayılması için execve() sürecinin tamamlanmasını beklemesini sağlar. ExecStart= içindeki yanlış bir yol, systemctl start işleminin status=203/EXEC hatasıyla başarısız olmasına neden olur. Type=simple ile aynı hata başarı dönüştürür ve günlük kayıtlarında gizli kalır. Type=forking ve Type=notify burada yanlıştır ve her ikisi de TimeoutStartSec süresi 90 saniye sonra dolana kadar askıda kalır.
dsh web arayüzünü dizüstü bilgisayarımdan nasıl açarım?
Portu SSH üzerinden yönlendirin: ssh -N -L 3080:127.0.0.1:3080 you@your-vps, ardından tarayıcınızda http://127.0.0.1:3080/ adresini açın. Servisi genel bir adrese bağlamaya çalışmayın. dsh, --host 0.0.0.0 bağlantılarını error: --host 0.0.0.0 is intentionally not supported yet for safety: it would expose remote code execution to the network; use 127.0.0.1 instead hatasıyla reddeder; çünkü web API, aracın shell komutları çalıştırmasına izin verebilir ve önünde uzak kimlik doğrulama katmanı yoktur.
İzinleri basit tutmak için dsh'ı root olarak çalıştırabilir miyim?
Hayır. Harness, komut çalıştırmak ve dosya yazmak için tasarlanmıştır; dolayısıyla servisin sahip olduğu tüm yetkiler, aracın da yetkileri olur. useradd --system --shell /usr/sbin/nologin dsh ile bir sistem hesabı oluşturun, /var/lib/dsh dizininin sahipliğini bu hesaba verin ve birim dosyasına NoNewPrivileges=true ekleyin. Daha sonra EACCES: permission denied hatası alırsanız, bunun yaygın nedeni daha önce root olarak yapılan bir çalıştırmanın root sahipliğinde dosyalar bırakmış olmasıdır; sudo chown -R dsh:dsh /var/lib/dsh bu dosyaları temizler.
Birim dosyasında dsh'ın hangi sürümünü sabitlemeliyim?
Servisi kurarken npm view @deepseek-ai/dsh version ne bildiriyorsa onu kullanın, npm install -g @deepseek-ai/dsh@<that version> ile kurun ve bulabileceğiniz bir yere kaydedin. 0.1.0-rc.7, 18 Ağustos 2026 itibarıyla güncel sürümdü. Önemli olan sürüm numarası değil, sürüm belirtilmeyen npx komutunun paketi başlatma anında çözümlemesidir; bu durum, gözetimsiz bir yeniden başlatmanın sizi sessizce farklı bir yapılandırma formatına sahip bir sürüme geçirmesine neden olabilir.