G.STANCUTA
Publicat · 2026 · 04 · 097 min de citit

De ce rulez totul pe Hetzner

  • infrastructure
  • devops
  • vps
  • self-hosting

AWS și GCP sunt bune până când vezi factura. Iată de ce mi-am mutat infrastructura pe Hetzner VPS și nu m-am mai uitat înapoi.

Am rulat pe DigitalOcean timp de trei ani. Apoi AWS o perioadă. Tiparul era mereu același: început mic, adăugat servicii, privit factura urcând peste ce ar trebui să plătească orice persoană rațională pentru a găzdui câteva aplicații web și o bază de date. Anul trecut am mutat totul pe Hetzner. Nu am regretat niciodată.

Diferența de preț nu este o eroare de rotunjire

Un Hetzner CPX31 îți oferă 4 vCPU, 8 GB RAM, 160 GB NVMe și 20 TB trafic de ieșire pentru aproximativ 15 EUR pe lună. Cel mai apropiat echivalent AWS EC2 (t3.large, memorie comparabilă, EBS gestionat, transfer de date) depășește 80 EUR când incluzi egress la volume reale. Nu este o diferență de 10% pe care o poți ignora. Este de cinci ori mai mult.

Hetzner dedică vCPU-urile. Nu sunt core-uri soft supraalocate care dispar când un vecin zgomotos pornește. Am rulat sarcini CPU susținute pe instanțe CPX și numerele se mențin. Primești ce spune fișa tehnică.

Diagramă izometrică ce compară arhitectura de costuri hyperscaler față de Hetzner
Straturile de costuri ale hyperscalerilor față de un singur element de linie Hetzner VPS.

Egress: taxa ascunsă pe care o încetezi să o plătești

Orice furnizor major de cloud îți percepe pentru transferul de date în exterior. AWS este celebru de scump la $0,09 pe GB după primul GB. GCP este similar. Azure puțin mai bun dar tot penalizant la scară. Hetzner include 20 TB de trafic de ieșire în orice plan VPS. Douăzeci de terabyți. Pentru majoritatea proiectelor nu vei atinge niciodată acea limită.

Servesc asset-uri video, descărcări de PDF-uri mari și răspunsuri API care pot fi voluminoase. Pe AWS costurile de trafic adăugau singure între $30 și $60 pe lună. Pe Hetzner sunt zero pentru că rămân în alocația inclusă. O CDN în față (nivelul gratuit Cloudflare este suficient pentru majoritatea tiparelor de trafic) înseamnă că originea vede oricum foarte puțin egress brut.

Taxele de egress nu sunt un cost al afacerii. Sunt un mecanism de retenție. Din momentul în care accepți această perspectivă, schimbarea furnizorului devine mai ușoară.

Storage NVMe și snapshot-uri care chiar funcționează

Storage-ul local pe NVMe al instanțelor CPX și CCX este rapid. Nu "rapid ca în cloud" unde fișa tehnică spune SSD dar latența spune altceva. Rapid cu adevărat. Citiri secvențiale bine peste 1 GB/s în practică. Pentru o bază de date Postgres sau un cache de build Next.js, diferența aceea se simte.

Snapshot-urile costă 20% din prețul serverului pe lună și sunt la un apel API distanță. Fac un snapshot înainte de fiecare deployment. Dacă ceva merge catastrofal greșit, pot reveni în mai puțin de două minute prin Cloud Console sau REST API. API-ul este curat și bine documentat, ceea ce contează când vrei să automatizezi aceste lucruri.

  • Snapshot-uri: un clic sau API, facturate la 20% din rata lunară a serverului
  • Floating IP-uri: reatribuie între servere instantaneu, fără jocuri cu TTL-ul DNS
  • Rețele private: L2 plat între serverele tale dintr-un datacenter, gratuit
  • Volume: atașează/detașează block storage persistent cât serverul rulează
  • Firewall-uri: reguli stateful gestionate din același panou sau API

Compromisul sincer: tu deții uptime-ul

Hetzner nu abstractizează operațiunile la fel cum o face AWS. Nu există RDS gestionat, niciun ECS, niciun Lambda. Primești o mașină Linux și o rețea curată. Ce faci cu ea este problema ta. Asta este fie înfricoșător, fie eliberator, în funcție de experiența ta.

Am rezolvat problema uptime-ului în trei straturi. Primul, Ploi pentru provisionarea și deployment-ul serverelor. Ploi comunică cu API-ul Hetzner, pornește servere, instalează Nginx, runtime-uri PHP sau Node, configurează SSL și gestionează deployment-uri zero-downtime prin Git hook-uri. Interfața este suficient de simplă încât chiar o folosesc. Al doilea, backup-uri automate ale bazei de date în Hetzner Object Storage (compatibil S3) la fiecare șase ore. Al treilea, Cloudflare în față pentru protecție DDoS, caching și un edge global, astfel încât VPS-ul dintr-o singură regiune să nu pară lent utilizatorilor din Tokyo.

Provisionare și hardening în 60 de linii

Ploi se ocupă de configurarea runtime-ului, dar tot rulează un script de hardening pe fiecare server nou înainte de a-l preda. Iată miezul acestuia. Nimic sofisticat, doar elementele de bază care contează: dezactivarea autentificării prin parolă, configurarea unui utilizator non-root, configurarea UFW și ajustarea câtorva parametri de kernel.

bash
#!/usr/bin/env bash
# harden.sh — run once as root immediately after provisioning
set -euo pipefail

NEW_USER="deploy"
SSH_PUBKEY="ssh-ed25519 AAAAC3Nza... your-key-here"

# Create deploy user with sudo, no password prompt for deploys
useradd -m -s /bin/bash "$NEW_USER"
usermod -aG sudo "$NEW_USER"
echo "$NEW_USER ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/"$NEW_USER"

# Inject SSH key
mkdir -p /home/"$NEW_USER"/.ssh
echo "$SSH_PUBKEY" > /home/"$NEW_USER"/.ssh/authorized_keys
chmod 700 /home/"$NEW_USER"/.ssh
chmod 600 /home/"$NEW_USER"/.ssh/authorized_keys
chown -R "$NEW_USER":"$NEW_USER" /home/"$NEW_USER"/.ssh

# Harden SSH
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd

# UFW: allow SSH + HTTP + HTTPS only
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable

# Kernel hardening: disable IP forwarding unless you need it, enable SYN cookies
cat >> /etc/sysctl.d/99-harden.conf <<EOF
net.ipv4.ip_forward = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.core.somaxconn = 65535
EOF
sysctl --system

# Unattended security upgrades
apt-get install -y unattended-upgrades
dpkg-reconfigure -f noninteractive unattended-upgrades

echo "Hardening complete. SSH as $NEW_USER."

După ce rulează, Ploi preia controlul. Îl pointezi la IP-ul serverului, selectezi stack-ul de runtime, pui URL-ul repo-ului și o cheie de deploy, iar primul deployment trece în aproximativ trei minute. Deployment-urile ulterioare sunt declanșate de un Git push și se completează în mai puțin de 30 de secunde pentru majoritatea aplicațiilor Node.

Diagramă a unui agent AI de coding care citește fișiere markdown de memorie pentru a gestiona un server Hetzner
Un agent AI care persistă cunoașterea serverului în fișiere markdown pentru o operare fiabilă pe termen lung.

Rulând totul asta cu un agent AI de coding

Folosesc Claude Code ca agent de coding pe majoritatea proiectelor mele. Un lucru care contează mult când un agent gestionează infrastructură este memoria pe termen lung. Agentul nu-și amintește IP-urile serverelor tale, regulile UFW sau motivul pentru care ai ales portul 9000 pentru endpoint-ul de metrici. Fiecare sesiune pornește din nou de la zero dacă nu îi oferi context persistent.

Soluția mea este un fișier HETZNER.md inclus în repository la rădăcina proiectului. Agentul îl citește la începutul oricărei sesiuni legate de infrastructură și are imaginea completă: specificațiile serverului, adresele IP, serviciile deployate, programele de backup, problemele cunoscute. Când ceva se schimbă, îi spun agentului să actualizeze fișierul. Devine sursa de adevăr care supraviețuiește reset-urilor ferestrei de context.

Fișierul este scurt și direct. Fără proză, doar fapte pe care agentul poate acționa. Iată un exemplu real despre cum arată:

md
# Hetzner Infrastructure Memory

## Servers
| Name        | IP            | Type   | Region | OS           |
|-------------|---------------|--------|--------|--------------|
| web-prod     | 65.21.xxx.xxx | CPX31  | HEL1   | Ubuntu 24.04 |
| db-prod      | 65.21.yyy.yyy | CPX21  | HEL1   | Ubuntu 24.04 |

## Deploy user: `deploy` (no-password sudo)
## SSH key: ed25519, stored in 1Password under "Hetzner deploy key"

## Services on web-prod
- Nginx 1.26, proxy to Node :3000
- PM2 manages the Node process (app name: `jumpinotech`)
- SSL via Let's Encrypt, auto-renew via certbot systemd timer
- Cloudflare proxied: DNS A record points to 65.21.xxx.xxx

## Database (db-prod)
- Postgres 16, port 5432, bound to private network only (10.0.0.x/24)
- Backups: pg_dump every 6h via cron, upload to Hetzner Object Storage bucket `db-backups-prod`
- Restore: `hetzner-restore.sh` in /home/deploy/scripts/

## Firewall (UFW on both servers)
- 22, 80, 443 open on web-prod
- 22, 5432 open on db-prod (5432 restricted to private network only)

## Snapshots
- Taken manually before each major deploy via Hetzner Cloud Console
- Naming convention: `web-prod-YYYY-MM-DD-pre-deploy`

## Known Gotchas
- Private network interface is eth1, not eth0 — use this for DB connection string
- Ploi deploy hook URL changes if you delete and recreate the site; update GitHub webhook
- Object Storage endpoint: `https://fsn1.your-objectstorage.com`

Cu acest fișier în repo, pot deschide o sesiune nouă, spun "verifică scriptul de backup pe db-prod" și agentul știe IP-ul, utilizatorul, calea scriptului și endpoint-ul de storage fără ca eu să repet nimic. Citește markdown-ul, formează un plan și execută comenzi SSH sau apeluri API cu contextul corect. Fără IP-uri halucinante, fără ghiciri la numele serviciilor.

Când Hetzner nu este răspunsul potrivit

Centrele de date Hetzner se află în Germania, Finlanda și SUA (Ashburn și Hillsboro). Dacă cerințele de conformitate necesită rezidența datelor în APAC sau ai nevoie de latență în milisecunde cu o singură cifră pentru utilizatorii din Sydney, te uiți la un setup hibrid sau un alt furnizor. Pentru sarcinile de lucru europene și nord-americane este în regulă.

Serviciile gestionate lipsesc de asemenea. Dacă ai nevoie de un cluster Redis gestionat, Kafka gestionat sau un runtime de funcții serverless, le vei adăuga din altă parte sau le vei rula tu însuți. Pentru mine nu este un factor decisiv. Pentru o echipă fără experiență în operații ar putea fi. Ploi acoperă mult din decalaj specific pentru aplicații web, dar nu înlocuiește o PaaS completă.

Pentru orice altceva, economia este greu de contestat. Core-uri dedicate, RAM real, storage NVMe, egress generos, API curat și o companie europeană care nu ascunde taxele în literele mici. Dacă rulezi aplicații web, proiecte secundare sau instrumente interne și ești încă pe un hyperscaler din obișnuință, scoate ultimele trei facturi și fă calculul. Numerele vor lua decizia pentru tine.

Portofoliu · Indicator
Desenat de
G. STANCUTA
Disciplină
AI & AUTOMATION
Locație
MORTER · SÜDTIROL
Stare
Disponibil
Limbi
IT · EN · RO · DE+
Stack
PLOI · HETZNER
Revizie
REV 2026.A
2026

© 2026 Gabriel Stancuta · jumpinotech.com — Proiectat cu AI, construit să funcționeze singur.