SSD Nodes Learn Hosting plans →
Mwongozo Matt ConnorNa Matt Connor · Imeboreshwa 2026-08-31

Jinsi ya kuendesha Claude Code kwenye VPS kwa kutumia tmux

Jifunze kuendesha Claude Code kwenye Linux VPS kwa kutumia tmux ili vikao vyako visikatike. Mwongozo huu unaelezea usakinishaji, usalama, na jinsi ya kuepuka hitilafu ya SIGHUP.

Tatizo ni mfuniko wa laptop, siyo CLI

Claude Code hufanya kazi vizuri kwenye laptop yako hadi utakapoiifunga: kikao cha SSH hufa, shell hupokea SIGHUP, na wakala anayefanya majaribio kwa dakika tatu hufa pamoja nayo. Endesha CLI kwenye mashine ambayo haipumziki kamwe, ndani ya terminal multiplexer ambapo michakato yake si watoto wa kikao chako cha SSH. Huo ndio ujanja wote, na tmux, siyo usakinishaji, ndiyo sehemu inayobeba mzigo.

Hii ni ukurasa kuhusu kuendesha mashine ambayo unaacha mawakala wakifanya kazi. Ikiwa huna seva ya Linux unayoweza kuiacha ikiwa imewashwa, hakuna lolote kati ya haya linalohusika. Hilo ndilo sharti moja la kweli.

tmux inafanya nini hasa

Unapounganisha kupitia SSH, sshd hufanya fork ya shell na kuipa pseudo-terminal; kila kitu unachoanzisha kutoka kwenye shell hiyo ni mtoto wake. Ukikata muunganisho, kernel huondoa pty, shell hupokea SIGHUP, na nayo huikata muunganisho kwa watoto wake. Michakato inayofanya kazi mbele (foreground) inayochukua muda mrefu hufa.

tmux hubadilisha umiliki huu. Amri ya tmux unayoandika ni client ndogo inayowasiliana kupitia unix socket na tmux server inayofanya kazi ikiwa imejitenga na terminal yako. Shell zilizo ndani ya session ni watoto wa seva hiyo, si wa sshd. Ukikata muunganisho wa SSH, client hupotea wakati seva, session, na wakala unaoendelea na kazi huendelea kufanya kazi. Unganisha tena, tumia tmux attach, na utarudi kwenye shell ileile ukiwa na historia ileile ya scrollback. nohup pia huweza kustahimili kukatika kwa muunganisho, lakini haikupi njia ya kurudi ndani; huwezi kuunganisha tena (re-attach) kwenye TUI iliyopo nyuma (backgrounded). Claude Code ni ya mwingiliano; tmux (au screen) ndiyo zana sahihi.

Kukadiria ukubwa wa seva

CLI ni mchakato wa Node; siyo kitu kinachojaza mashine. Kinachojaza mashine ni chochote ambacho wakala (agent) huendesha kwa niaba yako: build, suite kamili ya majaribio, tsc, seva ya lugha, au database ndani ya Docker. Kadiria ukubwa kulingana na toolchain, siyo CLI. Ongeza swap hata kama huna mpango wa kuitumia; inabadilisha OOM kill ya ghafla kuwa build ya polepole:

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

Fuatilia pia diski: repos, node_modules na picha za Docker hujilimbikiza haraka. Na kama toolchain inavuka mipaka ya containers na kuingia kwenye virtual machines kamili, kama KVM guest au node ya ndani ya Kubernetes, hakikisha mpango wako unaruhusu CPU virtualisation extensions kabla ya kuanza, kwa sababu kuendesha nested virtualization kwenye VPS ni kitu ambacho mtoa huduma anakuwezesha badala ya kitu unachoweza kukiwasha ukiwa ndani ya guest.

Mtumiaji asiye root kwanza

Unda mtumiaji maalum mwenye saraka yake ya nyumbani (home directory), na uweke public key yako mahali pake:

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

Jaribu kuingia (login) kutoka kwenye terminal ya pili kabla ya kuendelea, wakati uthibitishaji wa nenosiri bado unapatikana kama njia mbadala; ikiwa utapokea Permission denied (publickey), kosa mara nyingi huwa ni umiliki au mode kwenye saraka hiyo ya .ssh badala ya ufunguo wenyewe.

Kwa makusudi, agent haipo kwenye kundi la sudo. Ikiwa kifurushi cha mfumo kinahitajika, unakisakinisha. Uamuzi huo mmoja huondoa njia nyingi ambazo amri ya shell iliyopotea inaweza kuharibu seva (host).

Usafi wa SSH kwa seva unayoiacha ikiwaka

Kutumia password kwenye mashine iliyo wazi kwenye Internet muda wote, inayohifadhi agent na source code yako, ni hatari isiyo na sababu. Izime. Kwenye Ubuntu 24.04 na Debian 13, /etc/ssh/sshd_config inajumuisha /etc/ssh/sshd_config.d/*.conf, kwa hivyo weka faili jipya badala ya kuhariri usanidi mkuu:

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

Thibitisha na uwashe upya, huku ukiacha session yako ya sasa ikiwa wazi wakati unajaribu session mpya kutoka terminal ya pili:

sudo sshd -t && sudo systemctl restart ssh

Ujanja mdogo kwenye Ubuntu 24.04: sshd huwashwa kupitia socket. Mipangilio ya uthibitishaji hutumika kwenye systemctl restart ssh, lakini mabadiliko kwenye Port inayotumika kusikiliza pia yanahitaji systemctl daemon-reload na kuanzisha upya ssh.socket.

Kisha firewall. Ruhusu SSH kabla ya kuiwasha, la sivyo utajifungia nje:

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

Sakinisha fail2ban huku ukiwa na ufahamu wa faida yake: pindi uthibitishaji kwa password unapozimwa, mashambulizi ya brute force hayawezi kufanikiwa hata hivyo, inasaidia kuondoa majaribio yaliyoshindwa kwenye journal yako.

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

Mwisho, fanya patching ya kiotomatiki kwa kutumia sudo apt install unattended-upgrades na sudo dpkg-reconfigure -plow unattended-upgrades. Zingatia mwingiliano na tmux: ukiwasha Unattended-Upgrade::Automatic-Reboot na update ya kernel ikasababisha seva kuwaka upya, kila session itapotea. Iache ikiwa imezimwa na ufanye reboot kwa ratiba yako mwenyewe, wakati hakuna kazi inayoendelea. Tahadhari hiyo hiyo inatumika kwenye upgrade ya toleo: kuhamisha seva kutoka Ubuntu 24.04 kwenda 26.04 huanzisha upya sshd na kernel, kwa hivyo fanya hivyo wakati hakuna session ya tmux inayoshikilia kazi unayoiangalia.

Sakinisha Node.js na Claude Code kwenye Ubuntu

Claude Code ni CLI ya Node, kwa hivyo unahitaji toleo la sasa la Node. Kifurushi cha distro mara nyingi huwa kimepitwa na wakati; NodeSource ndiyo njia ya kawaida kwenye Ubuntu na Debian, na inatoa repo iliyotiwa saini (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 kimataifa inayomilikiwa na root husababisha makosa ya ruhusa baadaye na huacha faili zinazomilikiwa na root kwenye cache ya npm. Elekeza prefix ya npm kwenye saraka ya nyumbani ya 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

Export hiyo huwekwa kwenye ~/.bashrc, si ~/.profile, na inapaswa kuwa juu ya kizuizi cha "If not running interactively, don't do anything" karibu na sehemu ya juu ya faili: tmux inaweza kuanzisha shells zisizo za login, ambazo husoma ~/.bashrc na kuruka ~/.profile, ~/.profile huendeshwa tu kwa shells za login. Node ya kila mtumiaji kupitia meneja wa toleo kama nvm hufanikisha jambo lilelile; lengo kwa njia yoyote ile ni kwamba npm install -g haihitaji kamwe sudo. npm bado hufanya kazi vizuri, au tumia hati ya usakinishaji ya asili ya Anthropic, ambayo ndiyo chaguo-msingi lililoandikwa kwa sasa. Angalia nyaraka za usakinishaji za Anthropic kabla ya kupaste, mbinu za usakinishaji hubadilika.

Endesha claude ndani ya repo ili kuianzisha. Uendeshaji wa kwanza hukuongoza kupitia uthibitishaji; mashine isiyo na kichwa (headless) haina kivinjari, kwa hivyo mchakato huo hukupa URL ya kufungua kwenye mashine yako mwenyewe na msimbo wa kurudisha kwenye terminal. (API key katika mazingira ni njia nyingine.) Kwa vyovyote vile, kitambulisho hicho sasa kinaishi kwenye seva, jambo ambalo linatuleta kwenye sehemu ambayo watu huruka.

Mazungumzo kuhusu blast radius

Wakala mwenye uwezo wa kufikia shell ni shell yenyewe. Anaweza kusoma chochote ambacho mtumiaji anayeendesha wakala huyo anaweza kusoma, na anaweza kuandika popote ambapo mtumiaji huyo ana ruhusa ya kuandika. Hii si lawama kwa zana hiyo, bali ni ufafanuzi wa kazi yake, na ndiyo sababu akaunti inayotumika kuiendesha ni muhimu zaidi kuliko mpangilio wowote binafsi.

  • Mtumiaji maalum asiye na upendeleo (unprivileged user). Hakuna kundi la sudo, na hakuna saraka ya nyumbani (home directory) inayoshirikiwa na akaunti yako binafsi.
  • Hakuna vitambulisho vya production kwenye seva. Hakuna ~/.aws/credentials inayohifadhi funguo za production, hakuna .env iliyonakiliwa kutoka production, na hakuna nenosiri la database lenye ruhusa ya kuandika kwenye kitu chochote muhimu. Mpe wakala vitambulisho vya staging au vya kusoma pekee (read-only).
  • Token zenye upeo mdogo (scoped tokens). Tumia GitHub token iliyopunguziwa uwezo kwa ajili ya repository moja tu; au tumia deploy key ikiwa ruhusa ya kusoma pekee inatosha.

Claude Code inakuja na flag inayoruka maonyo ya ruhusa kabisa. Kwenye kompyuta yako binafsi, au kwenye mradi wa muda mfupi, hilo ni chaguo lako. Kwenye seva inayohifadhi token, flag hiyo huondoa kizuizi cha mwisho kati ya maelekezo yaliyofasiriwa vibaya na git push --force. Maonyo unayoruka si ya "yote au si kitu", na kwa auto mode inayokuja kama chaguo-msingi jipya, ni vyema kujua ni hali gani ya ruhusa inapaswa kuwekwa kwenye seva ambayo huifuatilii kwa karibu. Mambo ambayo flag hiyo hubadilisha kihalisi, na jinsi ya kudhibiti wakala anayeitumia, kuanzia sandbox iliyojengwa ndani hadi VPS ya muda, yamefafanuliwa katika kuendesha Claude Code kwa usalama kwenye seva.

Deploy key dhidi ya SSH agent forwarding

Inajaribu sana kutumia ssh -A ili git iweze kutumia ufunguo uliopo kwenye kompyuta yako. Elewa kile ambacho kitendo hicho kinatoa: agent forwarding hufichua socket ya SSH agent ya ndani kwa michakato (processes) inayoendeshwa kama mtumiaji huyo kwenye seva. Chochote kinachoendeshwa kama agent, ikiwemo wakala, kinaweza kuomba ufunguo wako kusaini kwa ajili ya host yoyote inayoweza kufikiwa, mradi tu umeunganishwa. Hiyo ni zaidi ya "kuruhusu git kuvuta (pull) repo moja".

Tengeneza ufunguo kwenye seva badala yake, uandikishe kama deploy key ya kila repository (ruhusa ya kuandika iweko tu ikiwa wakala anahitaji kusukuma/push), na uweke utambulisho wa git ili commits kutoka kwenye seva hiyo 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 msingi:

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

Amri nne zinatosha kwa 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 amri ya kukumbuka; inaunganisha kwenye session iliyopo au kuunda mpya ikiwa haipo, hivyo amri moja inatosha kuanza siku na kuendeleza kazi baada ya muungano kukatika. Iwekee alias. Ndani ya session, Ctrl-b c hufungua dirisha jipya, Ctrl-b n na Ctrl-b p hubadilisha madirisha, na Ctrl-b [ huingia kwenye copy mode ili kusogeza maandishi juu (q hutoka).

Kitu kimoja cha kuzingatia kuhusu session ambazo huzifungi kamwe: wakala hutuma tena mazungumzo yote katika kila hatua, kwa hivyo soma kile ambacho session ndefu ya Claude Code hutumia token zake kabla ya kuiacha ikiendelea kwa wiki nzima.

Njia za kufeli

"Kikao changu kimepotea." tmux ls huchapisha no server running on /tmp/tmux-1000/default. Hii karibu kila mara inamaanisha mchakato haukuwahi kuwa ndani ya tmux; uliingia kupitia SSH, ukaendesha claude moja kwa moja, na kukatika kwa muunganisho kuliuua. Hakuna cha kurejesha. Tabia ya kuzuia hili: tmux new -A -s <project> ndiyo amri ya kwanza baada ya kila login.

Dirisha dogo (pane) linajikunja na kuwa dogo sana. tmux hurekebisha ukubwa wa kikao kulingana na mteja (client) mdogo zaidi aliyeunganishwa, kwa hivyo mteja wa zamani aliyeunganishwa kutoka mashine nyingine hufinya onyesho. Lazimisha wengine watoke unapoingia: tmux attach -d -t claude.

Ujenzi (build) huchapisha Killed. Neno moja, hakuna stack trace. Thibitisha kwa sudo dmesg -T | grep -i -E 'out of memory|killed process', kernel OOM killer ilichagua mchakato mkubwa zaidi. Kutoka Node unaweza kuona FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory badala yake. Marekebisho, kwa mpangilio: ongeza swap (hapo juu), punguza parallelism ya test na compiler, 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 ujenzi, na kuondoa kikao chako; ikiwa systemd-oomd inaendeshwa, inaweza kuua user slice nzima na kusababisha athari hiyo hiyo.

npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'. Usakinishaji wa kimataifa (global install) kwenye prefix inayomilikiwa na root. Tumia prefix ya ~/.npm-global hapo juu. Ikiwa tayari uliendesha sudo npm wakati fulani unaweza pia kuona Your cache folder contains root-owned files, rekebisha 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 kizuizi cha "If not running interactively, don't do anything", kwa hivyo shell zisizo za maingiliano (non-interactive) huiruka. Hamisha export juu ya kizuizi hicho na uiweke kwenye ~/.bashrc, si ~/.profile: tmux inaweza kuanzisha shell zisizo za login, ambazo husoma ~/.bashrc na hazigusi ~/.profile kamwe.

Rangi zilizoharibika baada ya kuunganisha. Kutolingana kwa TERM, mstari wa default-terminal hapo juu ndio suluhisho.

Vikaa hupotea baada ya reboot. Sio hitilafu: seva ya tmux ni mchakato, na reboot huimaliza. Angalia uptime.

Nini kinaharibika kadiri mfumo huu unavyokua

Miradi mingi zaidi. Tumia tmux session moja kwa kila repo, ukiipa jina la mradi husika; tmux ls ndiyo itakuwa dashibodi yako. Ukipuuza utaratibu wa kuipa majina, utajikuta na session kama 0, 1, 2. Miradi mingi inapokuwa inaendeshwa kwa wakati mmoja, haihitaji kufanya kazi kwa kutengwa, kwa sababu session moja inaweza kutuma ujumbe kwa nyingine kwenye seva hiyo hiyo, jambo ambalo ni muhimu wakati wakala anayeshughulikia refactor ndefu anataka mwingine aende kuendesha majaribio. Bandari (ports) nazo huongezeka kwa njia hiyo hiyo; repo sita zote zikitaka :3000 ni ishara ya kuacha kuzipanga kwa mikono na kuruhusu Traefik reverse proxy kuelekeza apps nyingi chini ya Docker Compose ifanye usambazaji kwa kutumia hostname.

Watu wengi zaidi. Sockets za tmux ni za kila mtumiaji, kwa hivyo watengenezaji wawili kwenye seva moja kila mmoja anapata tmux server yake na hawawezi kuona session za mwenzao. Kushiriki session moja kupitia socket iliyoshirikiwa inamaanisha kila mtu anaandika kwenye shell ile ile kama mtumiaji mmoja wa Unix, jambo linaloleta athari za kiusalama na ruhusa. Kutumia watumiaji tofauti ndiyo njia sahihi na ya kitaalamu.

Kazi zisizosimamiwa. tmux ni kwa ajili ya session shirikishi unazojiunga nazo. Kazi zinazoendeshwa kwa ratiba bila mtu wa kuzitazama zinapaswa kuwekwa kwenye systemd unit na timer, ambapo zinapata logging, sera ya kuanzisha upya (restart policy), na uwezo wa kuendelea baada ya boot bila gharama yoyote. Kutumia tmux kuendesha kazi inayofanana na cron ni ishara kwamba kazi hiyo inapaswa kuwa huduma (service).

Ujumbe wa mwisho: funga (bind) seva za maendeleo (dev servers) ambazo wakala anazianzisha kwenye 127.0.0.1, si 0.0.0.0, na uzifikie kupitia SSH tunnel (ssh -L 3000:127.0.0.1:3000 agent@your-server) badala ya kufungua bandari kwenye ufw. Mara tu unapoanza kusambaza bandari nusu dazeni, au simu na laptop zote zikitaka kufikia preview moja, weka WireGuard VPN inayojiendesha kwenye VPS mbele yao: seva za maendeleo hufungwa kwenye interface ya kibinafsi, na ufw huendelea kuzuia kila kitu kutoka kwenye interface ya umma. Firewall inasaidia tu ikiwa utaacha kutoboa matundu ndani yake.

Claude Code si chaguo pekee: kuendesha coding AI agent kwenye VPS kunahusisha pia Aider na Goose.

FAQ

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

Ni kama tu uliianzisha ndani ya tmux. Mchakato ulioanzishwa moja kwa moja kutoka kwenye shell ya SSH ni mtoto wa shell hiyo na hufa pamoja na pty wakati muunganisho unapokatika. Ndani ya tmux, shell inamilikiwa na seva ya tmux iliyotenganishwa (detached), kwa hivyo wakala huendelea kufanya kazi katikati ya kazi na tmux attach hukurudisha kwenye sehemu ileile uliyokuwa nayo. Fanya tmux new -A -s <project> kuwa amri ya kwanza baada ya kila login na tatizo hilo litaisha.

Je, nifunge CLI kwa kutumia sudo npm install -g?

Hapana. Prefix ya kimataifa inayomilikiwa na root itakupa makosa ya EACCES kwenye usakinishaji wa baadaye na faili zinazomilikiwa na root kwenye cache ya npm. Weka prefix ya npm kuwa ~/.npm-global (au tumia meneja wa toleo kama nvm), sakinisha kama mtumiaji wa kawaida agent, na u-export ~/.npm-global/bin kwenye PATH kutoka ~/.bashrc, juu ya sehemu ya interactive guard. Ikiwa tayari ulishaendesha sudo npm mara moja, rekebisha cache kwa kutumia sudo chown -R $(id -u):$(id -g) ~/.npm.

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

Inatoa ruhusa nyingi zaidi kuliko inavyohitajika kwa kazi hiyo. Forwarding hufichua socket ya wakala wako wa SSH wa ndani kwa kila mchakato unaoendeshwa kama mtumiaji huyo, kwa hivyo chochote kwenye mashine kinaweza kuomba ufunguo wako kusaini kwa mwenyeji yeyote (host) inayoweza kuifikia muda wote unapokuwa umeunganishwa. Tengeneza ufunguo wa ed25519 kwenye seva na uisajili kama ufunguo wa deploy kwa kila hazina (repository), ukiwa na ruhusa ya kuandika tu ikiwa wakala anahitaji kufanya push.

Kwa nini build yangu inachapisha tu Killed?

Neno moja bila stack trace ni ishara ya kernel OOM killer. Thibitisha hili kwa sudo dmesg -T | grep -i -E 'out of memory|killed process'; kutoka Node unaweza kuona JavaScript heap out of memory badala yake. Fanyia kazi marekebisho haya kwa mpangilio: ongeza swapfile, punguza parallelism ya test na compiler, ongeza NODE_OPTIONS=--max-old-space-size=..., kisha ongeza ukubwa wa VPS. Jihadharini kuwa OOM killer inaweza kuchagua seva ya tmux badala ya build, na hivyo kufuta session yako yote.

tmux au systemd service?

tmux inafaa kwa session za interactive unazojiunga nazo, kuzitazama na kuandika ndani yake, ambayo ndiyo hasa hali ya session ya wakala. Kazi zinazoendeshwa kwa ratiba bila mtu wa kuzitazama zinapaswa kuwekwa kwenye unit na timer ya systemd, ambapo logging, sera ya restart, na kuendelea kuwaka baada ya boot hupatikana bila gharama. Ikiwa unatumia tmux kuendesha kazi inayofanana na cron, kazi hiyo inapaswa kuwa service.