SSD Nodes Learn Hosting plans →
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-29

Claude Code کو remote VPS پر tmux میں چلائیں

SSH کنکشن ٹوٹنے کے بعد بھی Claude Code session جاری رکھیں۔ ہمیشہ آن Linux VPS پر tmux انسٹال کریں، اسے محفوظ کریں، اور SIGHUP سمیت عام ناکامیوں کو سمجھیں۔

مسئلہ CLI نہیں، laptop کا lid ہے

Claude Code آپ کے laptop پر اس وقت تک درست چلتا ہے جب تک آپ اسے بند نہیں کرتے۔ lid بند کرتے ہی SSH session ختم ہو جاتا ہے، shell کو SIGHUP موصول ہوتا ہے، اور test run شروع ہونے کے تین منٹ بعد agent بھی ختم ہو جاتا ہے۔ CLI ایسی machine پر چلائیں جو کبھی sleep mode میں نہ جائے، اور اسے ایسے terminal multiplexer کے اندر چلائیں جس کے processes آپ کے SSH session کے child processes نہ ہوں۔ یہی مکمل حل ہے۔ اس میں بنیادی کردار tmux کا ہے، installation کا نہیں۔

یہ صفحہ ایسی box چلانے کے بارے میں ہے جس پر آپ agents کو مسلسل چلتا چھوڑ سکیں۔ اگر آپ کے پاس ایسا Linux server نہیں ہے جسے switched on رکھا جا سکے، تو اس میں دی گئی کوئی ہدایت آپ پر لاگو نہیں ہوتی۔ یہی ایک حقیقی ابتدائی شرط ہے۔

tmux اصل میں کیا کرتا ہے

جب آپ SSH کے ذریعے لاگ اِن کرتے ہیں تو sshd ایک shell کو fork کرتا ہے اور اسے pseudo-terminal فراہم کرتا ہے؛ اس shell سے شروع ہونے والا ہر عمل اسی کا child ہوتا ہے۔ کنکشن ختم ہونے پر kernel اس pty کو ختم کر دیتا ہے، shell کو SIGHUP ملتا ہے، اور وہ بھی اپنے children کو باری باری hangup بھیج دیتا ہے۔ اس کے نتیجے میں foreground میں چلنے والے طویل مدتی processes ختم ہو جاتے ہیں۔

tmux ملکیت کا یہ تعلق الٹ دیتا ہے۔ آپ جو tmux command چلاتے ہیں، وہ ایک thin client ہے جو unix socket کے ذریعے ایک tmux server سے رابطہ کرتا ہے۔ یہ server آپ کے terminal سے الگ ہو کر چلتا ہے۔ session کے اندر موجود shells اس server کے children ہوتے ہیں، sshd کے نہیں۔ SSH کنکشن ختم کرنے پر client بند ہو جاتا ہے، لیکن server، session اور کام کے دوران موجود agent چلتے رہتے ہیں۔ دوبارہ connect کریں، tmux attach، اور آپ اسی shell میں اسی scrollback کے ساتھ واپس آ جاتے ہیں۔ nohup بھی hangup کے بعد برقرار رہتا ہے، لیکن اس میں واپس آنے کا کوئی طریقہ نہیں ہوتا؛ آپ background میں بھیجے گئے TUI سے دوبارہ attach نہیں ہو سکتے۔ Claude Code interactive ہے؛ اس لیے tmux (یا screen) موزوں tool ہے۔

مشین کے وسائل کا تعین

CLI ایک Node process ہے؛ مشین کے وسائل CLI خود استعمال نہیں کرتی۔ وسائل وہ چیز استعمال کرتی ہے جو agent آپ کی جانب سے چلاتا ہے: build، مکمل test suite، tsc، language server، یا Docker میں database۔ وسائل کا تعین CLI کے بجائے toolchain کی ضروریات کے مطابق کریں۔ Swap شامل کریں، چاہے آپ اسے استعمال کرنے کا کبھی ارادہ نہ رکھتے ہوں۔ اس سے سخت OOM kill کے بجائے build سست ہو جاتی ہے:

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

Disk پر بھی نظر رکھیں: repos، node_modules اور Docker images تیزی سے جگہ گھیرتے ہیں۔ اگر toolchain containers سے آگے مکمل virtual machines تک پہنچتا ہے، مثلاً KVM guest یا مقامی Kubernetes node، تو commitment سے پہلے تصدیق کریں کہ plan میں CPU virtualisation extensions دستیاب ہیں۔ VPS پر nested virtualization چلانا ایسی سہولت ہے جسے provider آپ کے لیے فعال کرتا ہے؛ اسے guest کے اندر سے فعال نہیں کیا جا سکتا۔

پہلے non-root صارف

اپنی الگ home directory کے ساتھ dedicated صارف بنائیں، اور اس میں اپنی 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

مزید آگے بڑھنے سے پہلے دوسری terminal سے login کی جانچ کریں، جبکہ password authentication fallback کے طور پر ابھی فعال ہو۔ اگر جواب میں publickey کے ذریعے اجازت مسترد کر دی گئی آئے تو خرابی عموماً key میں نہیں بلکہ اس .ssh directory کی ownership یا mode میں ہوتی ہے۔

جان بوجھ کر، agent کو sudo گروپ میں شامل نہیں کیا گیا۔ اگر system package درکار ہو تو اسے install کریں۔ اس ایک فیصلے سے ان بیشتر طریقوں کا خاتمہ ہو جاتا ہے جن سے کوئی غیر متوقع shell command host کو خراب کر سکتی ہے۔

چلتے رہنے والے سرور کے لیے SSH کی بہتر حفاظت

ایسی مشین پر password authentication جاری رکھنا، جو سارا دن public internet پر موجود ہو اور agent اور آپ کا source code محفوظ رکھتی ہو، ایسا خطرہ ہے جسے برداشت کرنے کی ضرورت نہیں۔ اسے بند کریں۔ Ubuntu 24.04 اور Debian 13 پر /etc/ssh/sshd_config میں /etc/ssh/sshd_config.d/*.conf شامل ہے، اس لیے مرکزی configuration میں ترمیم کرنے کے بجائے ایک فائل شامل کریں:

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

اپنی موجودہ session کھلی رکھیں اور دوسری terminal سے نئی session آزمانے کے دوران configuration کی توثیق اور reload کریں:

sudo sshd -t && sudo systemctl restart ssh

Ubuntu 24.04 میں ایک اہم نکتہ ہے: sshd socket-activated ہے۔ Authentication settings systemctl restart ssh پر لاگو ہوتی ہیں، لیکن listening Port میں تبدیلی کے لیے systemctl daemon-reload اور ssh.socket کو restart کرنا بھی ضروری ہے۔

اب firewall ترتیب دیں۔ اسے enable کرنے سے پہلے SSH کی اجازت دیں، ورنہ آپ خود کو access سے محروم کر دیں گے:

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

fail2ban کو اس بات کی واضح سمجھ کے ساتھ install کریں کہ اس سے کیا فائدہ ہوتا ہے: password authentication بند ہونے کے بعد brute-force حملہ ویسے بھی کامیاب نہیں ہو سکتا؛ یہ صرف ناکام کوششوں کو آپ کے journal سے باہر رکھتا ہے۔

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

آخر میں sudo apt install unattended-upgrades اور sudo dpkg-reconfigure -plow unattended-upgrades کے ذریعے خودکار patching فعال کریں۔ tmux کے ساتھ اس کے تعلق کو سمجھیں: Unattended-Upgrade::Automatic-Reboot فعال کرنے پر kernel update سرور کو reboot کر دیتا ہے، جس کے ساتھ ہر session ختم ہو جاتی ہے۔ اسے غیر فعال رکھیں اور reboot اپنے شیڈول کے مطابق کریں، جب کوئی کام درمیان میں نہ چل رہا ہو۔ یہی احتیاط release upgrade پر بھی لاگو ہوتی ہے: سرور کو Ubuntu 24.04 سے 26.04 پر منتقل کرنا sshd اور kernel کو restart کرتا ہے، اس لیے یہ کام ایسے وقت میں کریں جب کوئی tmux session اہم کام نہ چلا رہی ہو۔

Ubuntu پر Node.js اور Claude Code انسٹال کریں

Claude Code ایک Node CLI ہے، اس لیے آپ کو موجودہ Node درکار ہے۔ Distro package اکثر پرانا ہوتا ہے؛ Ubuntu اور Debian پر عموماً NodeSource استعمال کیا جاتا ہے، اور یہ signed repo فراہم کرتا ہے (apt-key نہیں، وہ tool ختم ہو چکا ہے):

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

اب وہ مرحلہ جس میں لوگ اکثر غلطی کرتے ہیں: CLI کو اپنے agent صارف کے طور پر انسٹال کریں، کبھی بھی sudo npm -g کے ساتھ نہیں۔ Root-owned global prefix بعد میں permission errors پیدا کرتا ہے اور npm cache میں root-owned files چھوڑ دیتا ہے۔ پہلے npm کا prefix صارف کے home پر مقرر کریں:

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 ~/.bashrc میں شامل کریں، ~/.profile میں نہیں، اور اسے فائل کے اوپری حصے میں موجود "If not running interactively, don't do anything" guard سے اوپر رکھیں: tmux non-login shells شروع کر سکتا ہے، جو ~/.bashrc پڑھتے ہیں اور ~/.profile کو skip کرتے ہیں؛ ~/.profile صرف login shells کے لیے چلتا ہے۔ nvm جیسے version manager کے ذریعے per-user Node بھی یہی نتیجہ دیتا ہے؛ دونوں صورتوں میں مقصد یہ ہے کہ npm install -g کو کبھی sudo کی ضرورت نہ پڑے۔ npm پھر بھی درست طور پر کام کرتا ہے، یا Anthropic کا native install script استعمال کریں، جو موجودہ دستاویزات میں default طریقہ ہے۔ Paste کرنے سے پہلے Anthropic کی install docs دیکھیں، کیونکہ install methods تبدیل ہو سکتے ہیں۔

کسی repo کے اندر claude چلائیں تاکہ اسے شروع کیا جا سکے۔ پہلی بار چلانے پر authentication کے مراحل دکھائے جاتے ہیں؛ headless box میں browser موجود نہیں ہوتا، اس لیے flow آپ کو اپنے machine پر کھولنے کے لیے ایک URL اور terminal میں واپس درج کرنے کے لیے ایک code دیتا ہے۔ (Environment میں API key استعمال کرنا دوسرا طریقہ ہے۔) دونوں صورتوں میں یہ credential اب server پر موجود ہوتا ہے، اور یہی ہمیں اس مرحلے تک لاتا ہے جسے لوگ نظرانداز کر دیتے ہیں۔

تباہی کے دائرۂ اثر پر گفتگو

Shell access رکھنے والا agent دراصل shell ہی ہوتا ہے۔ وہ ہر وہ چیز پڑھ سکتا ہے جسے وہ user پڑھ سکتا ہے، اور ہر اس جگہ push کر سکتا ہے جہاں وہ user push کر سکتا ہے۔ یہ tool پر تنقید نہیں بلکہ اس کی بنیادی تعریف ہے۔ اسی لیے agent جس account کے تحت چلتا ہے، وہ کسی بھی ایک setting سے زیادہ اہم ہے۔

  • الگ، غیر مراعات یافتہ user۔ کوئی sudo group نہ ہو، اور اس کی home directory آپ کے اپنے account کے ساتھ shared نہ ہو۔
  • اس box پر production credentials نہ رکھیں۔ کوئی ~/.aws/credentials جس میں prod keys ہوں، production سے copy کیا ہوا کوئی .env، یا ایسا database password نہ ہو جسے اہم وسائل پر write access حاصل ہو۔ Agent کو staging یا read-only credential دیں۔
  • محدود دائرۂ کار والے tokens۔ ایسا fine-grained GitHub token جو صرف ایک repository تک محدود ہو؛ یا جب read access کافی ہو تو deploy key استعمال کریں۔

Claude Code ایک ایسا flag فراہم کرتا ہے جو اس کے permission prompts کو مکمل طور پر نظرانداز کر دیتا ہے۔ Laptop یا عارضی project پر یہ آپ کا فیصلہ ہے۔ لیکن tokens رکھنے والے server پر یہ غلط سمجھی گئی instruction اور git push --force کے درمیان موجود آخری رکاوٹ بھی ہٹا دیتا ہے۔ جن prompts کو آپ نظرانداز کرتے ہیں وہ بھی صرف اجازت یا عدم اجازت تک محدود نہیں ہوتے۔ مزید یہ کہ auto mode بطور نیا default متعارف ہو رہا ہے، اس لیے یہ جاننا ضروری ہے کہ جس server کی آپ نگرانی نہیں کر رہے، اس پر کون سا permission mode مقرر ہونا چاہیے۔ یہ flag حقیقت میں کیا تبدیل کرتا ہے، اور اس کے ساتھ چلنے والے agent کو کیسے محدود رکھا جائے، built-in sandbox سے لے کر disposable VPS تک، اس کی تفصیل server پر Claude Code محفوظ طریقے سے چلانا میں دی گئی ہے۔

Deploy key بمقابلہ SSH agent forwarding

یہ دلکش لگتا ہے کہ ssh -A تاکہ git آپ کے laptop پر موجود key استعمال کر سکے۔ لیکن سمجھیں کہ اس سے کیا اختیار ملتا ہے: agent forwarding آپ کے local SSH agent کا socket اس box پر اس user کے تحت چلنے والے processes کے لیے ظاہر کر دیتا ہے۔ agent کے تحت چلنے والی کوئی بھی چیز، agent سمیت، آپ کی key سے کسی بھی ایسے host کے لیے دستخط کروا سکتی ہے جس تک وہ پہنچ سکتی ہو، بشرطیکہ آپ connected رہیں۔ یہ صرف "اس ایک repo کو git pull کرنے دیں" سے کہیں زیادہ وسیع اختیار ہے۔

اس کے بجائے server پر key generate کریں، اسے فی repository deploy key کے طور پر register کریں، اور صرف اسی صورت میں write access دیں جب agent کو push کرنا ہو۔ پھر git identity مقرر کریں تاکہ box سے کیے گئے commits کی شناخت واضح رہے:

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"

tmux کا طریقۂ کار

اسے (sudo apt install tmux) انسٹال کریں، پھر کم سے کم ~/.tmux.conf بنائیں:

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

روزمرہ استعمال کے لیے چار کمانڈز کافی ہیں:

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 وہ کمانڈ ہے جسے یاد رکھنا چاہیے۔ اگر session موجود ہو تو یہ اس سے attach ہو جاتی ہے، اور اگر موجود نہ ہو تو اسے بناتی ہے۔ اس طرح دن کا کام شروع کرنے اور connection ختم ہونے کے بعد دوبارہ جاری رکھنے، دونوں کے لیے ایک ہی کمانڈ کافی ہے۔ اس کا alias بنائیں۔ session کے اندر Ctrl-b c نئی window کھولتا ہے، Ctrl-b n اور Ctrl-b p windows کے درمیان منتقل ہوتے ہیں، جبکہ Ctrl-b [ پیچھے کا متن دیکھنے کے لیے copy mode کھولتا ہے (q اس سے باہر نکلتا ہے)۔

ان sessions کے بارے میں ایک اہم بات یہ ہے کہ انہیں کبھی kill نہیں کرنا چاہیے: agent ہر turn پر پوری گفتگو دوبارہ بھیجتا ہے۔ اس لیے کسی session کو ایک ہفتے تک چلتا چھوڑنے سے پہلے یہ دیکھیں کہ طویل عرصے تک چلنے والا Claude Code session اپنے tokens کہاں خرچ کرتا ہے۔

ناکامی کی صورتیں

"میرا session ختم ہو گیا ہے۔" tmux ls، no server running on /tmp/tmux-1000/default دکھاتا ہے۔ اس کا تقریباً ہمیشہ مطلب یہ ہوتا ہے کہ process کبھی tmux کے اندر نہیں چل رہا تھا، آپ نے SSH کے ذریعے login کیا، براہِ راست claude چلایا، اور connection ختم ہونے سے process بھی ختم ہو گیا۔ Recover کرنے کے لیے کچھ موجود نہیں۔ اس سے بچنے کی عادت یہ ہے: ہر login کے فوراً بعد tmux new -A -s <project> پہلا command ہونا چاہیے۔

Pane سکڑ کر بہت چھوٹا box بن جاتا ہے۔ tmux session کا سائز سب سے چھوٹے attached client کے مطابق رکھتا ہے، اس لیے کسی دوسری machine سے ابھی تک attached پرانا client display کو محدود کر دیتا ہے۔ Attach کرتے وقت دوسرے clients کو زبردستی disconnect کریں: tmux attach -d -t claude۔

Build Killed دکھاتا ہے۔ صرف ایک لفظ، کوئی stack trace نہیں۔ sudo dmesg -T | grep -i -E 'out of memory|killed process' سے تصدیق کریں؛ kernel کا OOM killer سب سے بڑا process منتخب کر کے ختم کر رہا ہے۔ Node کی طرف سے اس کے بجائے FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory بھی دکھائی دے سکتا ہے۔ حل، اسی ترتیب سے: swap شامل کریں، جیسا کہ اوپر بتایا گیا ہے؛ test اور compiler parallelism کی حد مقرر کریں؛ NODE_OPTIONS=--max-old-space-size=... کے ذریعے Node کا heap بڑھائیں؛ یا VPS کا سائز بڑھائیں۔ OOM killer build کے بجائے tmux server کو بھی منتخب کر سکتا ہے، جس سے آپ کا session بھی ختم ہو جاتا ہے۔ اگر systemd-oomd چل رہا ہو تو وہ اسی نتیجے کے ساتھ پورا user slice ختم کر سکتا ہے۔

npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'۔ یہ root کی ملکیت والے prefix میں global install کی وجہ سے ہوتا ہے۔ اوپر دیا گیا ~/.npm-global prefix استعمال کریں۔ اگر آپ نے پہلے کبھی sudo npm چلایا ہے تو Your cache folder contains root-owned files بھی نظر آ سکتا ہے؛ اسے sudo chown -R $(id -u):$(id -g) ~/.npm کے ذریعے درست کریں۔

claude: command not found، لیکن صرف کبھی کبھار۔ آپ کا PATH export، ~/.bashrc میں "If not running interactively, don't do anything" guard کے نیچے موجود ہے، اس لیے non-interactive shells اسے skip کر دیتے ہیں۔ Export کو اس guard سے اوپر منتقل کریں اور اسے ~/.bashrc میں رکھیں، ~/.profile میں نہیں: tmux non-login shells شروع کر سکتا ہے، جو ~/.bashrc پڑھتے ہیں اور ~/.profile کو کبھی نہیں پڑھتے۔

Attach کرنے کے بعد رنگ خراب دکھائی دیتے ہیں۔ یہ TERM mismatch کی وجہ سے ہے؛ اوپر موجود default-terminal line اسے درست کرتی ہے۔

Reboot کے بعد sessions غائب ہو جاتے ہیں۔ یہ bug نہیں ہے: tmux server ایک process ہے، اور reboot اسے ختم کر دیتا ہے۔ uptime چیک کریں۔

جیسے جیسے یہ بڑھتا ہے، کیا خراب ہوتا ہے

زیادہ projects۔ ہر repo کے لیے ایک tmux session بنائیں اور اسے اسی repo کے نام سے نام دیں؛ اس کے بعد tmux ls آپ کا dashboard بن جاتا ہے۔ نام رکھنے کا یہ نظم چھوڑ دیں تو sessions 0، 1، 2 بن جاتے ہیں۔ جب کئی sessions بیک وقت چل رہے ہوں تو ضروری نہیں کہ وہ الگ الگ کام کریں، کیونکہ ایک session اسی box پر موجود دوسرے session کو message بھیج سکتا ہے۔ یہ اس وقت مفید ہے جب طویل refactor سنبھالنے والا agent دوسرے agent سے tests چلوانا چاہے۔ Ports بھی اسی طرح پھیلتے ہیں۔ جب چھے repos سب :3000 چاہنے لگیں تو ports خود assign کرنا بند کریں اور Traefik reverse proxy کو Docker Compose کے تحت متعدد apps کو route کرنے دیں، تاکہ hostname کی بنیاد پر dispatch ہو سکے۔

زیادہ لوگ۔ tmux sockets فی user ہوتے ہیں، اس لیے ایک ہی box پر موجود دو developers کو الگ الگ tmux servers ملتے ہیں اور وہ ایک دوسرے کے sessions نہیں دیکھ سکتے۔ ایک shared socket کے ذریعے ایک session share کرنے کا مطلب ہے کہ سب لوگ اسی Unix user کے طور پر اسی shell میں type کریں گے، جس کے audit اور permissions سے متعلق نتائج ہوں گے۔ الگ users رکھنا سادہ اور درست حل ہے۔

بغیر نگرانی کے کام۔ tmux ان interactive sessions کے لیے ہے جن سے آپ attach ہوتے ہیں۔ وہ jobs جو مقررہ schedule پر چلتی ہیں اور جنہیں کوئی نہیں دیکھ رہا، systemd unit اور timer میں ہونی چاہئیں۔ وہاں انہیں logging، restart policy اور boot کے بعد خودکار طور پر چلنے کی سہولت ملتی ہے۔ cron جیسی job چلانے کے لیے tmux استعمال کرنا اس بات کی علامت ہے کہ job کو service بننا چاہیے۔

آخر میں ایک بات: agent کے شروع کیے ہوئے dev servers کو 127.0.0.1 پر bind کریں، 0.0.0.0 پر نہیں، اور ports کو ufw میں کھولنے کے بجائے SSH tunnel (ssh -L 3000:127.0.0.1:3000 agent@your-server) کے ذریعے ان تک پہنچیں۔ جب آپ تقریباً چھے ports forward کرنے لگیں، یا phone اور laptop دونوں ایک ہی preview تک رسائی چاہیں، تو اس کے بجائے VPS کے آگے self-hosted WireGuard VPN رکھیں۔ اس صورت میں dev servers ایک private interface پر bind ہوں گے اور ufw public interface سے آنے والی ہر چیز کو deny کرتا رہے گا۔ Firewall صرف اسی وقت مدد دیتا ہے جب آپ اس میں سوراخ کرنا بند کریں۔

Claude Code واحد انتخاب نہیں ہے: VPS پر coding AI agent چلانے میں Aider اور Goose بھی شامل ہیں۔

FAQ

کیا Claude Code کا عمل SSH connection منقطع ہونے کے بعد بھی چلتا رہتا ہے؟

صرف اس صورت میں جب آپ نے اسے tmux کے اندر شروع کیا ہو۔ SSH shell سے براہ راست شروع کیا گیا process اسی shell کا child ہوتا ہے اور link منقطع ہونے پر pty کے ساتھ ختم ہو جاتا ہے۔ tmux کے اندر shell detached tmux server سے وابستہ ہوتی ہے، اس لیے agent کام کے دوران چلتا رہتا ہے، اور tmux attach آپ کو اسی scrollback میں واپس لے آتا ہے۔ ہر login کے بعد tmux new -A -s <project> کو پہلا command بنائیں، مسئلہ ختم ہو جائے گا۔

کیا مجھے CLI کو sudo npm install -g کے ساتھ install کرنا چاہیے؟

نہیں۔ root کی ملکیت والا global prefix بعد کی installations میں EACCES errors پیدا کرتا ہے اور npm cache میں root کی ملکیت والی files بناتا ہے۔ npm کا prefix ~/.npm-global پر set کریں، یا nvm جیسے version manager کا استعمال کریں، اور غیر مراعات یافتہ agent user کے طور پر install کریں۔ پھر ~/.bashrc سے PATH میں ~/.npm-global/bin export کریں، interactive guard سے اوپر۔ اگر آپ پہلے ہی ایک بار sudo npm چلا چکے ہیں تو sudo chown -R $(id -u):$(id -g) ~/.npm سے cache repair کریں۔

کیا agent چلانے والے server پر ssh -A agent forwarding محفوظ ہے؟

یہ job کی ضرورت سے کہیں زیادہ access دیتا ہے۔ Forwarding آپ کے local SSH agent کا socket اس user کے طور پر چلنے والے ہر process کے سامنے ظاہر کرتی ہے۔ اس لیے server پر موجود کوئی بھی process آپ کی key سے ہر اس host کے لیے sign کرنے کی درخواست کر سکتا ہے جہاں تک وہ پہنچ سکتا ہے، جب تک آپ attached رہیں۔ Server پر ed25519 key generate کریں اور اسے per-repository deploy key کے طور پر register کریں۔ Write access صرف اسی صورت میں دیں جب agent کو واقعی push کرنا ہو۔

میری build صرف Killed کیوں print کرتی ہے؟

بغیر stack trace کے ایک لفظ kernel OOM killer کی علامت ہے۔ sudo dmesg -T | grep -i -E 'out of memory|killed process' سے اس کی تصدیق کریں؛ Node سے اس کے بجائے JavaScript heap out of memory دکھائی دے سکتا ہے۔ اصلاحات اس ترتیب سے آزمائیں: swapfile شامل کریں، test اور compiler parallelism کی حد مقرر کریں، NODE_OPTIONS=--max-old-space-size=... بڑھائیں، پھر VPS کا سائز بڑھائیں۔ یاد رکھیں کہ OOM killer build کے بجائے tmux server کو منتخب کر سکتا ہے، جس سے آپ کا پورا session ختم ہو جائے گا۔

tmux یا systemd service؟

tmux ان interactive sessions کے لیے موزوں ہے جن سے آپ attach ہوتے ہیں، انہیں monitor کرتے ہیں اور ان میں commands درج کرتے ہیں۔ agent session بالکل اسی نوعیت کا session ہے۔ جو کام schedule کے مطابق چلتا ہو اور جسے کوئی monitor نہ کر رہا ہو، اسے systemd unit اور timer میں چلانا چاہیے۔ وہاں logging، restart policy اور boot کے بعد برقرار رہنے کی سہولت built-in ہوتی ہے۔ اگر آپ cron جیسے job کو چلانے کے لیے tmux استعمال کرنے کا سوچ رہے ہیں تو وہ job service کے طور پر چلنی چاہیے۔