Configurar un servidor web amb Nginx a Debian des de zero
Muntar un servidor web amb Nginx a Debian pot semblar una tasca directa —i ho és, en molts sentits— però quan ho fas amb regularitat en entorns reals, t’adones que no tot està en els comandaments. La diferència entre una instal·lació funcional i una instal·lació útil i fàcil de mantenir està en els detalls: decisions de disseny, convencions internes, errors recurrents, i petites configuracions que fan que el servidor no només arrenqui, sinó que aguanti.
1. Per què Nginx i per què Debian
Nginx és una elecció habitual per la seva arquitectura simple, bon rendiment i una corba de configuració raonable. És estable, suporta HTTP/2 sense complicacions, gestiona TLS decentment i té una sintaxi declarativa que, tot i que té les seves rareses, permet mantenir configuracions llegibles.
Debian és el sistema lliure base en què confiar quan volem estabilitat sense sorpreses. Les versions estables de Debian no no estan a l’última, però rara vegada et deixen tirat. Quan necessitem versions més recents (com per a Nginx), podem optar per backports o instal·lar des del repositori oficial de Nginx, no des de les fonts. Llevat que hi hagi una necessitat específica, compilar és innecessari i complica l’actualització a llarg termini.
2. Instal·lació: decisions que cal prendre
Repositori oficial vs. paquets de Debian
Els paquets de Debian funcionen bé, però solen estar una mica per darrere en versions. Si necessitem alguna cosa com a http3 o millores recents en TLS, tirem del repo oficial de Nginx:
curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian/ $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo apt install nginx
Fem aquest repositori perquè ve amb els binaris compilats directament per l’ equip de Nginx, amb suport per a la majoria de mòduls comuns. Però també té diferències: l’estructura de directoris no és exactament la mateixa que la del paquet de Debian (/etc/nginx segueix igual, però alguns paths de logs i scripts difereixen).
Configuració inicial
Abans de llançar-nos a configurar server blocks, revisem dues coses:
- Firewall: UFW està activat? iptables? No donem per fet que el port 80/443 estigui obert.
- Usuaris i permisos: Nginx córrer sovint amb www-data, però convé verificar que no hi hagi conflictes si es fan servir sockets de PHP o proxys cap a apps amb usuaris propis.
Una bona pràctica que és limitar la quantitat de mòduls i configuracions que no fem servir. L’arxiu principal /etc/nginx/nginx.conf ve amb coses com logs d’accés molt verbosos o worker_processes en auto. Els podem adaptar segons el context, especialment si sabem que s’ha de servir contingut estàtic o fer proxy a una app com Flask, Node o Rails.
3. Estructura de configuració
Molts setups fallen no per errors de sintaxi, sinó per desordre. Una estructura clara ens estalvia temps cada vegada que tornem a un servidor setmanes després.
Aquesta és una bona distribució:
/etc/nginx/
├── nginx.conf
├── conf.d/
│ ├── global.conf
├── sites-available/
│ ├── exemple.com.conf
│ └── api.exemple.com.conf
├── sites-enabled/
Sí, Debian fa servir sites-available i sites-enabled, però el repo oficial no ho fa per defecte. Els podem crear manualment. La pràctica d’enllaçar arxius des de sites-available a sites-enabled ens permet activar/desactivar llocs fàcilment amb un ln -s i sense tocar la resta de la configuració.
Truc habitual: configurar els includes explícitament a nginx.conf:
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
Dins de conf.d/global.conf fiquem regles comunes: mida de càrrega, headers de seguretat bàsics, configuració de logs compartits, etc. Així evitem repetir-les a cada lloc.
4. Blocs server: el que funciona
Una configuració de lloc bàsica però sensata que podem fer servir com a punt de partida:
server {
listen 80;
server_name exemple.com www.exemple.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name exemple.com www.exemple.com;
ssl_certificate /etc/letsencrypt/live/exemple.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/exemple.com/privkey.pem;
include /etc/nginx/conf.d/ssl_params.conf;
root /var/www/exemple.com/public;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
Un parell de decisions aquí:
- Fem redirecció 301 des d’HTTP a HTTPS amb un bloc separat. Evita errors de configuració i manté els logs nets.
- Fem servir http2 llevat que estiguem segurs que el client no ho suportarà. Està ben suportat des de fa anys.
- No posem listen [::]:443 llevat que es necessiti suport IPv6. La majoria de desplegaments petits no ho requereix i redueix problemes si no tens ben configurat IPv6 en el sistema.
5. Certificats: com fer-ho amb Let’s Encrypt
Fem servir certbot en mode standalone només quan no tinguem un Nginx corrent. En la resta dels casos, és preferible el plugin –nginx, però desactivant l’edició automàtica de l’arxiu de configuració. Exemple:
certbot --nginx --no-eff-email --agree-tos -m admin@exemple.com -d exemple.com -d www. exemple.com
Un cop fet, movem la configuració SSL que genera certbot a un arxiu extern (ssl_params.conf) i la mantenim.
Quant a renovació, deixem que certbot renew s’executi via cron, però sempre provem primer amb:
certbot renew --dry-run
I ens assegurem que el hook de reload funcioni bé. El comandament típic que funciona:
--deploy-hook "systemctl reload nginx"
Mai reiniciem Nginx des del hook. Recarregar (reload) és més segur i no interromp connexions actives.
6. Logs: on i per què
Per defecte, Nginx ho logueja tot. Per a trànsit real, això es pot tornar un problema. Configurem els logs així:
access_log /var/log/nginx/ejemplo.com.access.log main;
error_log /var/log/nginx/ejemplo.com.error.log warn;
I definim un format de log més concís a nginx.conf:
log_format main '$remote_addr - $host [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
Quan fem servir Cloudflare o altres proxies, ajustem real_ip_header i set_real_ip_from correctament. Això és una font freqüent de logs amb IPs irrellevants (normalment 127.0.0.1 o la del proxy), i cal solucionar-ho per tenir estadístiques útils o diagnòstics reals.
7. Seguretat bàsica
- TLS mínim a 1.2, a 1.3 si el client el suporta.
- Capçaleres: fem servir almenys X-Content-Type-Options, X-Frame-Options, Referrer-Policy, i Content-Security-Policy (tot i que aquesta última amb cura per no trencar frontend moderns).
- Desactivem server_tokens per evitar exposar la versió de Nginx.
- Fem servir limit_req_zone quan exposem APIs públiques que poden rebre peticions en ràfega.
- Per a zones d’administració, limitem IPs amb allow/deny o protegim amb auth bàsica si és inevitable.
8. Problemes comuns
- Errors 502 en usar PHP-FPM: gairebé sempre és per fastcgi_pass apuntant al socket incorrecte, o perquè l’user de Nginx no pot accedir al socket. Verifiquem permisos i rutes, i fem servir (127.0.0.1:9000) si hi ha conflictes amb sockets.
- Nginx no aixeca per “bind failed”: un altre procés està ocupant el port, o l’ha bloquejat. Verifiquem amb ss -tulpn i systemctl status.
- Canvis que no tenen efecte: el primer que fem és validar amb nginx -t i després systemctl reload nginx. Si no hi ha errors, de vegades el navegador ha deixat en memòria redireccions o headers, així que provem en incògnit o amb curl -v.
9. Checklist tècnica: pas a pas realista per desplegar Nginx a Debian
Aquest és el procediment que podem seguir en muntar Nginx en un servidor Debian tot just configurat. No és un guió rígid, sinó una guia pensada per evitar errors tontos, mantenir l’ordre i deixar tot preparat per créixer sense caos. Tot això assumeix un sistema net, sense panells de control ni configuracions heretades.
1. Actualitza el sistema
apt update & apt upgrade -y
Encara que sembli obvi, sovint em trobo amb servidors on no s’ha fet això després de la instal·lació base, i després apareixen errors per dependències trencades o binaris antics.
2. Instal·la Nginx (paquet de Debian o repositori oficial)
Opció A: des dels repos de Debian (més estable)
apt install nginx
Opció B: des del repositori oficial de Nginx (més actual)
curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian/ $(lsb_release -cs) nginx" > /etc/apt/sources.list.d/nginx.list
apt update
apt install nginx
Després:
systemctl enable nginx
systemctl start nginx
3. Ajusta l’estructura de configuració
mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled
Y edita /etc/nginx/nginx.conf para incluir estos directorios:
include /etc/nginx/sites-enabled/*;
Després de cada canvi estructural, no oblidis verificar la configuració:
nginx -t && systemctl reload nginx
4. Crea el teu primer lloc virtual
Arxiu d’ exemple:
nano /etc/nginx/sites-available/exemple.com.conf
Contingut mínim funcional:
server {
listen 80;
server_name ejemplo.com www.exemple.com;
root /var/www/exemple.com/public;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Actíval:
ln -s /etc/nginx/sites-available/ejemplo.com.conf /etc/nginx/sites-enabled/
Crea el directori arrel i un index provisional:
mkdir -p /var/www/exemple.com/public
echo "<h1>Funciona</h1>" > /var/www/exemple.com/public/index.html
chown -R www-data:www-data /var/www/exemple.com
5. Obre els ports al firewall (si estàs fent servir ufw)
ufw allow 'Nginx Full'
O explícitamente:
ufw allow 80,443/tcp
6. Configura HTTPS amb Let’s Encrypt
Instal·la Certbot i el plugin per a Nginx:
apt install certbot python3-certbot-nginx
Executa:
certbot --nginx -d exemple.com -d www.exemple.com
Verifica la renovació:
certbot renew --dry-run
7. Recàrrega i prova
nginx -t && systemctl reload nginx
curl -I https://exemple.com
Comprova que:
- Es redirigeix HTTP → HTTPS
- El certificat és vàlid
- El contingut es carrega correctament
8. (Opcional però recomanable) Configura logs i capçaleres
Defineix un format de log en nginx.conf:
log_format main '$remote_addr - $host [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
I aplica headers mínims segurs:
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy strict-origin-when-cross-origin;
9. Verifica els logs i monitoritza errors
tail -f /var/log/nginx/access.log /var/log/nginx/error.log
O crea logs separats per domini per facilitar la depuració.
10. Automatitza la supervisió mínima
Afegeix un cron per verificar certificats setmanalment i un petit script de monitoratge amb curl o uptime-kuma si el servidor va a producció.
10. Reflexions finals
Nginx permet solucions ràpides, però també una gran modularitat. Cada arxiu de configuració que escrivim l’hem de pensar com una cosa que s’ha de llegir dintre de sis mesos, no com una cosa que “funciona avui”. Per això evitem configuracions auto-generades, comentem el necessari, i mantenim versions de recolzament de configuracions que canvien.
Un bon servidor Nginx a Debian no és el que arrenca sense errors, sinó el que pots mantenir sense ensurts, actualitzar sense por i entendre sense haver de fer enginyeria inversa sobre el que vas fer fa un any.
Si comences des de zero, cèntra’t primer a fer-ho llegible i reproduïble. El rendiment i la seguretat arriben després, però només si entens el que estàs fent.

