Nginx Proxy Manager cu Docker: reverse proxy si SSL in fata containerelor de aplicatii
Docker

Nginx Proxy Manager cu Docker Compose: reverse proxy si SSL

Fiecare aplicatie pe care o rulezi pe un VPS vrea portul ei. Uptime Kuma asculta pe 3001, un dashboard pe 8080, un API mic pe 3000, si in scurt timp ajungi sa trimiti oamenilor linkuri de genul http://203.0.113.10:8080, sperand ca nimeni nu observa avertismentul “Not secure” din browser. Ce vrei de fapt e status.exemplu.ro si app.exemplu.ro, fiecare cu certificat HTTPS valid, toate servite de pe aceeasi masina. Asta e treaba unui reverse proxy, iar Nginx Proxy Manager te lasa sa-l administrezi dintr-o interfata web curata, in loc sa scrii de mana configuratii Nginx si comenzi certbot la miezul noptii.

Nginx Proxy Manager (ii vom spune NPM de aici incolo, nu-l confunda cu managerul de pachete din Node.js) e un proiect open source sub licenta MIT, documentat pe nginxproxymanager.com , cu codul pe github.com/NginxProxyManager/nginx-proxy-manager . In tutorialul asta il instalam cu Docker Compose pe un VPS proaspat, punem o aplicatie reala in spatele lui, emitem un certificat Let’s Encrypt gratuit din cateva clickuri, apoi facem partea pe care majoritatea ghidurilor o sar: securizam panoul de admin si folosim access lists, ca nu orice pagina sa fie deschisa pentru tot internetul.

Ce este un reverse proxy si de ce ai nevoie de el

Un port e o usa numerotata a unui server. O singura adresa IP poate rula mai multe programe in acelasi timp, si fiecare asculta in spatele propriei usi: SSH de obicei pe 22, traficul web pe 80 (HTTP) si 443 (HTTPS). Browserele bat automat la 80 sau 443, de aceea nu le scrii niciodata. Orice alt port trebuie scris in adresa, si exact asta arata neprofesionist si strica HTTPS-ul.

Un reverse proxy e un program care sta pe porturile 80 si 443, citeste ce nume de domeniu a cerut vizitatorul (header-ul Host trimis de browser) si trimite cererea mai departe catre aplicatia potrivita. Vizitatorii vorbesc doar cu proxy-ul. Aplicatiile nu mai au nevoie deloc de un port public.

Un certificat TLS (numit inca, din obisnuinta, certificat SSL) e ce transforma http:// in https://: dovedeste browserului ca serverul chiar apartine domeniului si cripteaza traficul. Let’s Encrypt e o autoritate de certificare gratuita si automatizata. Certificatele ei sunt valabile o perioada scurta (in prezent 90 de zile), deci trebuie reinnoite automat, iar reverse proxy-ul e locul natural unde se face asta.

Un reverse proxy in fata aplicatiilor iti aduce:

  • Un singur punct de intrare public. Doar 80 si 443 sunt deschise spre internet, aplicatiile raman interne.
  • HTTPS intr-un singur loc. Certificatele sunt cerute, pastrate si reinnoite de proxy, nu de fiecare aplicatie separat.
  • URL-uri curate. Un subdomeniu pe aplicatie, fara numere de port.
  • Un singur loc pentru reguli, cum ar fi liste de IP-uri permise, parole sau redirectari.

Ce este Nginx Proxy Manager

Nginx e unul dintre cele mai folosite servere web din lume, rapid si stabil, dar se configureaza prin fisiere text in care e usor sa gresesti un detaliu. NPM impacheteaza Nginx intr-un container (o aplicatie ambalata cu tot ce ii trebuie, izolata de restul sistemului si pornita dintr-o imagine) si adauga deasupra o interfata web.

In acest singur container ai o versiune de Nginx (OpenResty) care face efectiv proxy-ul, un backend Node.js cu API REST, interfata de administrare pe portul 81, un client Let’s Encrypt pentru certificate si o baza de date SQLite mica in care se pastreaza setarile. Tu dai click, NPM scrie configuratia Nginx si o reincarca pentru tine.

Ce primesti din cutie:

  • Proxy hosts: legi un domeniu de un container sau de un IP si port.
  • SSL gratuit: certificate Let’s Encrypt prin provocare HTTP, sau prin DNS pentru wildcard, cu reinnoire automata.
  • Access lists: reguli de tip allow si deny pe IP si autentificare HTTP basic.
  • Redirection hosts, 404 hosts si streams (forwarding TCP si UDP).
  • Mai multi utilizatori cu permisiuni, plus un jurnal de audit cu cine ce a schimbat.
  • Un tab Advanced in care poti lipi directive Nginx brute atunci cand interfata nu e de ajuns.

Cand se potriveste NPM si cand e mai bun alt tool

NPM e potrivit pentru cateva pana la cateva zeci de site-uri administrate de oameni care prefera clickul in locul editarii de fisiere: firme mici, freelanceri, homelab-uri, echipe in care nu toata lumea traieste in terminal. Daca vrei configuratia proxy-ului versionata in Git si revizuita ca orice cod, Caddy (un singur Caddyfile scurt) sau Traefik (configurat prin label-uri Docker) se potrivesc mai bine. NPM foloseste si mai multa memorie decat un Nginx simplu, pentru ca vine cu un backend Node.js si o interfata, desi pe orice VPS modern diferenta conteaza rar.

RAM aproximativ in repaus pentru reverse proxy-uri uzualeNginx (config manual)~10 MBCaddy~35 MBTraefik~70 MBNginx Proxy Manager~150 MB050100150200RAM in repaus, MB (aproximativ)Masurat in repaus cu cateva host-uri, variaza cu versiunea si traficulReverse proxy
Figura 3 (aratata mai devreme pentru context): NPM consuma cam 100-200 MB de RAM pentru ca include o interfata si un backend Node.js, tot confortabil pe cel mai mic VPS. Valorile sunt aproximative.

De ce ai nevoie

  • Un VPS DreamServer cu Debian 13 sau Ubuntu 24.04. Un VPS KVM e cea mai simpla alegere. Docker merge si intr-un container LXC, dar intr-un LXC unprivileged are nevoie de optiunea nesting activata, iar ufw s-ar putea sa nu functioneze in interior; daca ai dubii, intreaba suportul nostru sau alege KVM.
  • Minim 1 GB de RAM si cativa GB liberi pe disc. NPM plus doua-trei aplicatii mici incap fara probleme.
  • Un utilizator cu sudo si acces SSH (nu lucram direct ca root).
  • Un nume de domeniu la care poti edita inregistrarile DNS, de exemplu exemplu.ro.
  • Porturile 80 si 443 libere pe VPS: fara Apache sau Nginx instalat direct pe host.
  • Cam 30 de minute.

Cum se leaga piesele intre ele

Inainte sa scriem ceva, ajuta sa vedem imaginea finala. Vizitatorii ajung la VPS pe porturile 80 si 443, pe care Docker le publica pentru containerul NPM. NPM si aplicatiile tale impart o retea Docker privata numita proxy, deci NPM ajunge la fiecare aplicatie dupa numele containerului, iar aplicatiile nu publica niciun port. Interfata de admin de pe portul 81 e legata de 127.0.0.1, adica raspunde doar din interiorul VPS-ului, iar noi ajungem la ea printr-un tunel SSH.

VPS DreamServer (Debian 13 sau Ubuntu 24.04)Vizitatoridin internetLaptopul taubrowser + SSHretea docker: proxyNginx Proxy Manager80 / 443: public81: panou admin(doar 127.0.0.1)client Let's Encryptuptime-kumaport container 3001aplicatia-taport container 8080porturile 80, 443publicate de Docker./dataSQLite, config, loguri./letsencryptcertificate, cheibind mounts pe discul VPS-uluifirewall ufwpermite SSH :22tunel SSH spre :81Porturile publicate de Docker ocolesc ufw,deci portul de admin ramane pe 127.0.0.1
Figura 1: Vizitatorii ajung la NPM pe 80/443, aplicatiile stau in reteaua comuna proxy fara porturi publice, iar panoul de admin de pe portul 81 e accesibil doar prin tunel SSH. ufw protejeaza serviciile host-ului, cum e SSH, nu porturile publicate de Docker.

Un detaliu din diagrama merita repetat, pentru ca ii surprinde pe aproape toti: Docker isi scrie propriile reguli de firewall, iar porturile pe care le publica ocolesc ufw. Daca publici 81:81, ufw nu-l poate ascunde, nici cu o regula deny. Controlul real e ce publici si pe ce adresa. De aceea portul de admin e legat de 127.0.0.1 inca de la prima pornire.

Iata traseul pe care il urmam. Numerele corespund titlurilor pasilor de mai jos.

Instalare Nginx Proxy Manager in 8 pasiPasul 1DNS + firewallPasul 2Instalare DockerPasul 3Fisier ComposePasul 4Pornire + tunel SSHPasul 5Conectezi o aplicatiePasul 6Proxy host nouPasul 7Certificat SSLPasul 8Securizare adminPasii 1-8 corespund sectiunilor numerotate de mai jos, cam 30 de minute
Figura 2: Pasii 1-4 pregatesc serverul si pornesc NPM, pasii 5-8 pun o aplicatie in spatele lui, adauga HTTPS si restrictioneaza accesul.

Pasul 1: Indrepti DNS-ul spre VPS si pregatesti firewall-ul

Let’s Encrypt emite un certificat doar daca poate ajunge la domeniul tau pe VPS, asa ca incepem cu DNS-ul: propagarea poate dura cateva minute, timp in care faci restul.

In panoul furnizorului de DNS, creeaza inregistrari A catre adresa IPv4 publica a VPS-ului. In ghidul asta folosim:

  • status.exemplu.ro: pentru Uptime Kuma, aplicatia noastra de exemplu
  • npm.exemplu.ro: pentru panoul de admin NPM (il folosim la Pasul 8)

Daca VPS-ul are si IPv6, poti adauga inregistrari AAAA cu adresa IPv6. Daca nu folosesti IPv6, asigura-te ca nu exista o inregistrare AAAA veche care arata in alta parte: Let’s Encrypt prefera IPv6 cand exista, iar o inregistrare AAAA uitata e un motiv clasic de certificate esuate.

Acum intra pe VPS si adu-l la zi:

sudo apt update && sudo apt full-upgrade -y
sudo apt install -y bind9-dnsutils

A doua linie instaleaza dig, un utilitar de interogare DNS. Verifica daca inregistrarile duc deja la VPS:

dig +short status.exemplu.ro
dig +short npm.exemplu.ro

Fiecare comanda ar trebui sa afiseze IP-ul VPS-ului. Daca rezultatul e gol, inregistrarea nu s-a propagat inca, mai asteapta cateva minute.

Despre restart dupa upgrade: pe Ubuntu, fisierul /var/run/reboot-required apare cand e nevoie de restart. Debian nu creeaza mereu acest fisier, deci pe Debian dai restart daca upgrade-ul a instalat un pachet linux-image nou.

# Ubuntu: afiseaza un mesaj daca e nevoie de restart
[ -f /var/run/reboot-required ] && echo "E nevoie de restart"
sudo reboot

Urmeaza firewall-ul. ufw (Uncomplicated Firewall) e preinstalat pe Ubuntu, dar inactiv; pe Debian il instalezi intai. Permite intotdeauna SSH inainte sa-l activezi, altfel te blochezi singur afara:

sudo apt install -y ufw        # necesar pe Debian, inofensiv pe Ubuntu
sudo ufw allow OpenSSH         # sau: sudo ufw allow 2222/tcp daca SSH e pe alt port
sudo ufw enable
sudo ufw status verbose

Ultima comanda ar trebui sa arate Status: active si o regula care permite OpenSSH. Intentionat nu deschidem aici porturile 80, 443 sau 81. Cum am explicat mai sus, Docker isi publica porturile prin propriile reguli, deci ufw are rolul de a proteja serviciile care ruleaza direct pe host, cum e SSH. Daca esti pe un VPS LXC unprivileged si ufw enable da eroare, foloseste firewall-ul din panoul de control.

Pasul 2: Instalezi Docker Engine si pluginul Compose

Instalam Docker din repository-ul oficial Docker, mai nou decat pachetele din distributie si care include pluginul Compose v2. Acelasi bloc merge pe Debian 13 si pe Ubuntu 24.04, pentru ca citeste numele distributiei din /etc/os-release:

sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
. /etc/os-release
sudo curl -fsSL "https://download.docker.com/linux/${ID}/gpg" -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/${ID}
Suites: ${VERSION_CODENAME}
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Ce se intampla aici: . /etc/os-release incarca doua variabile, ID (debian sau ubuntu) si VERSION_CODENAME (trixie sau noble). Descarcam cheia de semnare Docker, scriem repository-ul in formatul modern deb822 in /etc/apt/sources.list.d/docker.sources si instalam engine-ul impreuna cu pluginul Compose.

Verifica daca totul merge:

sudo docker run --rm hello-world
docker compose version

Ar trebui sa vezi “Hello from Docker!” si o linie de tipul Docker Compose version v2.x.x. Ca sa rulezi docker fara sudo, adauga utilizatorul in grupul docker, apoi iesi si intra din nou in sesiune:

sudo usermod -aG docker "$USER"

Retine ca apartenenta la grupul docker inseamna practic acces root pe server, deci adauga doar utilizatori de incredere.

Optional, dar recomandat: implicit Docker pastreaza logurile containerelor la nesfarsit. Ca sa le rotesti, pune urmatorul continut in /etc/docker/daemon.json. Daca fisierul exista deja, combina aceste chei cu ce ai acolo, nu-l suprascrie:

{
  "log-driver": "json-file",
  "log-opts": { "max-size": "10m", "max-file": "3" }
}
sudo systemctl restart docker

Setarea se aplica containerelor create dupa schimbare, adica tuturor celor pe care le cream de aici incolo.

Pasul 3: Scrii docker-compose.yml pentru Nginx Proxy Manager

Mai intai cream reteaua comuna. Daca o creezi separat (nu in fisierul Compose al NPM), poti opri sau recrea NPM fara ca Docker sa se planga ca inca sunt aplicatii conectate:

docker network create proxy
mkdir -p ~/npm && cd ~/npm
nano docker-compose.yml

Lipeste continutul:

services:
  npm:
    image: jc21/nginx-proxy-manager:2
    container_name: npm
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "127.0.0.1:81:81"
    environment:
      TZ: "Europe/Bucharest"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    networks:
      - proxy

networks:
  proxy:
    external: true

Pe rand:

  • image: jc21/nginx-proxy-manager:2 foloseste linia majora 2.x actuala, deci primesti corecturi fara sa sari din greseala la o versiune majora viitoare. Documentatia oficiala arata des :latest, care merge si el, dar poate aduce schimbari incompatibile la orice pull. Verifica pagina de release-uri a proiectului pentru cea mai noua versiune inainte sa incepi.
  • restart: unless-stopped reporneste NPM dupa un restart al serverului sau dupa o cadere.
  • "80:80" si "443:443" publica HTTP si HTTPS spre lume; sunt singurele usi publice.
  • "127.0.0.1:81:81" publica panoul de admin doar pe adresa de loopback. Nimeni din internet nu ajunge la el, indiferent de ufw.
  • ./data contine baza SQLite, configuratiile Nginx generate si logurile; ./letsencrypt contine certificatele si cheile private. Ambele sunt bind mounts, foldere simple langa fisierul Compose, ceea ce face backup-ul usor.
  • networks: proxy cu external: true conecteaza NPM la reteaua creata mai sus.

Salveaza cu Ctrl+O, Enter, si iesi cu Ctrl+X.

Pasul 4: Pornesti stack-ul si te loghezi printr-un tunel SSH

Porneste NPM in fundal:

docker compose up -d
docker compose ps

Prima comanda descarca imaginea si afiseaza Container npm Started. A doua ar trebui sa arate containerul cu statusul Up. Ca sa urmaresti pornirea, ruleaza docker compose logs -f npm si asteapta pana se opreste derularea fara erori (la prima pornire ruleaza migrarile bazei de date), apoi apasa Ctrl+C.

Doua verificari rapide chiar de pe VPS:

curl -sI http://127.0.0.1:81 | head -n 1
curl -sI http://127.0.0.1 | head -n 1

Ambele ar trebui sa raspunda HTTP/1.1 200 OK: prima e interfata de admin, a doua pagina implicita “Congratulations” a NPM.

Acum deschide panoul de admin de pe laptop. Un tunel SSH trimite un port de pe calculatorul tau, prin conexiunea SSH criptata pe care o ai deja, catre un port de pe server. Pe laptop (Linux, macOS sau PowerShell pe Windows 10/11):

ssh -N -L 8181:127.0.0.1:81 utilizator@203.0.113.10

Lasa fereastra deschisa si intra in browser pe http://localhost:8181. -L 8181:127.0.0.1:81 inseamna “portul meu local 8181 duce la 127.0.0.1:81 vazut de pe VPS”, iar -N nu deschide shell, doar tunelul.

Daca o sa faci asta des, adauga un alias de host separat in ~/.ssh/config pe laptop, ca intrarea ta normala de SSH pentru administrare sa ramana neatinsa:

Host npm-tunnel
    HostName 203.0.113.10
    User utilizator
    # Port 2222   # doar daca SSH ruleaza pe un port nestandard
    LocalForward 8181 127.0.0.1:81

De acum, ssh -N npm-tunnel deschide tunelul.

Prima logare: in functie de versiunea NPM, fie primesti un ecran care iti cere sa creezi primul cont de admin, fie un formular de login unde datele implicite sunt admin@example.com cu parola changeme, urmat imediat de schimbarea obligatorie a emailului si parolei. In ambele cazuri foloseste o adresa de email reala (Let’s Encrypt o foloseste pentru notificari de expirare) si o parola lunga si unica din managerul tau de parole.

Pasul 5: Conectezi o aplicatie la reteaua proxy

NPM are nevoie de ceva caruia sa-i faca proxy. Folosim Uptime Kuma, un tool de monitorizare, dar tiparul e identic pentru orice aplicatie in container: o conectezi la reteaua proxy si stergi sectiunea ports:, ca sa fie accesibila doar prin NPM.

mkdir -p ~/apps/uptime-kuma && cd ~/apps/uptime-kuma
nano docker-compose.yml
services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    container_name: uptime-kuma
    restart: unless-stopped
    volumes:
      - ./data:/app/data
    networks:
      - proxy

networks:
  proxy:
    external: true

Ca si la NPM, verifica release-urile Uptime Kuma pentru versiunea curenta. Porneste-l si confirma ca ambele containere sunt in aceeasi retea:

docker compose up -d
docker network inspect proxy --format '{{range .Containers}}{{.Name}} {{end}}'
docker run --rm --network proxy curlimages/curl -sI http://uptime-kuma:3001

A doua comanda ar trebui sa afiseze npm uptime-kuma (in orice ordine). A treia porneste un container temporar in aceeasi retea si cere aplicatia dupa nume: un raspuns 200 sau 302 inseamna ca aplicatia e accesibila din interiorul retelei. Docker ofera un mic DNS intern in retelele definite de utilizator, de aceea numele containerului functioneaza ca hostname.

Pasul 6: Adaugi un proxy host

Inapoi in panoul NPM (prin tunel), mergi la Hosts > Proxy Hosts > Add Proxy Host. In tab-ul Details completeaza:

  • Domain Names: status.exemplu.ro (apasa Enter dupa ce il scrii, ca sa devina eticheta)
  • Scheme: http. Traficul dintre NPM si aplicatie ramane in interiorul VPS-ului; HTTPS-ul e gestionat de NPM in fata.
  • Forward Hostname / IP: uptime-kuma, numele containerului
  • Forward Port: 3001, portul pe care asculta aplicatia in interiorul containerului, nu un port de pe host
  • Block Common Exploits: activat
  • Websockets Support: activat. Uptime Kuma, ca multe aplicatii moderne, foloseste websockets pentru actualizari live; fara asta, dashboard-ul se tot deconecteaza.

Lasa Cache Assets dezactivat daca nu stii sigur ca aplicatia are de castigat. Apasa Save (etichetele pot diferi putin intre versiunile NPM, dar campurile sunt aceleasi). Host-ul apare cu statusul “Online”.

Deschide http://status.exemplu.ro in browser. Ar trebui sa vezi ecranul de configurare Uptime Kuma. Versiunea 2 intreaba mai intai ce baza de date sa foloseasca; varianta SQLite integrata e perfecta pentru o instanta mica. Cum aplicatia e acum accesibila public, creeaza imediat contul de admin, inainte sa-l revendice altcineva. Si mai bine, treci direct la Pasul 7 si fa configurarea peste HTTPS.

Pasul 7: Emiti un certificat Let’s Encrypt

Editeaza proxy host-ul (meniul cu trei puncte > Edit) si deschide tab-ul SSL:

  • SSL Certificate: alege Request a new SSL Certificate
  • Force SSL: activat, ca vizitatorii pe HTTP simplu sa fie redirectati spre HTTPS
  • HTTP/2 Support: activat
  • HSTS Enabled: deocamdata dezactivat (vezi notele de securitate de mai jos)
  • Email Address for Let’s Encrypt: emailul tau real
  • Bifeaza I Agree to the Let’s Encrypt Terms of Service

Apasa Save. NPM cere un certificat de la Let’s Encrypt, care se conecteaza la http://status.exemplu.ro/.well-known/acme-challenge/... pe portul 80 ca sa confirme ca tu controlezi domeniul (provocarea HTTP-01), iar dupa 10-30 de secunde dialogul se inchide. Verifica de pe orice masina:

curl -sI http://status.exemplu.ro | head -n 1
curl -sI https://status.exemplu.ro | head -n 1

Prima ar trebui sa intoarca o redirectare 301, a doua HTTP/2 200 (sau un 302 de redirectare din aplicatie). Browserul arata acum lacatul. Reinnoirea e automata: NPM reinnoieste certificatele cu mult inainte sa expire, nu ai nevoie de un cron.

Ai nevoie de un certificat wildcard, gen *.exemplu.ro, sau de un domeniu al carui port 80 nu e accesibil? Foloseste optiunea Use a DNS Challenge. NPM suporta multi furnizori DNS prin credentiale API; dovedeste ca detii domeniul creand temporar o inregistrare TXT.

Pasul 8: Securizezi panoul de admin si adaugi access lists

Momentan panoul de admin e in siguranta, pentru ca exista doar pe 127.0.0.1. Tunelul e insa putin incomod, asa ca multi vor https://npm.exemplu.ro. Putem face asta in siguranta cu un access list: un set de reguli pe care NPM le aplica inainte ca cererea sa ajunga la backend.

Creezi un access list doar pe IP pentru admin

Mai intai afla IP-ul public de pe care te conectezi. Cat timp esti logat pe VPS prin SSH, ruleaza:

echo "$SSH_CLIENT"

Primul camp (de exemplu 198.51.100.23) e IP-ul tau asa cum il vede VPS-ul. In NPM mergi la Access Lists > Add Access List:

  • Tab-ul Details: numeste-l admin-only. Lasa Satisfy Any dezactivat.
  • Tab-ul Access: adauga o regula allow 198.51.100.23 (sau o plaja precum 198.51.100.0/24 pentru reteaua unui birou), apoi o regula deny all.
  • Lasa tab-ul Authorization gol. Panoul NPM are deja login propriu, iar un strat de parola in plus l-ar strica (detalii mai jos).

Salveaza.

Pui panoul de admin pe propriul domeniu

Adauga un proxy host nou: domeniul npm.exemplu.ro, scheme http, forward hostname 127.0.0.1, forward port 81. Aici 127.0.0.1 inseamna “chiar acest container NPM”, exact unde traieste panoul de admin. Alege admin-only din lista Access List, apoi in tab-ul SSL cere un certificat cu Force SSL activat, ca la Pasul 7.

De pe IP-ul permis, https://npm.exemplu.ro deschide acum pagina de login; de oriunde altundeva primesti 403 Forbidden. Pastreaza legarea 127.0.0.1:81 din fisierul Compose: daca ti se schimba IP-ul si te blochezi afara, tunelul SSH de la Pasul 4 merge in continuare si poti actualiza regula.

Protejezi cu parola o aplicatie care nu are login

Unele lucruri nu trebuie sa fie publice, dar nu au login propriu: un site de staging, o previzualizare de documentatie, un tool simplu de administrare. Creeaza alt access list, de exemplu parola-echipa, adauga unul sau mai multi utilizatori in tab-ul Authorization si ataseaza-l acelui proxy host. Vizitatorii primesc acum o fereastra de login in browser (autentificare HTTP basic) inainte sa vada ceva.

Daca vrei ca oricare conditie sa fie suficienta (IP-ul biroului sau o parola), adauga si regulile de IP si activeaza Satisfy Any. Cu optiunea dezactivata, vizitatorul trebuie sa indeplineasca si regulile de IP, si parola.

O atentionare importanta: autentificarea basic foloseste header-ul HTTP Authorization. Aplicatiile care folosesc acelasi header pentru propriul login, cum sunt multe API-uri si chiar panoul NPM, se pot strica in spatele unui access list cu parola. Pentru ele, foloseste doar reguli de IP.

Alegi ce vad hostname-urile necunoscute

Orice domeniu indreptat spre IP-ul tau care nu corespunde unui proxy host primeste acum pagina “Congratulations” a NPM, care le spune scanerelor exact ce rulezi. In Settings > Default Site, schimb-o pe 404 Page sau No Response (444).

Backup si actualizari

Tot ce stie NPM sta in doua foldere: ~/npm/data si ~/npm/letsencrypt. Fa-le backup regulat, cu NPM oprit pentru scurt timp, ca baza SQLite sa fie consistenta:

cd ~/npm
docker compose stop
sudo tar czf ~/npm-backup-$(date +%F).tar.gz -C ~/npm data letsencrypt
docker compose start
sudo chown "$USER": ~/npm-backup-*.tar.gz

Folosim sudo pentru ca unele fisiere apartin lui root, ceea ce face si arhiva sa apartina lui root; chown o da inapoi utilizatorului tau, ca s-o poti copia de pe server de pe laptop:

scp utilizator@203.0.113.10:npm-backup-2026-11-10.tar.gz .

La restaurare (pe un VPS nou sau dupa un dezastru), restaurezi in foldere goale, niciodata peste o instanta care ruleaza:

cd ~/npm
docker compose down
sudo mv data data.old && sudo mv letsencrypt letsencrypt.old
sudo tar xzf ~/npm-backup-2026-11-10.tar.gz -C ~/npm
docker compose up -d

Ca sa actualizezi NPM, fa intai backup, citeste release notes, apoi:

cd ~/npm
docker compose pull
docker compose up -d
docker image prune -f

Depanare si greseli frecvente

  • 502 Bad Gateway. NPM nu ajunge la aplicatie. Verifica daca containerul aplicatiei ruleaza, daca e in reteaua proxy (docker network inspect proxy) si daca portul de forward e cel din interiorul containerului. Testul cu curlimages/curl de la Pasul 5 iti spune repede daca problema e la aplicatie sau la NPM.
  • Cererea de certificat esueaza cu “Internal Error”. De obicei DNS-ul nu arata inca spre acest VPS, o inregistrare AAAA veche arata in alta parte, sau portul 80 e blocat de un firewall extern. Daca ai un proxy CDN in fata domeniului, dezactiveaza-l in timpul emiterii sau foloseste provocarea DNS. Dupa 5 incercari esuate pentru acelasi hostname, Let’s Encrypt te limiteaza temporar, deci repara cauza inainte sa reincerci.
  • NPM nu porneste: “port is already allocated” sau “address already in use”. Altceva asculta pe 80 sau 443. Gaseste-l cu sudo ss -tlnp | grep -E ':(80|443) ' si opreste-l sau dezinstaleaza-l, de obicei un Apache (sudo systemctl disable --now apache2) sau Nginx (sudo systemctl disable --now nginx) instalat pe host.
  • Nu pot deschide http://IP:81 in browser. Asa e gandit: portul e legat de 127.0.0.1. Foloseste tunelul SSH de la Pasul 4.
  • Aplicatia se tot deconecteaza sau arata “reconnecting”. Activeaza Websockets Support pentru acel proxy host.
  • Upload-urile esueaza cu “413 Request Entity Too Large”. Editeaza proxy host-ul, deschide tab-ul Advanced si adauga client_max_body_size 100m; (ajusteaza dimensiunea).
  • Access list-ul ma blocheaza de pe un IP permis. Uita-te in ~/npm/data/logs/proxy-host-N_access.log (N e ID-ul host-ului) ca sa vezi ce adresa primeste NPM de fapt. Daca navighezi pe IPv6, adauga si adresa IPv6; daca toti vizitatorii apar cu o adresa 172.x.x.x, conexiunile vin prin proxy-ul userland al Docker si regulile de IP nu vor vedea clientii reali.
  • Bucla de restart dupa actualizare. Ruleaza docker compose logs npm si citeste release notes; la nevoie, revino la tag-ul anterior si restaureaza backup-ul.

Note de securitate

  • Nu publica niciodata portul 81 public. Pastreaza 127.0.0.1:81:81. Tine minte ca ufw nu filtreaza porturile publicate de Docker, deci o regula ufw deny 81 iti da un fals sentiment de siguranta.
  • Aplicatiile nu au ports:. Fiecare aplicatie ajunge in internet doar prin NPM. Un ports: - "8080:8080" uitat o expune pe HTTP simplu, ocolind access lists.
  • Credentiale de admin puternice si unice, plus un utilizator NPM separat pentru fiecare persoana, cu doar permisiunile de care are nevoie.
  • HSTS cu grija. HSTS le spune browserelor sa refuze HTTP simplu pentru domeniul tau timp de luni de zile. Activeaza-l doar dupa ce HTTPS merge sigur, si activeaza HSTS Subdomains doar daca toate subdomeniile au certificat valid.
  • “Block Common Exploits” nu e un WAF. Filtreaza cateva tipare de atac evidente; aplicatiile tale au nevoie in continuare de actualizari si parole bune.
  • Trateaza backup-urile ca pe niste secrete. Folderul letsencrypt contine chei private; pastreaza arhivele criptate sau intr-un loc cu acces restrans.
  • Tine imaginea la zi si host-ul actualizat. Urmareste release-urile proiectului pe GitHub ca sa stii cand sa actualizezi.

Deci, merita Nginx Proxy Manager?

Daca rulezi cateva aplicatii self-hosted pe un VPS si vrei domenii curate cu HTTPS fara sa devii expert in Nginx, NPM cu Docker Compose e una dintre cele mai rapide cai: un singur container, o interfata prietenoasa, certificate care se reinnoiesc singure si access lists care se aplica in cateva secunde. Tine portul de admin pe localhost, nu da aplicatiilor porturi publice, fa backup la doua foldere, si ai un setup comod si solid in acelasi timp. Daca mai tarziu vrei totul ca cod in Git, Caddy sau Traefik sunt pasul firesc urmator.

Poti avea toate acestea pe un VPS din data center-ul nostru din Romania in cam o jumatate de ora, sau lasa echipa noastra de administrare servere sa-ti configureze proxy-ul, certificatele si regulile de securitate.

Intrebari frecvente

Poate Nginx Proxy Manager sa faca proxy pentru aplicatii care nu ruleaza in Docker?

Da. Pune ca forward hostname un IP la care containerul poate ajunge. Pentru un serviciu care ruleaza direct pe VPS, adauga extra_hosts: ["host.docker.internal:host-gateway"] la serviciul NPM, foloseste host.docker.internal ca forward hostname si asigura-te ca serviciul asculta pe o adresa accesibila din Docker, nu doar pe 127.0.0.1. Poti trimite trafic si catre alte servere din reteaua ta privata.

Am nevoie de MySQL sau MariaDB pentru NPM?

Nu. Versiunile actuale folosesc implicit SQLite, salvat in ./data, mai mult decat suficient pentru sute de host-uri. O baza externa MySQL/MariaDB e suportata daca o preferi, dar inseamna inca un container si mai mult de pus la backup.

Cum obtin un certificat wildcard?

Foloseste provocarea DNS din tab-ul SSL, alege furnizorul DNS si introdu credentialele API. Certificatele wildcard precum *.exemplu.ro pot fi validate doar prin DNS, nu prin portul 80.

Merge pe cel mai mic VPS?

Da. NPM sta in repaus la cam 100-200 MB de RAM, deci un VPS cu 1 GB il ruleaza confortabil, plus cateva aplicatii usoare. De obicei aplicatiile, nu proxy-ul, decid cat RAM iti trebuie.

E sigur tag-ul :2 sau ar trebui sa fixez o versiune exacta?

:2 urmareste versiunea majora curenta, un echilibru bun pentru majoritatea. Daca ai nevoie de deploy-uri perfect reproductibile, fixeaza o versiune exacta din pagina de release-uri si actualizeaz-o constient, dupa ce citesti changelog-ul.

Avem Incredere & Suntem Membri

Suntem membri ai principalelor organizatii de infrastructura internet.

RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX