Ghid · 45 de minute · Debian · Ubuntu · AlmaLinux
Administrare de server cu Claude Code
Claude Code e un agent care citește fișiere și rulează comenzi. Pe un server de producție asta e util și periculos în aceeași măsură, iar diferența o fac limitele pe care i le pui înainte de prima sesiune, nu atenția ta în timpul ei.
Ai nevoie de
- Un VPS securizat, cu un utilizator obișnuit și sudo
- Node.js 18 sau mai nou
- O cheie de API Anthropic, sau un abonament Claude
- Un server pe care ți-ai permite să-l reconstruiești. Începe acolo, nu pe producție.
- 01
Așază-ți așteptările înainte de instalare
Claude Code nu e un script care face exact ce i-ai scris. E un agent care decide singur ce comenzi rulează ca să ajungă la rezultatul cerut. Pe un server, asta înseamnă că poate citi ce nu voiai să citească și poate rula ce nu voiai să ruleze.
Modelul mental corect: îi dai acces ca unui coleg nou, competent dar fără context despre ce e critic la tine. Colegului îi spui „nu umbla la baza de date de producție". Aici, spui asta în fișiere de configurare, fiindcă ele se aplică de fiecare dată.
AtențieNu rula prima sesiune pe un server de producție. Ia un VPS separat, exersează, apoi mută configurația verificată pe producție.
- 02
Instalează și autentifică
Pe un server fără interfață grafică, autentificarea prin browser nu merge direct. Cea mai simplă cale e o cheie de API în variabilă de mediu.
Pune cheia într-un fișier citibil doar de utilizatorul tău, nu în .bashrc partajat și nu în istoricul shell-ului.
npm install -g @anthropic-ai/claude-code claude --version install -d -m 700 ~/.config/claude printf 'export ANTHROPIC_API_KEY=%s\n' 'sk-ant-...' > ~/.config/claude/env chmod 600 ~/.config/claude/env echo '[ -f ~/.config/claude/env ] && . ~/.config/claude/env' >> ~/.bashrc - 03
Scrie regulile de permisiuni înainte de prima sesiune
Regulile stau în .claude/settings.json și au forma Tool(tipar). Cele din deny nu pot fi ocolite din interfață, nici de tine în timpul sesiunii, nici de agent.
Precedența, de la cea mai puternică: setările administrate de organizație, argumentele din linia de comandă, .claude/settings.local.json, .claude/settings.json, apoi ~/.claude/settings.json.
Începe restrictiv. E mult mai ușor să adaugi o permisiune când te lovești de ea decât să afli după ce s-a executat ceva ce nu trebuia.
~/.claude/settings.json { "permissions": { "deny": [ "Read(./.env)", "Read(./.env.*)", "Read(~/.ssh/**)", "Read(/etc/shadow)", "Bash(rm -rf *)", "Bash(mkfs*)", "Bash(dd *)", "Bash(systemctl stop *)", "Bash(docker compose down*)", "Bash(curl * | *)", "Bash(wget * | *)" ], "ask": [ "Bash(systemctl restart *)", "Bash(docker compose up*)", "Write(/etc/**)", "Delete(**)" ], "allow": [ "Bash(systemctl status *)", "Bash(journalctl *)", "Bash(docker compose ps)", "Bash(docker compose logs*)", "Bash(df *)", "Bash(free *)", "Read(/var/log/**)" ] } }AtențieBash(curl * | *) în deny nu e paranoia. Un pipe de la curl direct în shell execută cod descărcat de pe internet, iar decizia despre ce se descarcă nu mai e a ta.
- 04
Pune un hook care oprește ce scapă de reguli
Regulile de permisiuni lucrează pe tipare. Un hook lucrează pe conținutul real al comenzii, deci prinde ce trece de tipar.
Hook-ul PreToolUse rulează înainte de execuție și poate refuza acțiunea. Primește pe intrare un JSON cu unealta și argumentele, iar refuzul se dă fie cu ieșire 2, fie cu un JSON de decizie.
~/.claude/settings.json (secțiunea hooks) { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "/home/utilizator/.claude/hooks/opreste-distructive.sh", "timeout": 10 } ] } ] } } - 05
Scrie hook-ul
Scriptul primește apelul pe intrarea standard și decide. Lista de tipare de mai jos acoperă operațiunile din care nu te mai întorci: ștergeri recursive de la rădăcină, scriere directă pe disc, oprirea bazei de date, curățarea volumelor Docker.
Ieșirea JSON cu permissionDecision: deny e mai bună decât ieșirea 2, fiindcă îi spune agentului și de ce a fost refuzat, deci nu reîncearcă aceeași comandă în altă formă.
~/.claude/hooks/opreste-distructive.sh #!/usr/bin/env bash set -euo pipefail CMD=$(jq -r '.tool_input.command // ""') refuza() { jq -n --arg motiv "$1" '{ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: $motiv } }' exit 0 } case "$CMD" in *"rm -rf /"*|*"rm -fr /"*) refuza "Ștergere recursivă de la rădăcină." ;; *"mkfs"*) refuza "Formatare de partiție." ;; *"dd if="*"of=/dev/"*) refuza "Scriere directă pe dispozitiv bloc." ;; *"docker volume rm"*|*"docker system prune -a"*) refuza "Ștergere de volume Docker: se pierd date." ;; *"DROP DATABASE"*|*"DROP TABLE"*) refuza "Comandă SQL distructivă." ;; *"> /etc/"*) refuza "Suprascriere de fișier din /etc." ;; esac exit 0AtențieTestează hook-ul înainte să te bazezi pe el. Rulează scriptul manual cu un JSON de test pe intrare și verifică refuzul. Un hook care se termină cu eroare de sintaxă nu blochează nimic.
- 06
Alege modul de permisiuni potrivit mașinii
Modul default cere confirmare pentru fiecare acțiune care nu e acoperită de o regulă. Modul auto lasă un clasificator să decidă, blocând ce pare suspect. Modul restricted refuză tot ce nu e permis explicit.
Pe producție, restricted. Pe un server de test, default e suficient și te învață unde te lovești de limite.
Nu folosi --dangerously-skip-permissions pe un server la care ții. Numele e o descriere exactă a ceea ce face.
# pe producție claude --permission-mode restricted # în sesiune, dacă vrei să schimbi /permission-mode restricted - 07
Lucrează întâi în citire, abia apoi în scriere
Tiparul care merge: prima sesiune diagnostichează și nu schimbă nimic; a doua aplică ce ai citit și aprobat. Separarea asta prinde majoritatea greșelilor înainte să atingă serverul.
Modul print, cu -p, rulează o singură cerere și iese. E potrivit pentru diagnostice repetate și pentru cron.
# diagnostic, fără modificări claude -p "Uită-te în journalctl din ultima oră și spune-mi ce servicii au erori. \ Nu schimba nimic, doar raportează." # raport zilnic prin cron, cu ieșirea trimisă pe mail 30 7 * * * cd /srv && claude -p "Rezumă erorile din ultimele 24h din \ /var/log și starea containerelor. Maxim 20 de rânduri." | mail -s "Raport server" tu@exemplu.ro - 08
Dă-i contextul serverului într-un CLAUDE.md
Un fișier CLAUDE.md în directorul de lucru se încarcă la începutul fiecărei sesiuni. Acolo scrii ce nu poate deduce singur: ce rulează pe mașină, ce e critic, ce are voie să repornească și ce nu.
Scris bine, reduce mult întrebările și greșelile. Scris ca o listă de dorințe, nu ajută: fii concret.
/srv/CLAUDE.md # Serverul acesta Producție. Rulează magazinul de pe exemplu.ro. ## Ce rulează - docker compose în /srv/shop: web (nginx), app (php-fpm), db (postgres), redis - backup restic zilnic la 03:30, prin systemd timer ## Reguli - NU reporni db fără să întrebi. Repornirea taie comenzile în curs. - NU rula migrări. Le rulez eu, din pipeline. - Poți reporni web și app oricând, sunt fără stare. - Logurile aplicației: docker compose logs app, nu /var/log. ## Când ceva nu merge 1. docker compose ps 2. logurile serviciului picat 3. df -h, fiindcă discul plin e cauza cea mai frecventă - 09
Limitează serverele MCP
Un server MCP adaugă unelte noi, deci extinde ce poate face agentul. Pe un server de producție, tratează fiecare adăugare ca pe o instalare de pachet: din surse pe care le cunoști.
Lista de refuz e mai sigură decât atenția: scrii o dată ce nu vrei și nu te mai bazezi pe memorie.
~/.claude/settings.json { "deniedMcpServers": [ { "serverName": "filesystem" } ], "disableAllHooks": false, "availableModels": ["claude-opus-5", "claude-sonnet-5"], "enforceAvailableModels": true } - 10
Fă-ți socoteala costului
Se plătește la token, separat pentru intrare și ieșire. O sesiune de diagnostic care citește câteva loguri costă cenți; una care parcurge un repo mare, mai mult.
Ce reduce factura, în ordinea efectului: pornește sesiunea în directorul potrivit, nu în rădăcina serverului; cere explicit un rezumat scurt; folosește un model mai mic pentru sarcini mecanice.
Model Contextul Intrare $/1M Ieșire $/1M claude-opus-5 1M 5,00 25,00 claude-sonnet-5 1M 3,00 15,00 claude-haiku-4-5 200K 1,00 5,00 Prețuri Anthropic la august 2026, pentru API-ul de primă parte. Abonamentele Claude au altă socoteală, pe limite de utilizare.
Întrebări frecvente
+E sigur să dau unui model acces la shell-ul serverului?
Depinde complet de limitele pe care i le pui. Fără reguli de permisiuni, e echivalent cu a da acces shell cuiva pe care nu-l cunoști. Cu reguli de refuz, un hook pentru comenzi distructive, mod restricționat și un utilizator fără sudo pentru operațiuni obișnuite, riscul devine comparabil cu al oricărui automatism care rulează pe server.
+Îl rulez ca root?
Nu. Utilizator obișnuit, cu sudo doar acolo unde chiar e nevoie, și cu regulile de refuz configurate. Ca root, o singură comandă greșită nu mai are nimic care s-o oprească.
+Ce VPS îmi trebuie?
Claude Code în sine e ușor: modelul rulează la Anthropic, pe server stă doar clientul Node.js. Planul de 2 GB e suficient dacă administrezi un server. Contează mai mult ce rulează deja pe mașină.
+Merge fără interfață grafică, doar prin SSH?
Da, e cazul obișnuit. Autentificarea se face cu o cheie de API în variabilă de mediu, iar sesiunea rulează în terminal. Pentru rulări automate, folosește modul print cu -p.
+Pot să-l pun pe cron?
Da, cu -p pentru o singură cerere. Ține minte că într-o rulare automată nu ai pe cine întreba: regulile din ask devin blocante. Pentru cron, formulează cereri de citire și raportare, nu de modificare.
+Ce fac dacă a schimbat ceva ce nu trebuia?
De asta backup-ul și controlul versiunilor nu sunt opționale. Ține /etc într-un repo git și fă backup înainte de sesiunile care modifică. Un agent cu acces la shell e un motiv în plus pentru igiena pe care oricum ar trebui s-o ai.