SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-28

Jak uruchomić dsh jako usługę systemd na VPS

Skonfiguruj dsh jako usługę systemd, aby uniknąć zamykania procesu po zakończeniu sesji SSH. Poradnik obejmuje tworzenie dedykowanego użytkownika, reguły Restart oraz logi journalctl.

Uruchamianie dsh w trybie bezgłowym na VPS, poza terminalem

Uruchomienie dsh w trybie bezgłowym na VPS wymaga utworzenia pliku jednostki systemd oraz dedykowanego użytkownika, który będzie właścicielem procesu. dsh to wiersz poleceń służący do uruchamiania DeepSeek Harness, środowiska uruchomieniowego agentów DeepSeek, opublikowanego na licencji MIT w wersji poglądowej dla programistów w sierpniu 2026 roku. Harness to program otaczający model, a nie sam model, dlatego pod kontrolą systemd umieszczasz pętlę, narzędzia oraz uprawnienia, a nie proces wnioskowania DeepSeek. Szybki start zaleca wpisanie npx @deepseek-ai/dsh web, co jest poprawne, ale powoduje zamknięcie procesu w momencie zakończenia sesji SSH (secure shell).

Plik jednostki rozwiązuje cztery problemy jednocześnie. Usługa uruchamia się automatycznie po restarcie systemu. Jej wyjście trafia do dziennika zamiast znikać z ekranu. Proces działa na koncie innym niż root. Uruchamiana jest dokładnie ta wersja, którą wybrano, co jest tutaj szczególnie istotne, ponieważ twórcy oprogramowania zaznaczają to wielkimi literami:

DeepSeek Harness znajduje się obecnie w fazie developer preview i jest intensywnie rozwijany. WYSTĄPIĄ ZMIANY NIEKOMPATYBILNE WSTECZNIE.

Niniejszy przewodnik zakłada, że dsh działa już poprawnie przy ręcznym uruchomieniu. Jeśli tak nie jest, należy zacząć od instalacji DeepSeek Harness na VPS i wrócić, gdy npx @deepseek-ai/dsh web zacznie wyświetlać stronę.

Najpierw Node, ponieważ npm nie wyświetli ostrzeżenia

node -v

Pakiet Node w systemie Ubuntu 24.04 to wersja 18 (18.19.1 na sierpień 2026), co jest wersją przestarzałą jak na pakiet wydany w tym roku. @deepseek-ai/dsh nie publikuje żadnego pola engines, więc npm nie wyświetla ostrzeżenia EBADENGINE, gdy wersja Node jest zbyt stara. Błąd pojawia się dopiero w czasie wykonywania jako błąd składni lub brak wbudowanej funkcji, co jest znacznie trudniejsze do zdiagnozowania. Należy zainstalować bieżące wydanie o długoterminowym wsparciu (LTS) z repozytorium NodeSource:

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 -v

node -v powinno teraz wyświetlić wersję v22. Wiersz less znajduje się tam, ponieważ przesyłanie zdalnego skryptu bezpośrednio do bash uruchamia kod, którego użytkownik nie przeczytał.

Weryfikacja działania przed utworzeniem jednostki

npx @deepseek-ai/dsh@0.1.0-rc.7 web

Pozostaw ten proces uruchomiony. Z drugiej sesji SSH wykonaj:

curl -fsS http://127.0.0.1:3080/ -o /dev/null && echo up

up oznacza, że profil web nasłuchuje na interfejsie loopback, co jest domyślnym zachowaniem. curl: (7) Failed to connect to 127.0.0.1 port 3080: Connection refused oznacza, że tak nie jest, a pierwszy terminal wskazuje przyczynę. Zatrzymaj ręczne uruchomienie za pomocą Ctrl+C przed przejściem dalej: jednostka próbująca powiązać port zajęty przez inny proces zakończy się błędem Error: listen EADDRINUSE: address already in use 127.0.0.1:3080.

0.1.0-rc.7 była wersją opublikowaną 18 sierpnia 2026. Sprawdź aktualną wersję za pomocą npm view @deepseek-ai/dsh version, a następnie przypnij wybraną wersję do uruchomienia.

Instalacja przypiętej wersji globalnie

npx jest niewłaściwym narzędziem wewnątrz pliku jednostki. Rozwiązuje ono wersję pakietu w momencie uruchomienia procesu, więc restart wykonany za trzy miesiące może zainicjować inną kompilację agenta w fazie podglądu bez żadnej zmiany z Twojej strony. Wymaga to również dostępności rejestru npm podczas startu systemu, co sprawia, że działająca maszyna staje się niedziałającą jednostką w dniu, w którym rejestr działa wolno. Zainstaluj raz, używając wersji, którą zanotowałeś:

sudo npm install -g @deepseek-ai/dsh@0.1.0-rc.7
command -v dsh
npm ls -g --depth=0 @deepseek-ai/dsh

command -v dsh wyświetla /usr/bin/dsh, gdy npm pochodzi z NodeSource, oraz /usr/local/bin/dsh, gdy pochodzi z pakietów Ubuntu. Użyj ścieżki, która została faktycznie wyświetlona w pliku jednostki. npm ls -g wyświetla dokładną wersję, co jest odpowiedzią, której będziesz potrzebować za sześć tygodni, gdy zachowanie ulegnie zmianie, a Ty nie będziesz pamiętać, co zainstalowałeś. Jeśli instalacja się nie powiedzie, command -v dsh nie wyświetli nic po zakończeniu lub otrzymana wersja nie jest tą, o którą prosiłeś, przeanalizuj typowe błędy instalacji i wersji dsh przed przystąpieniem do tworzenia pliku jednostki.

Użytkownik będący właścicielem usługi i niczego więcej

Agent wykonuje polecenia powłoki. Na tym polega jego zadanie. Uruchamianie go jako root sprawia, że każde wywołanie narzędzia staje się wywołaniem z uprawnieniami roota, dlatego należy utworzyć dla niego osobne konto bez powłoki logowania.

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 staje się DSH_HOME, katalogiem, w którym dsh przechowuje profile. Profil to nazwany stos pakietów wtyczek z własną warstwą poprawek na wierzchu, a profile web oraz headless budują się same z dostarczonych szablonów przy pierwszym uruchomieniu. Wszystko, co dodasz do tego stosu później, działa jako ten użytkownik z dostępem do plików i powłoki agenta, więc weryfikacja wtyczki przed instalacją jest częścią tego samego zadania, co tworzenie konta. To pierwsze uruchomienie zapisuje pliki i może pobierać pakiety, więc wykonaj je ręcznie, aby móc je monitorować.

sudo -u dsh env HOME=/var/lib/dsh DSH_HOME=/var/lib/dsh/harness /usr/bin/dsh --profile web

Ustaw HOME jawnie, zamiast polegać na tym, co robi z nim sudo, ponieważ to, czy sudo nadpisuje HOME dla polecenia bez logowania, zależy od ustawienia set_home w /etc/sudoers. Błędna konfiguracja spowoduje, że pierwsze uruchomienie zapisze katalogi pamięci podręcznej w Twoim katalogu domowym, których właścicielem będzie dsh, a usługa później nie odnajdzie własnego stanu. Zatrzymaj proces za pomocą Ctrl+C, gdy sprawdzenie curl zwróci up.

Plik jednostki

Wpisz /etc/systemd/system/dsh.service:

[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.target

ExecStart= przyjmuje ścieżkę bezwzględną uzyskaną za pomocą command -v dsh. systemd przeszukuje ustaloną listę ścieżek dla samej nazwy polecenia, jednak lista ta nie jest zmienną PATH powłoki, dlatego ścieżka bezwzględna eliminuje niepewność.

WorkingDirectory= to miejsce, w którym rozwiązywane są ścieżki względne oraz punkt startowy dla wywołania narzędzia uruchamiającego ls bez argumentów. Wskaż katalog roboczy przekazany agentowi. Jeśli katalog nie istnieje lub użytkownik usługi nie ma uprawnień do wejścia do niego, jednostka zakończy działanie błędem status=200/CHDIR jeszcze przed uruchomieniem dsh.

ProtectHome=true ukrywa /home oraz /root przed procesem. Jest to bezpieczne, ponieważ wszystkie zasoby, do których odwołuje się usługa, znajdują się wewnątrz /var/lib/dsh. Wskazanie katalogu roboczego w ścieżce pod /home spowoduje, że agent zgłosi brak katalogu, co jest mylące, dopóki nie pamięta się o tej linii. ProtectSystem=full ustawia /usr, /boot oraz /etc w tryb tylko do odczytu, ponieważ usługa nie musi w nich nic zapisywać.

Dalsze zaostrzanie restrykcji jest kuszące, ale zazwyczaj błędne. ProtectSystem=strict ustawia cały system plików w tryb tylko do odczytu, z wyłączeniem pseudosystemów plików jądra, przez co pierwsze wywołanie narzędzia próbujące zapisać plik zakończy się błędem EROFS: read-only file system. Jeśli wymagany jest taki poziom zabezpieczeń, należy dodać ReadWritePaths=/var/lib/dsh w tej samej edycji.

Jaki typ Type= należy tutaj zastosować

Type=exec, ponieważ dsh działa w pierwszym planie i nigdy nie wykonuje operacji fork. Zaletą tego rozwiązania w porównaniu z wartością domyślną jest otrzymanie rzeczywistego komunikatu o błędzie. W przypadku Type=simple, systemd uznaje start za udany natychmiast po wykonaniu forka, zanim jeszcze sprawdzi, czy plik binarny w ogóle istnieje. Dlatego systemctl start dsh kończy się poprawnie, a błąd jest widoczny dopiero w dzienniku. Przy Type=exec, systemd czeka na poprawne zakończenie execve(), więc literówka w ExecStart= spowoduje błąd polecenia, które właśnie wpisano, co będzie od razu widoczne.

Obie błędne odpowiedzi powodują zawieszenie procesu. Type=forking nakazuje systemd czekać na zakończenie procesu nadrzędnego, a dsh nigdy się nie kończy, więc start usługi blokuje się do momentu upłynięcia TimeoutStartSec (domyślnie 90 sekund), po czym zwracany jest błąd Job for dsh.service failed because a timeout was exceeded.. Type=notify oczekuje na komunikat READY=1 przesyłany przez sd_notify, a proces Node, który nigdy go nie wyśle, zawiesza się w ten sam sposób. Pełne porównanie typów usług systemd omawia pozostałe przypadki, w tym sytuacje, w których warto podjąć wysiłek związany z konfiguracją notify.

Reguły restartu kończące się błędem

Restart=on-failure restartuje usługę w przypadku wyjścia z kodem innym niż zero lub wystąpienia sygnału krytycznego, natomiast pozostawia jednostkę w spokoju po poprawnym zakończeniu pracy. Jest to zachowanie pożądane w przypadku wersji testowych. Jeśli dsh zakończy działanie z kodem 0 z powodu odczytania nieprawidłowej konfiguracji, jednostka zatrzyma się i pozostanie w tym stanie, a systemctl status dsh wyświetli inactive (dead), co pozwala na weryfikację problemu. Restart=always zmienia to samo zdarzenie w pętlę restartów, która z dystansu wygląda na poprawnie działającą.

Limit częstotliwości to element, który jest często pomijany. Domyślne ustawienia systemd to pięć uruchomień w ciągu dziesięciu sekund. Przy RestartSec=5s nigdy nie osiągniesz pięciu uruchomień w oknie dziesięciu sekund, więc jednostka, która ulega awarii przy starcie, restartuje się w nieskończoność, a informację o tym posiada jedynie dziennik. StartLimitIntervalSec=300 wraz z StartLimitBurst=5 oznacza, że pięć awarii w ciągu pięciu minut jest wystarczające: systemd poddaje się i parkuje jednostkę w stanie failed, logując Start request repeated too quickly.. Po usunięciu przyczyny błędu należy wyczyścić ten stan za pomocą sudo systemctl reset-failed dsh. Oba ustawienia powinny znajdować się w [Unit], a nie w [Service], ponieważ w niewłaściwej sekcji systemd ignoruje je bez żadnego komunikatu.

Uruchomienie i weryfikacja

sudo systemctl daemon-reload
sudo systemctl enable --now dsh
systemctl status dsh

enable --now wykonuje dwa zadania. enable odpowiada za przywrócenie usługi po restarcie systemu, a --now uruchamia ją w bieżącej sesji. Samo systemctl start przestaje działać po ponownym uruchomieniu, a aktualizacje jądra wymuszają restarty.

systemctl status dsh powinno wyświetlić Active: active (running), Main PID oraz linię Memory:. Następnie należy potwierdzić, na jakim porcie usługa nasłuchuje:

sudo ss -lntp | grep 3080

Oczekiwany wynik to 127.0.0.1:3080. Jeśli widoczny jest adres 0.0.0.0:3080, oznacza to, że adres powiązania został zmieniony i agent jest wystawiony na publiczny dostęp w Internecie. Nazwa procesu w tym wyniku to node, a nie dsh, ponieważ plik binarny dsh jest skryptem Node, więc pgrep -x dsh nie zwróci żadnych wyników. Należy użyć systemctl show -p MainPID dsh.

Następnie należy wykonać restart systemu. Usługa, która nie przetrwała restartu, nie jest jeszcze w pełni skonfigurowana.

sudo reboot

Po ponownym połączeniu należy wykonać systemctl is-active dsh. Polecenie to wyświetli active.

Odczytywanie logów za pomocą journalctl

Wszystkie dane zapisywane przez dsh do stdout oraz stderr trafiają do dziennika pod nazwą jednostki.

journalctl -u dsh -f
journalctl -u dsh -n 200 --no-pager
journalctl -u dsh --since "10 min ago" -p err

-f śledzi nowe linie, -n wyświetla ostatnie N linii, a -p err filtruje według priorytetu. SyslogIdentifier=dsh w jednostce jest powodem, dla którego te linie są oznaczone jako dsh, a nie node, co ma znaczenie przy pierwszym odczycie danych z dziennika, które nie są przefiltrowane według jednostki.

Sprawdź, czy dziennik przetrwa restarty, zanim będzie to konieczne:

journalctl -u dsh -b -1

Jeśli polecenie zwróci Specifying boot ID or boot offset has no effect, no persistent journal was found, dziennik znajduje się w /run i jest usuwany przy każdym restarcie. Utwórz katalog i zrestartuj demona:

sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald

Dostęp do interfejsu użytkownika przez tunel SSH, a nie port publiczny

dsh udostępnia interfejs WWW (user interface) na 127.0.0.1:3080 i odmawia pracy w jakiejkolwiek innej lokalizacji. Próba wymuszenia --host 0.0.0.0 kończy się błędem:

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

Nie jest to ograniczenie, które należy obchodzić. Interfejs API (application programming interface) steruje agentem, a agent wykonuje polecenia powłoki, więc dostępny port oznacza dostęp do powłoki na VPS dla każdego, kto go znajdzie. Twórcy wskazują brak wbudowanego uwierzytelniania zdalnego jako powód, dla którego powiązanie (bind) jest na stałe przypisane do pętli zwrotnej (loopback). Warto przeczytać co w rzeczywistości oznacza wiersz 127.0.0.1:3080 w danych wyjściowych przy starcie, zanim podejmiesz próbę jego zmiany. Zamiast tego przekieruj port ze swojej maszyny:

ssh -N -L 3080:127.0.0.1:3080 you@203.0.113.10

-L 3080:127.0.0.1:3080 otwiera port 3080 na laptopie i przesyła wszystko, co tam trafi, do 127.0.0.1:3080, zgodnie z rozwiązaniem nazwy hosta na VPS. -N oznacza brak wykonywania zdalnego polecenia, więc sesja służy wyłącznie do utrzymania tunelu. Pozostaw sesję uruchomioną i otwórz http://127.0.0.1:3080/ w przeglądarce. To tam wprowadza się klucz API DeepSeek w sekcji Settings, a następnie Models, oraz wybiera katalog obszaru roboczego (workspace). Wskaż jako obszar roboczy /var/lib/dsh/workspace, czyli katalog należący do użytkownika usługi, w przeciwnym razie narzędzia plikowe agenta zgłoszą błąd EACCES: permission denied.

Jeśli port 3080 jest zajęty na laptopie, ssh wyświetli komunikat:

bind [127.0.0.1]:3080: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 3080

Wybierz inny port lokalny za pomocą ssh -N -L 3081:127.0.0.1:3080 you@203.0.113.10, a następnie przejdź do http://127.0.0.1:3081/. Aby uniknąć wpisywania poleceń, dodaj do ~/.ssh/config na własnej maszynie:

Host dsh-vps
  HostName 203.0.113.10
  User you
  LocalForward 3080 127.0.0.1:3080

Po tej konfiguracji ssh -N dsh-vps wystarczy jako pełne polecenie. Ten tunel jest teraz jedyną drogą dostępu do agenta, więc to demon SSH zapewnia jego ochronę: używaj wyłącznie kluczy, wyłącz uwierzytelnianie hasłem, a pozostałe zasady zwiększania bezpieczeństwa SSH na VPS mają tu jeszcze większe znaczenie niż zwykle. Jeśli VPS rozrośnie się do małej sieci prywatnej z bazą danych lub środowiskiem testowym, udostępnienie tych adresów w sieci tailnet za pomocą routera podsieci pozwoli uniknąć tworzenia osobnego przekierowania dla każdej usługi, choć ze względu na powiązanie dsh z pętlą zwrotną, interfejs WWW nadal będzie wymagał tunelu.

Klucz nie powinien znajdować się w pliku jednostki (unit file). Wartości Environment= są wyświetlane przez systemctl show dsh -p Environment, co może wykonać każdy użytkownik w systemie. Jeśli instalowana wtyczka wymaga klucza w zmiennych środowiskowych, umieść go w /etc/dsh.env z uprawnieniami 600, należącym do root, i odwołaj się do niego za pomocą EnvironmentFile=/etc/dsh.env. systemd odczytuje ten plik jako root w momencie uruchomienia, a systemctl show nie wyświetla jego zawartości. Informacje o tym, w którym pliku na dysku zapisywane jest każde ustawienie oraz co opuszcza serwer, gdy zamiast API DeepSeek wskażesz lokalny punkt końcowy Ollama, znajdują się w konfiguracji kluczy, modeli i punktów końcowych dsh.

Koszty utrzymania

Wnioskowanie odbywa się w API DeepSeek, a nie na Twoim VPS. Twój serwer pokrywa koszty procesu Node, serwowanej przez niego interfejsu użytkownika oraz każdego polecenia, które agent zdecyduje się wykonać. Dwa pierwsze elementy są stałe i niewielkie. Trzeci nie jest w żaden sposób ograniczony w tym pliku jednostki.

Określ bazowe zużycie zasobów na własnym serwerze, zamiast polegać na danych innych osób:

systemctl show dsh -p MemoryCurrent
systemd-cgtop -1 --depth 2

MemoryCurrent jest podawane w bajtach. Monitoruj ten parametr podczas pracy agenta, a nie w czasie jego bezczynności.

Wywołania narzędzi są procesami potomnymi usługi, więc trafiają do tej samej grupy kontrolnej i wliczają się do tych samych limitów. Agent uruchamiający npm install lub zestaw testów wewnątrz obszaru roboczego może zużyć znacznie więcej pamięci niż sam mechanizm sterujący. Na serwerze VPS z 1 GB pamięci RAM w tym miejscu pojawiają się problemy: jądro systemu wybiera proces i kończy go, a journalctl -k | grep -i "out of memory" wyświetla komunikat Out of memory: Killed process wskazujący na wybrany proces. Często nie jest to proces, który faktycznie spowodował problem.

Rozwiązaniem jest celowe ustawienie limitów. MemoryMax= oraz CPUQuota= w sekcji [Service] ograniczają skutki awarii do samej jednostki, dzięki czemu niekontrolowany proces budowania zostanie przerwany, zamiast doprowadzić do zawieszenia całego serwera. Ograniczanie pamięci i procesora za pomocą systemd omawia wartości liczbowe oraz zachowanie systemu w przypadku przekroczenia limitów. Zużycie dysku również rośnie ze względu na historię sesji w DSH_HOME oraz pliki tworzone przez agenta w obszarze roboczym, dlatego uwzględnij du -sh /var/lib/dsh w narzędziach, których używasz do monitorowania przestrzeni dyskowej.

Jeśli potrzebujesz interaktywnego agenta, do którego można się podłączać i odłączać, usługa systemd nie jest odpowiednim rozwiązaniem. W takim przypadku lepiej sprawdzi się uruchamianie agenta w trwałej sesji tmux. Uruchamiaj dsh jako usługę tylko wtedy, gdy ma być stale dostępny i osiągalny przez tunel.

Tryby awarii i komunikaty, które zobaczysz

status=203/EXEC. systemd nie mógł uruchomić pliku, a dzienniki wskazują na Failed to locate executable /usr/local/bin/dsh: No such file or directory. Ścieżka w ExecStart= nie zgadza się z tym, co wyświetliło command -v dsh. Jest to błąd, który Type=exec zgłasza w czasie systemctl start, zamiast go ukrywać.

status=217/USER. Konto wskazane w User= nie istnieje. Potwierdź to za pomocą id dsh.

status=200/CHDIR. Brakuje WorkingDirectory= lub użytkownik usługi nie ma uprawnień do wejścia do tego katalogu. sudo -u dsh ls /var/lib/dsh/workspace pozwala na bezpośrednią reprodukcję tego problemu.

Error: listen EADDRINUSE: address already in use 127.0.0.1:3080. Port jest już zajęty, zazwyczaj przez proces npx pozostawiony w innym terminalu. sudo ss -lntp | grep 3080 wskazuje nazwę tego procesu.

EACCES: permission denied wraz ze ścieżką. Właściciel plików w /var/lib/dsh jest nieprawidłowy, zazwyczaj dlatego, że pierwsze uruchomienie nastąpiło jako root lub z niewłaściwym HOME. sudo chown -R dsh:dsh /var/lib/dsh naprawia ten problem.

Start request repeated too quickly. Jednostka osiągnęła limit częstotliwości uruchamiania i przerwała próbę. Rzeczywisty błąd znajduje się w liniach powyżej. Wykonaj sudo systemctl reset-failed dsh przed ponowną próbą.

Jednostka jest active (running), ale przeglądarka nic nie wyświetla. Wykonaj sprawdzenie na VPS: jeśli curl -fsS http://127.0.0.1:3080/ -o /dev/null && echo up wyświetla up, usługa działa poprawnie, a problem leży w przekierowaniu portów.

Celowa aktualizacja

Przypięcie wersji oznacza, że aktualizacja jest działaniem świadomym, a nie zdarzeniem losowym. Należy najpierw zapoznać się z informacjami o wydaniu (release notes), ponieważ ostrzeżenia twórców o zmianach naruszających kompatybilność są głównym powodem stosowania przypięć. Należy wykonać kopię zapasową katalogu stanu, a następnie zmienić wersję:

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-pager

Wycofanie zmian (rollback) polega na wykonaniu tej samej procedury npm install -g z użyciem starej wersji oraz przywróceniu archiwum tar, co jest możliwe tylko w przypadku wcześniejszego wykonania kopii zapasowej. Środowisko uruchomieniowe agenta w fazie preview to dokładnie ten typ oprogramowania, w którym aktualizacja może w sposób nieprzewidziany nadpisać format konfiguracji.

FAQ

Dlaczego dsh zatrzymuje się po zamknięciu sesji SSH?

Ponieważ npx @deepseek-ai/dsh web jest procesem pierwszoplanowym powiązanym z sesją logowania, więc zostaje zakończony w momencie jej zamknięcia. Jednostka systemd jest zarządzana przez system init, dzięki czemu działa po rozłączeniu i uruchamia się ponownie po restarcie systemu. sudo systemctl enable --now dsh to zestaw kroków zapewniający oba te mechanizmy: enable dla restartu, --now dla bieżącej sesji.

Czy dla dsh należy użyć Type=simple czy Type=exec?

Type=exec. dsh działa w pierwszym planie i nie tworzy procesów potomnych (fork), więc obie opcje działają, jednak Type=exec sprawia, że systemd czeka na powodzenie execve() przed uznaniem startu za udany. Błędna ścieżka w ExecStart= spowoduje wtedy niepowodzenie systemctl start z komunikatem status=203/EXEC widocznym bezpośrednio. Przy Type=simple ten sam błąd zostanie uznany za sukces i ukryty w dzienniku. Type=forking oraz Type=notify są w tym przypadku błędne i powodują zawieszenie do momentu wygaśnięcia TimeoutStartSec po 90 sekundach.

Jak otworzyć interfejs webowy dsh z laptopa?

Przekieruj port przez SSH: ssh -N -L 3080:127.0.0.1:3080 you@your-vps, a następnie otwórz http://127.0.0.1:3080/ w przeglądarce. Nie należy wiązać usługi z publicznym adresem IP. dsh odrzuca --host 0.0.0.0 z komunikatem 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, ponieważ API webowe pozwala agentowi na wykonywanie poleceń powłoki, a przed nim nie ma żadnego zdalnego uwierzytelniania.

Czy można uruchomić dsh jako root, aby uprościć uprawnienia?

Nie. Mechanizm ten służy do wykonywania poleceń i zapisu plików, więc wszelkie uprawnienia usługi stają się uprawnieniami agenta. Należy utworzyć konto systemowe za pomocą useradd --system --shell /usr/sbin/nologin dsh, nadać mu własność /var/lib/dsh i dodać NoNewPrivileges=true do jednostki. Jeśli po tym wystąpi EACCES: permission denied, najczęstszą przyczyną jest wcześniejsze uruchomienie jako root, co pozostawiło pliki z błędnym właścicielem; sudo chown -R dsh:dsh /var/lib/dsh rozwiązuje ten problem.

Którą wersję dsh należy przypiąć w jednostce?

Wersję, którą zwraca npm view @deepseek-ai/dsh version podczas konfiguracji usługi, zainstalowaną przez npm install -g @deepseek-ai/dsh@<that version> i zapisaną w dostępnym miejscu. 0.1.0-rc.7 była aktualna w dniu 18 sierpnia 2026. Istotą nie jest numer wersji, lecz fakt, że npx bez określonej wersji pobiera pakiet w momencie startu, co może spowodować, że automatyczny restart niepostrzeżenie przeniesie usługę na wersję z innym formatem konfiguracji.