Remote VPS पर Claude Code कैसे चलाएं: tmux गाइड
Claude Code को हमेशा चालू रहने वाले Linux VPS पर tmux के साथ चलाएं ताकि SSH कनेक्शन टूटने पर भी आपका सेशन सुरक्षित रहे। इंस्टॉलेशन, सुरक्षा और संभावित एरर से बचें।
समस्या लैपटॉप का ढक्कन है, CLI नहीं
Claude Code आपके लैपटॉप पर तब तक ठीक चलता है जब तक आप उसे बंद नहीं करते: SSH session समाप्त हो जाता है, shell को SIGHUP मिलता है, और test run के तीन मिनट बाद ही agent उसके साथ बंद हो जाता है। CLI को ऐसी मशीन पर चलाएं जो कभी sleep मोड में न जाए, और इसे ऐसे terminal multiplexer के अंदर चलाएं जिसकी प्रक्रियाएं आपके SSH session की child न हों। यही पूरी तरकीब है, और tmux, न कि install, इसका मुख्य आधार है।
यह पृष्ठ उस मशीन को संचालित करने के बारे में है जिस पर आप agents को चलते हुए छोड़ते हैं। यदि आपके पास कोई ऐसा Linux server नहीं है जिसे आप चालू छोड़ सकें, तो यह जानकारी आपके लिए नहीं है। यही एकमात्र ईमानदार पूर्व-शर्त है।
tmux वास्तव में क्या करता है
जब आप SSH के जरिए login करते हैं, तो sshd एक shell fork करता है और उसे एक pseudo-terminal सौंप देता है; उस shell से आप जो कुछ भी शुरू करते हैं, वह उसका child process होता है। यदि connection टूट जाए, तो kernel pty को नष्ट कर देता है, shell को SIGHUP प्राप्त होता है, और वह अपने सभी child processes को बंद कर देता है। इससे foreground में चल रही लंबी प्रक्रियाएं समाप्त हो जाती हैं।
tmux इस स्वामित्व (ownership) को उलट देता है। आपके द्वारा टाइप किया गया tmux command एक thin client है, जो unix socket के माध्यम से एक tmux server से बात करता है। यह server आपके terminal से अलग (detached) होकर चलता है। session के अंदर चलने वाली shells उस server की child होती हैं, न कि sshd की। यदि आप SSH connection काट देते हैं, तो client बंद हो जाता है, लेकिन server, session और बीच में चल रहा कार्य (agent) चलते रहते हैं। दोबारा connect करने पर, tmux attach का उपयोग करें, और आप उसी shell में वापस आ जाएंगे, जहाँ scrollback भी सुरक्षित रहता है। nohup भी hangup के बाद जीवित रहता है, लेकिन यह आपको वापस अंदर जाने का कोई रास्ता नहीं देता; आप background में चल रहे TUI से फिर से attach नहीं हो सकते। Claude Code interactive है; इसलिए tmux (या screen) सही उपकरण है।
सर्वर का आकार निर्धारित करना
CLI एक Node process है; यह वह नहीं है जो मशीन की मेमोरी भरता है। मशीन को वह भरता है जो agent आपकी ओर से चलाता है: एक build, एक पूर्ण test suite, tsc, एक language server, या Docker में चल रहा database। CLI के लिए नहीं, बल्कि toolchain के लिए आकार निर्धारित करें। Swap memory जोड़ें, भले ही आप उसे कभी इस्तेमाल न करने की योजना बना रहे हों; यह एक hard 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/fstabDisk space पर भी नजर रखें: repos, node_modules और Docker images तेजी से जमा होते हैं। और यदि toolchain containers से आगे बढ़कर पूर्ण virtual machines, KVM guest, या local Kubernetes node तक पहुँचती है, तो सुनिश्चित करें कि plan में CPU virtualisation extensions उपलब्ध हैं। ऐसा इसलिए है क्योंकि VPS पर nested virtualization चलाना एक ऐसी सुविधा है जिसे provider आपके लिए enable करता है, न कि ऐसी जिसे आप guest के अंदर से चालू कर सकें।
एक non-root user बनाना
एक समर्पित user बनाएँ जिसका अपना home directory हो, और अपनी 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 के रूप में उपलब्ध है; यदि यह Permission denied (publickey) error देता है, तो समस्या आमतौर पर .ssh directory के ownership या mode में होती है, न कि key में।
जानबूझकर, agent को sudo group में नहीं रखा गया है। यदि किसी system package की आवश्यकता हो, तो आप उसे install करें। यह एक निर्णय उन अधिकांश तरीकों को समाप्त कर देता है जिनसे कोई गलत shell command host को नुकसान पहुँचा सकती है।
लंबे समय तक चलने वाले सर्वर के लिए SSH स्वच्छता
सार्वजनिक इंटरनेट पर मौजूद मशीन पर पासवर्ड ऑथेंटिकेशन का उपयोग करना, जिसमें SSH agent और आपका सोर्स कोड हो, एक अनावश्यक जोखिम है। इसे बंद कर दें। Ubuntu 24.04 और Debian 13 पर, /etc/ssh/sshd_config में /etc/ssh/sshd_config.d/*.conf शामिल है, इसलिए मुख्य कॉन्फ़िगरेशन फ़ाइल को एडिट करने के बजाय एक अलग फ़ाइल बनाएँ:
# /etc/ssh/sshd_config.d/10-hardening.conf
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin noउस फ़ाइल में key exchange को तब तक न छोड़ें जब तक आपके पास कोई विशेष कारण न हो: पुरानी हार्डनिंग गाइड से कॉपी की गई KexAlgorithms लाइन अक्सर केवल क्लासिकल एल्गोरिदम को ही पिन करती है, जिसके कारण एक आधुनिक SSH क्लाइंट यह चेतावनी देता है कि कनेक्शन post-quantum key exchange का उपयोग नहीं कर रहा है।
कॉन्फ़िगरेशन को वैलिडेट करें और रिलोड करें। परीक्षण के लिए दूसरे टर्मिनल से एक नया कनेक्शन बनाएँ, लेकिन अपना वर्तमान सेशन खुला रखें:
sudo sshd -t && sudo systemctl restart sshUbuntu 24.04 पर एक सूक्ष्म अंतर: sshd सॉकेट-एक्टिवेटेड है। ऑथेंटिकेशन सेटिंग्स systemctl restart ssh पर लागू होती हैं, लेकिन लिसनिंग Port में बदलाव के लिए systemctl daemon-reload और ssh.socket को रीस्टार्ट करने की भी आवश्यकता होती है।
इसके बाद फ़ायरवॉल की बारी है। SSH को इनेबल करने से पहले उसे अनुमति दें, अन्यथा आप खुद को सर्वर से बाहर लॉक कर लेंगे:
sudo ufw allow OpenSSH
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enablefail2ban को इस स्पष्ट समझ के साथ इंस्टॉल करें कि यह आपको क्या लाभ देता है: एक बार पासवर्ड ऑथेंटिकेशन बंद हो जाने पर, ब्रूट फ़ोर्स हमले वैसे भी सफल नहीं हो सकते, यह केवल विफल प्रयासों को आपके जर्नल से बाहर रखता है।
# /etc/fail2ban/jail.local
[sshd]
enabled = true
backend = systemd
maxretry = 5
bantime = 1hअंत में, sudo apt install unattended-upgrades और sudo dpkg-reconfigure -plow unattended-upgrades के साथ स्वचालित रूप से पैच करें। tmux के साथ इसके इंटरैक्शन पर ध्यान दें: यदि Unattended-Upgrade::Automatic-Reboot चालू है और कर्नल अपडेट होता है, तो सर्वर रीबूट हो जाएगा और आपके सभी सेशन बंद हो जाएंगे। इसे बंद रखें और अपनी सुविधानुसार रीबूट करें, जब कोई काम बीच में न चल रहा हो। यही सावधानी रिलीज़ अपग्रेड पर भी लागू होती है: सर्वर को Ubuntu 24.04 से 26.04 पर ले जाना sshd और कर्नल को रीस्टार्ट करता है, इसलिए इसे ऐसे समय में करें जब कोई tmux सेशन महत्वपूर्ण काम न संभाल रहा हो।
Ubuntu पर Node.js और Claude Code इंस्टॉल करें
Claude Code एक Node CLI है, इसलिए आपको एक current Node वर्ज़न की आवश्यकता है। Distro पैकेज अक्सर पुराने होते हैं; Ubuntu और Debian पर NodeSource का उपयोग करना सामान्य तरीका है, और यह एक signed repo प्रदान करता है (apt-key का उपयोग न करें, वह टूल अब उपलब्ध नहीं है):
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 फाइलें छोड़ देता है। सबसे पहले npm के prefix को यूजर के home directory पर सेट करें:
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" गार्ड के ऊपर होना चाहिए: tmux non-login shells शुरू कर सकता है, जो ~/.bashrc को पढ़ते हैं और ~/.profile को छोड़ देते हैं, जबकि ~/.profile केवल login shells के लिए चलता है। nvm जैसे version manager के माध्यम से per-user Node भी यही परिणाम देता है; किसी भी स्थिति में लक्ष्य यह है कि npm install -g को कभी भी sudo की आवश्यकता न पड़े। npm अभी भी ठीक काम करता है, या Anthropic की native install script का उपयोग करें, जो वर्तमान में documented default है। पेस्ट करने से पहले Anthropic के install docs देखें, क्योंकि इंस्टॉलेशन के तरीके बदलते रहते हैं।
इसे शुरू करने के लिए किसी repo के अंदर claude चलाएं। पहली बार चलाने पर यह आपको authentication की प्रक्रिया समझाएगा; headless box में ब्राउज़र नहीं होता, इसलिए यह प्रक्रिया आपको एक URL देगी जिसे आप अपनी मशीन पर खोल सकते हैं और एक कोड जिसे वापस टर्मिनल में डालना होगा। (environment में API key डालना दूसरा तरीका है।) किसी भी तरह, वह credential अब सर्वर पर रहता है, जो हमें उस हिस्से पर लाता है जिसे लोग अक्सर छोड़ देते हैं।
ब्लास्ट रेडियस (blast radius) पर चर्चा
शेल एक्सेस वाला कोई भी एजेंट एक शेल ही होता है। यह उन सभी फाइलों को पढ़ सकता है जिन्हें वह यूजर पढ़ सकता है जिसके तहत यह चल रहा है, और यह उन सभी जगहों पर बदलाव कर सकता है जहाँ वह यूजर कर सकता है। यह टूल की आलोचना नहीं, बल्कि इसकी परिभाषा है। यही कारण है कि किसी व्यक्तिगत सेटिंग की तुलना में वह अकाउंट अधिक महत्वपूर्ण है जिसके तहत यह चलता है।
- समर्पित, अनप्रिविलेज्ड (unprivileged) यूजर। कोई
sudoग्रुप नहीं, और न ही आपके अपने अकाउंट के साथ साझा की गई होम डायरेक्टरी। - मशीन पर कोई प्रोडक्शन क्रेडेंशियल न रखें। कोई
~/.aws/credentialsनहीं जिसमें प्रोडक्शन कीज़ हों, कोई.envनहीं जिसे प्रोडक्शन से कॉपी किया गया हो, और न ही ऐसा कोई डेटाबेस पासवर्ड जिसमें किसी महत्वपूर्ण चीज़ का राइट एक्सेस हो। एजेंट को केवल स्टेजिंग या रीड-ओनली क्रेडेंशियल दें। - स्कोप किए गए टोकन (Scoped tokens)। एक फाइन-ग्रेन्ड GitHub टोकन जो केवल एक रिपॉजिटरी तक सीमित हो; या एक डिप्लॉय की (deploy key) जब केवल रीड एक्सेस पर्याप्त हो।
Claude Code में एक फ्लैग होता है जो इसके परमिशन प्रॉम्प्ट्स को पूरी तरह से स्किप कर देता है। लैपटॉप पर, किसी अस्थायी प्रोजेक्ट के लिए, यह आपका निर्णय है। लेकिन टोकन रखने वाले सर्वर पर, यह गलत तरीके से पढ़े गए निर्देश और git push --force के बीच की आखिरी बाधा को हटा देता है। जिन प्रॉम्प्ट्स को आप स्किप कर रहे हैं, वे 'सब या कुछ नहीं' (all-or-nothing) नहीं हैं, और ऑटो मोड के नए डिफॉल्ट के रूप में आने के साथ, यह जानना महत्वपूर्ण है कि जिस सर्वर की आप निगरानी नहीं कर रहे हैं, उसे किस परमिशन मोड पर पिन किया जाना चाहिए। यह फ्लैग वास्तव में क्या बदलता है, और इसके साथ चलने वाले एजेंट को कैसे नियंत्रित किया जाए (इन-बिल्ट सैंडबॉक्स से लेकर डिस्पोजेबल VPS तक), यह सर्वर पर सुरक्षित रूप से Claude Code चलाने के लेख में कवर किया गया है।
डिप्लॉय की (Deploy key) बनाम SSH एजेंट फॉरवर्डिंग
ssh -A का उपयोग करना आकर्षक लगता है ताकि git आपके लैपटॉप की की (key) का उपयोग कर सके। समझें कि यह क्या अनुमति देता है: एजेंट फॉरवर्डिंग आपके लोकल SSH एजेंट के सॉकेट को उस मशीन पर उस यूजर के रूप में चलने वाली प्रक्रियाओं के लिए एक्सपोज कर देता है। agent के रूप में चलने वाली कोई भी चीज़, जिसमें एजेंट भी शामिल है, आपकी की से किसी भी ऐसे होस्ट के लिए साइन करने को कह सकती है जिस तक वह पहुँच सकती है, जब तक आप कनेक्टेड हैं। यह "git को केवल एक रिपॉजिटरी पुल करने दें" से कहीं अधिक है।
इसके बजाय सर्वर पर एक की (key) जनरेट करें, इसे प्रति-रिपॉजिटरी डिप्लॉय की के रूप में रजिस्टर करें (केवल तभी राइट एक्सेस दें यदि एजेंट को पुश करने की आवश्यकता हो), और एक git आइडेंटिटी सेट करें ताकि मशीन से किए गए कमिट्स पहचाने जा सकें:
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 claudetmux new -A -s claude वह कमांड है जिसे याद रखना चाहिए। यदि सेशन मौजूद है तो यह उससे जुड़ जाता है और यदि नहीं है तो यह उसे बना देता है। इस प्रकार एक ही कमांड दिन की शुरुआत करने और डिस्कनेक्ट होने के बाद फिर से जुड़ने, दोनों के काम आती है। इसका एक alias बना लें। सेशन के अंदर, Ctrl-b c एक विंडो खोलता है, Ctrl-b n और Ctrl-b p उनके बीच स्विच करते हैं, और Ctrl-b [ स्क्रॉल करने के लिए कॉपी मोड में प्रवेश करता है (q से बाहर निकला जाता है)।
उन सेशन्स के बारे में एक बात ध्यान रखें जिन्हें आप कभी बंद नहीं करते: एजेंट हर टर्न पर पूरी बातचीत को फिर से भेजता है। इसलिए, किसी सेशन को एक सप्ताह तक खुला छोड़ने से पहले एक लंबे समय तक चलने वाला Claude Code सेशन अपने टोकन कहाँ खर्च करता है पढ़ें।
विफलता के प्रकार (Failure modes)
"मेरा सेशन गायब हो गया है।" tmux ls, no server running on /tmp/tmux-1000/default प्रिंट करता है। इसका लगभग हमेशा यही अर्थ होता है कि प्रक्रिया कभी tmux के अंदर थी ही नहीं; आपने SSH किया, सीधे claude चलाया, और डिस्कनेक्ट होते ही वह समाप्त हो गई। इसे रिकवर करने का कोई तरीका नहीं है। इसे रोकने की आदत: हर लॉगिन के बाद tmux new -A -s <project> पहला कमांड होना चाहिए।
पेन (pane) एक छोटे बॉक्स में सिकुड़ जाता है। tmux एक सेशन का आकार सबसे छोटे अटैच्ड क्लाइंट के अनुसार तय करता है, इसलिए किसी दूसरी मशीन से अटैच्ड पुराना क्लाइंट डिस्प्ले को सिकोड़ देता है। अटैच करते समय दूसरों को जबरन हटा दें: tmux attach -d -t claude।
एक बिल्ड Killed प्रिंट करता है। केवल एक शब्द, कोई स्टैक ट्रेस नहीं। sudo dmesg -T | grep -i -E 'out of memory|killed process' के साथ पुष्टि करें, कर्नल OOM killer ने सबसे बड़ी प्रक्रिया को चुना है। Node से आपको इसके बजाय FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory दिख सकता है। समाधान, क्रम में: swap जोड़ें (ऊपर देखें), टेस्ट और कंपाइलर की समानांतरता (parallelism) को सीमित करें, NODE_OPTIONS=--max-old-space-size=... के साथ Node का हीप बढ़ाएं, या VPS का आकार बढ़ाएं। OOM killer बिल्ड के बजाय tmux server को भी चुन सकता है, जिससे आपका सेशन भी समाप्त हो जाएगा; यदि systemd-oomd चल रहा है, तो यह पूरे यूजर स्लाइस को समाप्त कर सकता है जिसका प्रभाव समान होगा।
npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'। रूट-ओन्ड प्रीफिक्स में ग्लोबल इंस्टाल। ऊपर दिए गए ~/.npm-global प्रीफिक्स का उपयोग करें। यदि आपने पहले कभी sudo npm चलाया है, तो आपको Your cache folder contains root-owned files भी दिख सकता है, इसे sudo chown -R $(id -u):$(id -g) ~/.npm से ठीक करें।
claude: command not found, लेकिन केवल कभी-कभी। आपका PATH एक्सपोर्ट ~/.bashrc में "यदि इंटरैक्टिव रूप से नहीं चल रहा है, तो कुछ न करें" गार्ड के नीचे स्थित है, इसलिए नॉन-इंटरैक्टिव शेल इसे छोड़ देते हैं। एक्सपोर्ट को उस गार्ड के ऊपर ले जाएं और इसे ~/.bashrc में रखें, न कि ~/.profile में: tmux नॉन-लॉगिन शेल शुरू कर सकता है, जो ~/.bashrc को पढ़ते हैं और कभी ~/.profile तक नहीं पहुँचते।
अटैच करने के बाद रंग खराब दिखना। एक TERM बेमेल है, ऊपर दी गई default-terminal लाइन इसका समाधान है।
रीबूट के बाद सेशन गायब हो जाते हैं। यह कोई बग नहीं है: tmux सर्वर एक प्रक्रिया है, और रीबूट इसे समाप्त कर देता है। uptime देखें।
जैसे-जैसे यह बढ़ता है, क्या खराब होता है
अधिक प्रोजेक्ट्स। प्रत्येक repo के लिए एक tmux session, जिसका नाम उसी के नाम पर हो; tmux ls तब आपका डैशबोर्ड होता है। यदि आप नामकरण के अनुशासन का पालन नहीं करते हैं, तो आपको 0, 1, 2 जैसे sessions मिलेंगे। जब कई sessions एक साथ चल रहे हों, तो उन्हें अलग-थलग काम करने की आवश्यकता नहीं होती, क्योंकि एक session उसी box पर दूसरे को संदेश भेज सकता है, जो तब उपयोगी होता है जब एक लंबा refactor करने वाला agent चाहता है कि दूसरा agent जाकर tests चलाए। Ports भी इसी तरह फैलते हैं, छह repos जो सभी :3000 चाहते हैं, वह बिंदु है जहाँ आपको उन्हें मैन्युअल रूप से असाइन करना बंद कर देना चाहिए और Docker Compose के साथ Traefik reverse proxy को hostname के आधार पर dispatching करने देना चाहिए।
अधिक लोग। tmux sockets प्रति-उपयोगकर्ता (per-user) होते हैं, इसलिए एक ही box पर दो developers को अपना-अपना tmux server मिलता है और वे एक-दूसरे के sessions नहीं देख सकते। एक shared socket पर एक session साझा करने का मतलब है कि हर कोई एक ही Unix user के रूप में एक ही shell में टाइप करता है, जिसके audit और permission संबंधी परिणाम होते हैं। अलग-अलग users का होना ही सही और सुरक्षित तरीका है।
बिना निगरानी वाला काम। tmux उन interactive sessions के लिए है जिनसे आप जुड़ते हैं। जो काम बिना किसी की निगरानी के schedule पर चलते हैं, उन्हें systemd unit और timer में होना चाहिए, जहाँ उन्हें logging, restart policy और boot के बाद भी चलने की सुविधा मिलती है। cron-जैसे काम को चलाने के लिए tmux का उपयोग करना इस बात का संकेत है कि उस काम को एक service के रूप में होना चाहिए।
एक अंतिम बात: agent द्वारा शुरू किए गए dev servers को 0.0.0.0 के बजाय 127.0.0.1 पर bind करें, और ufw में ports खोलने के बजाय उन्हें SSH tunnel (ssh -L 3000:127.0.0.1:3000 agent@your-server) के माध्यम से एक्सेस करें। जब आप आधा दर्जन ports forward कर रहे हों, या एक फोन और एक लैपटॉप दोनों एक ही preview देखना चाहते हों, तो उनके सामने VPS पर self-hosted WireGuard VPN लगा दें: dev servers एक private interface से bind होते हैं, और ufw public interface से आने वाली हर चीज़ को block करता रहता है। firewall केवल तभी मदद करता है जब आप उसमें छेद करना बंद कर दें।
Claude Code ही एकमात्र विकल्प नहीं है: VPS पर coding AI agent चलाना Aider और Goose को भी विकल्प के रूप में देखता है।
FAQ
क्या SSH connection टूटने के बाद भी Claude Code चलता रहता है?
केवल तभी, यदि आपने इसे tmux के अंदर शुरू किया हो। सीधे SSH shell से शुरू की गई process उस shell की child होती है और connection टूटने पर pty के साथ ही समाप्त हो जाती है। tmux के अंदर, shell एक detached tmux server का हिस्सा होती है, इसलिए agent अपना काम जारी रखता है और tmux attach आपको वापस उसी scrollback पर ले आता है। हर login के बाद tmux new -A -s <project> को अपनी पहली command बनाएँ, इससे यह समस्या हल हो जाएगी।
क्या मुझे CLI को sudo npm install -g के साथ install करना चाहिए?
नहीं। root-owned global prefix भविष्य में install करते समय EACCES error देता है और npm cache में root-owned files बना देता है। npm के prefix को ~/.npm-global पर सेट करें (या nvm जैसे version manager का उपयोग करें), इसे unprivileged agent user के रूप में install करें, और ~/.bashrc से PATH पर ~/.npm-global/bin को export करें (interactive guard के ऊपर)। यदि आपने पहले ही एक बार sudo npm चला दिया है, तो sudo chown -R $(id -u):$(id -g) ~/.npm के साथ cache को repair करें।
क्या agent चलाने वाले box पर ssh -A agent forwarding सुरक्षित है?
यह काम की जरूरत से कहीं अधिक अधिकार देता है। Forwarding आपके local SSH agent के socket को उस user के रूप में चलने वाली हर process के लिए खोल देता है। इसलिए, जब तक आप connected हैं, box पर मौजूद कोई भी process आपके key से किसी भी host के लिए sign करवा सकती है। सर्वर पर एक ed25519 key generate करें और उसे per-repository deploy key के रूप में register करें। यदि agent को वास्तव में push करना हो, तभी उसे write access दें।
मेरा 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 का size बढ़ाएँ। ध्यान रखें कि OOM killer build के बजाय tmux server को चुन सकता है, जिससे आपका पूरा session बंद हो जाएगा।
tmux या systemd service?
tmux उन interactive sessions के लिए उपयुक्त है जिन्हें आप देखते हैं, जिनमें आप type करते हैं और जिनसे आप जुड़ते हैं; agent session बिल्कुल ऐसा ही होता है। जो काम बिना किसी की निगरानी के schedule पर चलता है, उसे systemd unit और timer में होना चाहिए, जहाँ logging, restart policy और boot के बाद भी चलते रहने की सुविधा स्वतः मिलती है। यदि आप cron-shaped job चलाने के लिए tmux का उपयोग कर रहे हैं, तो उस job को एक service के रूप में होना चाहिए।