SSD Nodes Learn
Mwongozo Matt ConnorNa Matt Connor · Imeboreshwa 2026-07-24

Kuendesha Claude Code kwenye VPS kwa tmux

Jifunze jinsi ya kutumia tmux kwenye Linux VPS ili kuzuia Claude Code kufa wakati SSH inakatika. Tumia mbinu hii kulinda session zako za agent.

Tatizo ni kifuniko cha laptop, siyo CLI

Claude Code hufanya kazi vizuri kwenye laptop yako mpaka unapoifunga: session ya SSH hukatika, shell inapata SIGHUP, na agent hufa baada ya dakika tatu za kuendesha test. Run CLI kwenye mashine ambayo hailali, ndani ya terminal multiplexer ambayo processes zake siyo watoto wa session yako ya SSH. Hilo ndilo jambo la msingi — na tmux, siyo installation, ndiyo sehemu muhimu zaidi.

Hii ni ukurasa kuhusu kuendesha mashine ambayo unaacha agent zikiwa zinafanya kazi. Kama huna Linux server ambayo unaweza kuiacha ikiwa imewashwa, maelezo haya hayatumiki. Hilo ndilo hitaji la msingi.

Kazi halisi ya tmux

Unapofanya SSH, sshd hutengeneza shell na kuipa pseudo-terminal; kila kitu unachoanzisha kutoka kwenye shell hiyo ni mtoto wake. Ukikatisha muunganisho, kernel huondoa pty, shell inapata SIGHUP, na kisha huacha kuwataalika watoto wake. Michakato inayotumia muda mrefu mbele (foreground) hufa.

tmux hubadilisha umiliki. Amri ya tmux unayoandika ni client nyembamba inayozungumza kupitia unix socket na tmux server inayojiendesha bila kuunganishwa na terminal yako. Shell ndani ya session ni watoto wa server hiyo, siyo ya sshd. Ukikatisha muunganisho wa SSH, client huondoka lakini server, session, na agent vinaendelea kuendelea na kazi. Ukirudia kuunganisha, tmux attach, utarudi kwenye shell ile ile na historia ile ile ya kusogeza maandishi (scrollback). nohup pia huendelea kuishi baada ya muunganisho kukatika, lakini haikupi njia ya kurudi — huwezi kuunganisha tena (re-attach) TUI iliyo nyuma (backgrounded). Claude Code ni ya kutoingiliana (interactive); tmux (au screen) ndio chombo sahihi.

Ukubwa wa mashine

CLI ni mchakato wa Node; si CLI inayojaza mashine. Kitu kinachojaza mashine ni chochote ambacho agent anafanya kwa niaba yako: build, mfululizo kamili wa majaribio, tsc, language server, au database ndani ya Docker. Panga ukubwa kwa ajili ya toolchain, si kwa ajili ya CLI. Ongeza swap hata kama hautakusudia kuitumia — inabadilisha OOM kill ya ghafla kuwa build inayochelewa:

sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Angalia pia diski: repos, node_modules na Docker images hukusanyika haraka. Na ikiwa toolchain inatumia zaidi containers hadi kwenye virtual machines kamili — kama KVM guest au Kubernetes node ya ndani — hakikisha mpango wako unaruhusu CPU virtualisation extensions kabla ya kuanza, kwa sababu kuendesha nested virtualization kwenye VPS ni kitu ambacho mtoa huduma anakuwezeshea, si kitu unachowasha kutoka ndani ya guest.

Mtumiaji asiye na haki za root kwanza

Tengeneza mtumiaji maalum mwenye nyumbani (home) yake, na uweke ufunguo wako wa umma (public key):

sudo adduser --disabled-password --gecos "" agent
sudo install -d -m 700 -o agent -g agent /home/agent/.ssh
sudo cp ~/.ssh/authorized_keys /home/agent/.ssh/authorized_keys
sudo chown agent:agent /home/agent/.ssh/authorized_keys
sudo chmod 600 /home/agent/.ssh/authorized_keys

Kwa makusudi, agent hayupo kwenye kikundi cha sudo. Ikiwa kifurushi cha mfumo kinahitajika, kisha unakipakua. Hatua hiyo moja huondoa njia nyingi ambazo amri ya shell isiyo na udhibiti inaweza kuharibu host.

Usalama wa SSH kwa seva inayojiacha ikiwa imewashwa

Kutumia uthibitisho wa password kwenye mashine iliyo kwenye mtandao wa umma, inayoshikilia agent na source code yako, ni hatari isiyo na lazima. Zima uthibitisho huo. Kwenye Ubuntu 24.04 na Debian 13, /etc/ssh/sshd_config inajumuisha /etc/ssh/sshd_config.d/*.conf, hivyo weka faili badala ya kuhariri config kuu:

# /etc/ssh/sshd_config.d/10-hardening.conf
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no

Thibitisha na uweke upya (reload) — wacha session yako ya sasa ikiwa wazi wakati unapojaribu session mpya kutoka kwenye terminal nyingine:

sudo sshd -t && sudo systemctl restart ssh

Jambo la kuzingatia kwenye Ubuntu 24.04: sshd inatumia socket-activation. Mipangilio ya uthibitisho inatumika kwenye systemctl restart ssh, lakini mabadiliko kwenye Port yanahitaji systemctl daemon-reload na kuanza upya (restart) kwa ssh.socket.

Kisha firewall. Ruhusu SSH kabla ya kuiwasha, vinginevyo utajifunga nje:

sudo ufw allow OpenSSH
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable

Install fail2ban ukijua faida yake: mara password authentication itakapozimwa, brute force haiwezi kufanikiwa — inazuia majaribio yaliyoshindwa yasijae kwenye journal yako.

# /etc/fail2ban/jail.local
[sshd]
enabled = true
backend = systemd
maxretry = 5
bantime = 1h

Mwisho, fanya updates kiotomatiki kwa kutumia sudo apt install unattended-upgrades na sudo dpkg-reconfigure -plow unattended-upgrades. Zingatia uhusiano na tmux: ukiwasha Unattended-Upgrade::Automatic-Reboot na kernel update ikifanya mashine ijiwashe upya, itafunga session zote. Iache ikiwa imezimwa na uwashe mashine kwa ratiba yako, wakati hakuna kazi inayojiendesha.

Sakinisha Node.js na Claude Code kwenye Ubuntu

Claude Code ni Node CLI, hivyo unahitaji Node ya sasa. Paketi ya distro mara nyingi ina ucheleweshaji; NodeSource ndiyo njia ya kawaida kwenye Ubuntu na Debian, na inatoa repo iliyosainiwa (hakuna apt-key — zana hiyo haipo tena):

curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt install -y nodejs
node --version

Sasa sehemu ambayo watu hukosea: sakinisha CLI kama mtumiaji wako wa agent, usitumie kamwe sudo npm -g. Prefix ya global inayomilikiwa na root husababisha makosa ya ruhusa baadaye na kuacha faili zinazomilikiwa na root kwenye npm cache. Elekeza prefix ya npm kwenye nyumbani (home) kwa mtumiaji kwanza:

mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
npm install -g @anthropic-ai/claude-code
claude --version

Amri ya export inawekwa kwenye ~/.bashrc, siyo ~/.profile, na inapaswa kuwa juu ya kinga ya "If not running interactively, don't do anything" karibu juu ya faili: tmux inaweza kuanzisha shells zisizo za login, ambazo husoma ~/.bashrc na kuruka ~/.profile~/.profile inaendeshwa tu kwa shells za login. Kutumia Node kwa kila mtumiaji kupitia usimamizi wa toleo kama nvm hufanya jambo lile lile; lengo kwa njia yoyote ni kwamba npm install -g haitahitaji sudo. npm bado inafanya kazi vizuri, au tumia script ya usakinishaji ya asili ya Anthropic, ambayo ndiyo chaguo la kawaida lililodokumentiwa sasa. Angalia docs za usakinishaji za Anthropic kabla ya kupaste — mbinu za usakinishaji hubadilika.

Run claude ndani ya repo ili kuanza. Run ya kwanza itakuongoza kwenye uthibitishaji (authentication); seva isiyo na kioo (headless box) haina kivinjari, hivyo mchakato utakupe URL ya kufungua kwenye mashine yako mwenyewe na kodi ya kurudisha kwenye terminal. (API key kwenye mazingira/environment ndiyo njia nyingine.) Kwa njia yoyote, udugu huo sasa unaishi kwenye seva — jambo ambalo linatuleta kwenye sehemu ambayo watu hupuuza.

Mazungumzo kuhusu blast radius

Agent mwenye ufikiaji wa shell ni shell. Inaweza kusoma kila kitu ambacho mtumiaji anayefanya nayo anaweza kusoma, na kuweka (push) mahali popote ambapo mtumiaji huyo anaweza kuweka. Hii si kashfa dhidi ya zana hiyo, bali ni ufafanuzi wake — na ndiyo sababu akaunti inayoiendesha ni muhimu zaidi kuliko mipangilio yoyote.

  • Mtumiaji maalum asiye na mamlaka. Hakuna kikundi cha sudo, hakuna nyumbani (home directory) inayoshirikishwa na akaunti yako.
  • Hakuna siri za uzalishaji (production credentials) kwenye mashine. Hakuna ~/.aws/credentials inayoshikilia funguo za prod, hakuna .env iliyonaswa kutoka kwenye uzalishaji, hakuna nywila ya database yenye ufikiaji wa kuandika kwenye kitu chochote muhimu. Mpe agent siri za staging au za kusoma tu (read-only).
  • Tokeni zenye upeo mdogo. Tokeni ya GitHub yenye upeo finyu iliyozingatia repository moja; deploy key wakati ufikiaji wa kusoma unatosha.

Claude Code inakuja na flag inayopuuza jumbe za ruhusa zote. Kwenye laptop, kwenye mradi wa muda, uamuzi ni wako. Kwenye seva inayoshikilia tokeni, inaondoa kinga ya mwisho kati ya maelekezo yaliyosomwa vibaya na git push --force. Kile ambacho flag hiyo inabadilisha, na jinsi ya kudhibiti agent inayojiendesha nayo, kuanzia sandbox iliyojengwa ndani hadi VPS inayoweza kutupwa, kunaelezwa kwenye kuendesha Claude Code salama kwenye seva.

Deploy key dhidi ya SSH agent forwarding

Ni rahisi ssh -A ili git iweze kutumia funguo kwenye laptop yako. Elewa kile kinachotolewa: agent forwarding inafichua socket ya SSH agent yako ya ndani kwa michakato inayojiendesha kama mtumiaji huyo kwenye mashine. Kitu chochote kinachojiendesha kama agent — ikiwa ni pamoja na agent — kinaweza kuomba funguo yako kusaini kwa hoja yoyote inayoweza kuifikia, mradi tu ukiendelea kuwa umeunganishwa. Hii ni zaidi ya "kuruhusu git ipakue repository hii moja".

Badala yake, tengeneza funguo kwenye seva, iandikishe kama deploy key ya kila repository (ufikiaji wa kuandika tu ikiwa agent inahitaji kuweka/push), na uweke utambulisho wa git ili commits kutoka kwenye mashine ziweze kutambulika:

ssh-keygen -t ed25519 -C "agent deploy key" -f ~/.ssh/id_ed25519_repo
cat ~/.ssh/id_ed25519_repo.pub   # paste into the repo's Deploy Keys
git config --global user.name "Agent (build box)"
git config --global user.email "agent@example.com"

Mtiririko wa kazi wa tmux

Iweke (sudo apt install tmux), kisha uweke ~/.tmux.conf ya kimsingi:

set -g mouse on
set -g history-limit 50000
set -g default-terminal "tmux-256color"

Amri nne zinajumuisha matumizi ya kila siku:

tmux new -A -s claude     # attach to session "claude", creating it if absent
# ...run `claude` inside it, work normally...
# Ctrl-b then d           -> detach; everything keeps running
tmux ls                   # list sessions
tmux attach -t claude     # reattach, from this machine or any other
tmux kill-session -t claude

tmux new -A -s claude ndiyo ya kukumbuka — inaunganisha ikiwa kikao (session) kipo na kinatengeneza kikao kipya ikiwa hakipo, hivyo amri moja inafanya kazi ya kuanza siku na kuendelea baada ya kuingia tena. Iweke kama alias. Ndani ya kikao, Ctrl-b c hufungua dirisha, Ctrl-b n na Ctrl-b p huzunguka madirisha hayo, na Ctrl-b [ huingia kwenye hali ya kunakili (copy mode) ili kurudi nyuma (q hufunga).

Jambo moja la kujua kuhusu vikao ambavyo huvidhibiti (kill): agent hutuma tena mazungumzo yote kila wakati, hivyo soma matumizi ya token kwenye kikao cha Claude Code kinachodumu kwa muda mrefu kabla ya kuacha kikao kikiwa kinafanya kazi kwa wiki moja.

Failure modes

"My session is gone." tmux ls inatoa no server running on /tmp/tmux-1000/default. Hii mara nyingi inamaanisha kuwa mchakato haukuwa ndani ya tmux — ulitingia kwa SSH, ukateka claude moja kwa moja, na kuunganishwa kwa mtandao kuliuua. Hakuna cha kuokoa. Jambo la kuepuka: tmux new -A -s <project> ndiyo amri ya kwanza baada ya kila kuingia.

Pane inasinyaa kuwa sanduku dogo sana. tmux huweka ukubwa wa session kulingana na mteja mdogo zaidi aliyeunganishwa, hivyo mteja wa zamani aliyeunganishwa kutoka mashine nyingine hufinya kioo. Watoe wengine wakati unaunganisha: tmux attach -d -t claude.

Build inatoa Killed. Neno moja, bila stack trace. Hakikisha kwa sudo dmesg -T | grep -i -E 'out of memory|killed process' — kernel OOM killer imechagua mchakato mkubwa zaidi. Kutoka Node unaweza kuona FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory badala yake. Suluhisho, kwa mpangilio: ongeza swap (juu), weka kikomo cha majaribio na ufanisi wa kiprogramu (compiler parallelism), ongeza heap ya Node kwa NODE_OPTIONS=--max-old-space-size=..., au ongeza ukubwa wa VPS. OOM killer inaweza pia kuchagua tmux server badala ya build, ikichukua session yako pamoja nayo; ikiwa systemd-oomd inafanya kazi, inaweza kuua user slice nzima kwa athari kama hiyo.

npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'. Install ya jumla (global) kwenye prefix inayomilikiwa na root. Tumia prefix ya ~/.npm-global iliyo juu. Ikiwa tayari umekimbiza sudo npm wakati fulani, unaweza pia kuona Your cache folder contains root-owned files — tatua kwa sudo chown -R $(id -u):$(id -g) ~/.npm.

claude: command not found — lakini wakati mwingine tu. Export yako ya PATH iko kwenye ~/.bashrc chini ya kinga ya "If not running interactively, don't do anything", hivyo shell zisizo za kienyeji (non-interactive) hupita hapo. Hamisha export hiyo juu ya kinga hiyo na uiweke kwenye ~/.bashrc, si ~/.profile: tmux inaweza kuanzisha shell zisizo za login, ambazo husoma ~/.bashrc na hazigusi ~/.profile.

Rangi zilizovurugika baada ya kuunganisha. TERM mismatch — mstari wa default-terminal hapo juu ndio suluhisho.

Sessions zinapotea baada ya kuwasha upya (reboot). Si hitilafu: tmux server ni mchakato, na kuwasha upya kunaumaliza. Angalia uptime.

Nini kinachovunjika mfumo unapokuwa mkubwa

Miradi zaidi. Tmux session moja kwa kila repo, ipewe jina la repo husika; tmux ls itakuwa dashboard yako. Ukikosa nidhamu ya kutunza majina, utapata session 0, 1, 2. Bandari (ports) pia huchanganyika kwa njia hiyo hiyo — repo sita zote zinazotaka :3000 ni wakati wa kuacha kuziunganisha kwa mkono na kuruhusu Traefik reverse proxy route multiple apps under Docker Compose kufanya usambazaji kwa kutumia hostname.

Watu zaidi. tmux sockets ni kwa kila mtumiaji, hivyo watengenezaji wawili kwenye mashine moja kila mmoja anapata tmux server yake na hawawezi kuona session za wengine. Kushiriki session moja kupitia socket inayoshirikishwa inamaanisha kila mtu anafanya kazi kwenye shell moja kama mtumiaji mmoja wa Unix, jambo ambalo lina matokeo ya ukaguzi na ruhusa. Kutumia watumiaji tofauti ndiyo jibu sahihi na la kawaida.

Kazi zisizo na usimamizi. tmux ni kwa ajili ya session zinazohitaji mwingiliano (interactive) ambazo unaweza kuziunganisha. Kazi zinazojiendesha kwa ratiba bila mtu kuangalia zinapaswa kuwa kwenye systemd unit na timer, ambapo zinapata uwezo wa kurekodi (logging), sera ya kuanza upya, na kuendelea kufanya kazi baada ya kuwasha mashine. Kutumia tmux kwa ajili ya kazi kama za cron ni ishara kwamba kazi hiyo inahitaji kuwa huduma (service).

Kidokezo cha mwisho: funga dev servers ambazo agent inaanza kwenye 127.0.0.1, siyo 0.0.0.0, na ufikie kwa kutumia SSH tunnel (ssh -L 3000:127.0.0.1:3000 agent@your-server) badala ya kufungua ports kwenye ufw. Ukianza ku-forward ports nyingi, au simu na laptop zote zinazohitaji preview moja, weka self-hosted WireGuard VPN on the VPS mbele yao: dev servers zinafungwa kwenye interface ya ndani, na ufw inaendelea kukataa kila kitu kutoka kwenye interface ya umma. Firewall inasaidia tu ikiwa utaacha kutoboa matundu kwenye ulinzi wake.

Claude Code si chaguo pekee: running a coding AI agent on a VPS inajumuisha Aider na Goose pia.

FAQ

Je, Claude Code inaendelea kufanya kazi baada ya muunganisho wangu wa SSH kukatika?

Itaendelea tu ikiwa uliianza ndani ya tmux. Mchakato unaozinduliwa moja kwa moja kutoka kwenye shell ya SSH ni mtoto wa shell hiyo na utafika mwisho pindi pty inapofungwa. Ndani ya tmux, shell inamilikiwa na tmux server iliyojitenga, hivyo agent itaendelea kufanya kazi katikati ya kazi na tmux attach itakurudisha kwenye maandishi yale yale. Fanya tmux new -A -s <project> kuwa amri ya kwanza baada ya kila kuingia ili tatizo lisionekane.

Je, nianze kuweka CLI kwa kutumia sudo npm install -g?

Hapana. Kutumia prefix ya kiwango cha juu inayomilikiwa na root husababisha EACCES wakati wa kuweka programu nyingine baadaye na files zinazomilikiwa na root kwenye npm cache. Set prefix ya npm kuwa ~/.npm-global (au tumia version manager kama nvm), weka kama mtumiaji asiye na mamlaka ya agent, na ushindo ~/.npm-global/bin kwenye PATH kutoka ~/.bashrc, juu ya ulinzi wa interactive. Ikiwa tayari umesharun sudo npm mara moja, tatua cache kwa kutumia sudo chown -R $(id -u):$(id -g) ~/.npm.

Je, agent forwarding ya ssh -A ni salama kwenye mashine inayotumia agent?

Inatoa zaidi ya kile ambacho kazi inahitaji. Forwarding inaweka socket ya SSH agent yako ya ndani wazi kwa kila mchakato unaofanya kazi kama mtumiaji huyo, hivyo kitu chochote kwenye mashine kinaweza kutumia funguo zako kusaini kwa host yoyote inayofikiwa wakati wote uliounganishwa. Tengeneza ed25519 key kwenye server na uisajili kama deploy key ya kila repository, ukiwa na uwezo wa kuandika tu ikiwa agent inahitaji ku-push.

Kwa nini build yangu inadumisha Killed pekee?

Neno moja bila stack trace ni kernel OOM killer. Hakikisha hili kwa kutumia sudo dmesg -T | grep -i -E 'out of memory|killed process'; kutoka Node unaweza kuona JavaScript heap out of memory badala yake. Fuata marekebisho kwa mpangilio huu: ongeza swapfile, dhibiti parallelism ya test na compiler, ongeza NODE_OPTIONS=--max-old-space-size=..., kisha ongeza ukubwa wa VPS. Kumbuka kuwa OOM killer inaweza kuchagua tmux server badala ya build, ikichukua session yako nzima pamoja nayo.

tmux au systemd service?

tmux inafaa kwa session za interactive ambazo unaweza kuziunganisha, kuzitazama na kuandika ndani yake, ambayo ndiyo kazi ya session ya agent. Kazi zinazofanya kazi kwa ratiba bila mtu anayezitazama zinapaswa kuwa kwenye systemd unit na timer, ambapo logging, sera ya kuanza upya na kuendelea baada ya kuwaka zinakuja bure. Ikiwa unatumia tmux kuendesha kazi kama cron, kazi hiyo inahitaji kuwa service.