Docker rezolva „merge pe masina mea", dar in productie ai nevoie de un punct de intrare controlat: Nginx in fata containerelor, cu TLS terminat intr-un singur loc, retele izolate si porturi inchise. Ghid practic, pas cu pas, cu docker-compose.
De ce Docker + Nginx
- Izolare si reproductibilitate — fiecare aplicatie cu dependintele ei, identic pe dev si productie.
- Un singur punct de intrare — Nginx termina TLS o data si ruteaza catre containere dupa domeniu/cale.
- Suprafata de atac mica — doar 80/443 expuse; bazele de date raman in reteaua interna Docker, fara port public.
- Operare simpla — restart policy, healthcheck, update prin re-pull de imagine.
Arhitectura
Internetul atinge doar Nginx (80/443). Nginx face proxy catre containerele de aplicatie printr-o retea bridge interna Docker. Baza de date e in aceeasi retea, dar NU publica niciun port catre exterior.
Pas 1 — Instalare Docker
- Instaleaza Docker Engine + plugin-ul compose (Debian/Ubuntu): pachetele
docker-ce docker-ce-cli containerd.io docker-compose-plugindin repo-ul oficial Docker. - Verifica:
docker run --rm hello-worldsidocker compose version. - Creeaza o retea dedicata:
docker network create web(retea user-defined = rezolvare DNS intre containere pe nume).
Pas 2 — docker-compose pentru aplicatie
Exemplu docker-compose.yml cu o aplicatie + Postgres, healthcheck si restart policy:
- services.app:
image,restart: unless-stopped,expose: ["8080"](NUports— nu expune public),networks: [web],healthcheckcutest: curl -f http://localhost:8080/health. - services.db:
image: postgres:16,volumes: [dbdata:/var/lib/postgresql/data],networks: [web], FARAports— accesibila doar intern. - Secretele (parole) prin
environmentdin fisier.env(nu in imagine), sausecrets. - Porneste:
docker compose up -d; verifica:docker compose ps,docker compose logs -f app.
Pas 3 — Nginx reverse proxy
Nginx (pe host sau ca container in aceeasi retea web) face proxy catre container pe numele serviciului:
upstreamsauproxy_pass http://app:8080;(numele „app" se rezolva prin DNS-ul retelei Docker).- Headere corecte:
proxy_set_header Host $host;X-Real-IP $remote_addr;X-Forwarded-For $proxy_add_x_forwarded_for;X-Forwarded-Proto $scheme; - WebSocket (daca e cazul):
proxy_http_version 1.1;+Upgrade/Connection. - Rutare multi-app: dupa
server_name(domenii diferite) saulocation /app2/catreproxy_pass http://app2:3000;.
Pas 4 — TLS cu Let's Encrypt
- Redirect
80 -> 443pentru tot traficul uman; lasa deschis doar/.well-known/acme-challenge/pe 80. - Certificat:
certbot --webroot(sau containerulcertbotin compose) cu reinnoire automata. - In blocul 443:
ssl_certificate/ssl_certificate_key,ssl_protocols TLSv1.2 TLSv1.3.
Pas 5 — Hardening
- Fara porturi inutile: doar Nginx publica 80/443. DB si app folosesc
expose, nuports. - Non-root in container:
user:in compose sauUSERin Dockerfile; evita rularea ca root. - Read-only + no-new-privileges:
read_only: true,security_opt: [no-new-privileges:true],cap_drop: [ALL]. - Limite resurse:
deploy.resources.limits(CPU/RAM) ca un container sa nu doboare hostul. - Security headers la Nginx: HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, CSP.
- Imagini mici + update: baze
-slim/alpine, scaneaza cudocker scout/ Trivy, re-pull periodic.
Let's Encrypt automat
Certificatul nu trebuie reinnoit manual. Certbot instaleaza un systemd timer (certbot.timer) care ruleaza certbot renew de doua ori pe zi si reinnoieste doar ce expira in mai putin de 30 de zile.
- Reincarcare nginx dupa reinnoire:
certbot renew --deploy-hook "nginx -s reload". - Test fara emitere reala:
certbot renew --dry-run. - In Docker: fie un container
certbotcu volum partajat cu nginx (reinnoire in bucla), fie pattern-ulnginx-proxy+acme-companioncare emite si reinnoieste automat certificate per container, dupa variabileleVIRTUAL_HOST/LETSENCRYPT_HOST.
GeoIP + firewall cu nftables
Blocarea pe tara se poate face pe doua niveluri. La nivel nginx (modul GeoIP2 + map $geoip2_country_code) raspunzi cu 403. Mai eficient e sa pici pachetele in nftables inainte sa ajunga la nginx — blochezi si scanarile, nu doar cererile HTTP.
- Pui prefixele de tara intr-un set nftables (interval):
set blocked_cc { type ipv4_addr; flags interval; }. - Regula in lantul input:
ip saddr @blocked_cc drop(sau invers, whitelist: accepta doar tarile permise). - Sursa prefixelor: liste per tara (ex. ipdeny.com) sau baza GeoIP; un script cu cron reincarca setul zilnic.
- Persistenta in
/etc/nftables.conf; verificare cunft list ruleset. - Blacklist vs whitelist: blacklist (blochezi cateva tari cu risc) e sigur; whitelist (doar RO + cateva) e agresiv — poate bloca boti legitimi/CDN, testeaza intai.
CrowdSec pe logurile Nginx
CrowdSec citeste logurile nginx (access.log / error.log), aplica scenarii si blocheaza IP-urile ostile — cu inteligenta colectiva (IP-uri raportate de toata reteaua CrowdSec).
- Acquisition: in
/etc/crowdsec/acquis.yamladaugi caile logurilor nginx (tipnginx). - Colectii:
cscli collections install crowdsecurity/nginx crowdsecurity/base-http-scenarios crowdsecurity/http-cve— detecteaza brute-force, scanari de path, flood, user-agent malitios, tentative de exploit. - Bouncer (aplica blocarea):
crowdsec-firewall-bouncerpune IP-urile intr-un set nftables (crowdsec-blacklists) → drop; saucrowdsec-nginx-bouncercare raspunde 403 la nivel de nginx. - Operare:
cscli decisions list,cscli metrics,cscli alerts list; inrolare in consola CrowdSec pentru dashboard + blocklist-uri comunitare (CTI). - vs fail2ban: CrowdSec are scenarii mai bogate si reputatie colaborativa; fail2ban ramane bun pentru reguli simple, locale.
Logging si operare
- Loguri:
docker compose logs; pentru productie, driverjson-filecumax-size/max-filesau trimite la un stack de log-uri (Loki). - Update aplicatie:
docker compose pull && docker compose up -d(recreare doar ce s-a schimbat). - Backup: volumele (
dbdata) —docker run --rm -v dbdata:/data ...saupg_dumpprogramat. - Sanatate:
docker compose psarata starea healthcheck; restart policy repune containerul cazut.
Concluzie
Pattern-ul Nginx + Docker iti da deploy reproductibil, un singur punct de intrare TLS si o suprafata de atac minima — potrivit de la un singur VPS pana la mai multe noduri. Il proiectam, il securizam si il monitorizam pentru tine.