Configurer Nginx comme Reverse Proxy avec SSL
Configurez Nginx comme reverse proxy avec des certificats SSL gratuits de Let's Encrypt. Routez plusieurs domaines vers différents services sur un seul VPS.
Configurer Nginx comme Reverse Proxy avec SSL
Vous exécutez plusieurs applications sur un seul VPS ? Nginx en tant que reverse proxy vous permet de diriger le trafic vers différents services, de gérer automatiquement les certificats SSL et d’améliorer les performances — le tout sur un seul serveur. Si vous préférez une approche native Docker, consultez plutôt notre guide Traefik.
Pourquoi c’est important
Sans reverse proxy, vous auriez besoin de :
- Une adresse IP publique distincte pour chaque application
- Une gestion manuelle des certificats SSL par service
- Chaque application gérant ses propres en-têtes de sécurité
- Aucune journalisation centralisée ni limitation de débit
Un reverse proxy résout tous ces problèmes. Un seul point d’entrée, plusieurs backends, HTTPS automatique.
Avantages concrets :
- Exécuter plus de 10 applications sur un VPS avec une seule IP
- SSL automatique et gratuit via Let’s Encrypt
- Un endroit centralisé pour les en-têtes de sécurité
- Répartition de charge lorsque vous passez à l’échelle
- Support WebSocket pour les applications en temps réel
Prérequis
- Un VPS avec Ubuntu 22.04+ (nous recommandons Hostinger VPS pour leurs performances et leur gestion DNS simple)
- Un nom de domaine pointant vers votre serveur
- Accès root ou sudo
- Des applications fonctionnant sur des ports localhost
Étape 1 : Installer Nginx
# Update packages
sudo apt update
# Install Nginx
sudo apt install nginx -y
# Start and enable
sudo systemctl start nginx
sudo systemctl enable nginx
# Verify it's running
sudo systemctl status nginx
Ouvrez l’adresse IP de votre serveur dans un navigateur — vous devriez voir la page d’accueil de Nginx.
Étape 2 : Comprendre la structure des répertoires
/etc/nginx/
├── nginx.conf # Main config (rarely edit)
├── sites-available/ # All site configs
├── sites-enabled/ # Symlinks to active configs
├── snippets/ # Reusable config snippets
└── conf.d/ # Additional configs
Étape 3 : Configurer votre premier Reverse Proxy
Supposons que vous ayez une application Node.js fonctionnant sur le port 3000. Créez une configuration :
sudo nano /etc/nginx/sites-available/myapp.example.com
Ajoutez :
server {
listen 80;
listen [::]:80;
server_name myapp.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
Activez le site :
# Create symlink
sudo ln -s /etc/nginx/sites-available/myapp.example.com /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
Étape 4 : Installer Certbot pour le SSL gratuit
# Install Certbot and Nginx plugin
sudo apt install certbot python3-certbot-nginx -y
Étape 5 : Obtenir votre certificat SSL
sudo certbot --nginx -d myapp.example.com
Certbot va :
- Vérifier que vous êtes propriétaire du domaine
- Générer les certificats
- Configurer automatiquement Nginx pour HTTPS
- Mettre en place le renouvellement automatique
Votre configuration est maintenant automatiquement mise à jour avec les paramètres SSL.
Étape 6 : Vérifier le renouvellement automatique
# Test renewal process
sudo certbot renew --dry-run
# Check the timer
sudo systemctl status certbot.timer
Les certificats se renouvellent automatiquement avant expiration. Aucune intervention manuelle nécessaire.
Étape 7 : Ajouter plusieurs applications
Pour chaque nouvelle application, créez un fichier de configuration :
Backend API (port 4000) :
sudo nano /etc/nginx/sites-available/api.example.com
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:4000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Site web statique (répertoire différent) :
server {
listen 80;
server_name static.example.com;
root /var/www/static.example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Activez et obtenez le SSL :
sudo ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d api.example.com
Étape 8 : Ajouter des en-têtes de sécurité
Créez un snippet réutilisable :
sudo nano /etc/nginx/snippets/security-headers.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
Incluez-le dans vos blocs server :
server {
# ... other config ...
include snippets/security-headers.conf;
location / {
# ... proxy settings ...
}
}
Étape 9 : Configurer le support WebSocket
Pour les applications utilisant les WebSockets (chat, fonctionnalités en temps réel) :
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 86400; # 24 hours for long connections
}
Étape 10 : Mettre en place la limitation de débit
Protégez-vous contre les abus dans votre fichier nginx.conf principal :
sudo nano /etc/nginx/nginx.conf
Ajoutez dans le bloc http :
http {
# Define rate limit zones
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
# ... rest of config ...
}
Appliquez dans les blocs server :
location / {
limit_req zone=general burst=20 nodelay;
proxy_pass http://127.0.0.1:3000;
# ...
}
location /api/ {
limit_req zone=api burst=50 nodelay;
proxy_pass http://127.0.0.1:4000;
# ...
}
Étape 11 : Activer la compression Gzip
sudo nano /etc/nginx/conf.d/gzip.conf
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml
application/xml+rss
application/x-javascript
image/svg+xml;
Étape 12 : Configurer la répartition de charge basique
Pour plusieurs serveurs backend :
upstream myapp_backends {
least_conn; # Send to least busy server
server 127.0.0.1:3000 weight=3;
server 127.0.0.1:3001 weight=2;
server 127.0.0.1:3002 backup; # Only if others fail
}
server {
listen 80;
server_name myapp.example.com;
location / {
proxy_pass http://myapp_backends;
proxy_http_version 1.1;
proxy_set_header Host $host;
# ... other headers ...
}
}
Exemple complet de configuration pour la production
Voici une configuration complète prête pour la production :
upstream app_backend {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 80;
listen [::]:80;
server_name myapp.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name myapp.example.com;
# SSL (managed by Certbot, but you can customize)
ssl_certificate /etc/letsencrypt/live/myapp.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.example.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
# Security headers
include snippets/security-headers.conf;
# Logging
access_log /var/log/nginx/myapp.access.log;
error_log /var/log/nginx/myapp.error.log;
# Rate limiting
limit_req zone=general burst=20 nodelay;
# Proxy settings
location / {
proxy_pass http://app_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Static files (if served by Nginx)
location /static/ {
alias /var/www/myapp/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
Bonnes pratiques
- Un fichier de configuration par domaine - Plus facile à gérer et déboguer (également important pour la sécurité VPS)
- Toujours tester avant de recharger -
nginx -tdétecte les erreurs de syntaxe - Utilisez des includes pour les paramètres communs - Le principe DRY s’applique aussi aux configurations
- Définissez des délais d’attente appropriés - Ne laissez pas les clients lents monopoliser les connexions
- Activez HTTP/2 - Gain de performance gratuit pour HTTPS
- Journalisez séparément par application - Débogage et analyse plus faciles
- Utilisez les blocs upstream - Même pour un seul serveur, cela facilite la mise à l’échelle
- Maintenez la configuration SSL à jour - Les bonnes pratiques de sécurité évoluent
Erreurs courantes à éviter
❌ Oublier de tester la configuration - Une seule faute de frappe casse tous les sites
❌ Ne pas activer les sites - Créer une configuration sans lien symbolique ne fait rien
❌ Mauvais slash final dans proxy_pass - /api vs /api/ se comportent différemment
❌ En-têtes WebSocket manquants - Les fonctionnalités en temps réel échouent silencieusement
❌ Ignorer le keepalive upstream - Crée des connexions inutiles
❌ Incompatibilité de certificat SSL - Le certificat doit correspondre exactement au server_name
❌ Pas de limitation de débit - Votre serveur devient une cible pour les attaques DoS
❌ Servir les fichiers statiques via l’application - Laissez Nginx gérer directement le contenu statique
Conseils de débogage
# Check Nginx error log
sudo tail -f /var/log/nginx/error.log
# Check specific site log
sudo tail -f /var/log/nginx/myapp.error.log
# Test configuration
sudo nginx -t
# Check if port is listening
sudo ss -tlnp | grep nginx
# View active connections
sudo nginx -T | grep server_name
FAQ
Combien de sites un seul serveur Nginx peut-il gérer ?
Nginx est incroyablement efficace. Un modeste Hostinger VPS peut facilement gérer plus de 50 sites à faible trafic ou plusieurs sites à fort trafic. La mémoire est généralement le facteur limitant.
Dois-je utiliser Apache ou Nginx ?
Nginx pour le reverse proxy, presque toujours. Il gère mieux les connexions simultanées et utilise moins de mémoire. Apache convient pour l’hébergement PHP traditionnel avec mod_php. Pour une configuration encore plus simple, envisagez un PaaS auto-hébergé comme Coolify ou Dokploy.
Quelle est la différence entre sites-available et sites-enabled ?
sites-available stocke toutes les configurations. sites-enabled contient des liens symboliques vers les configurations actives. Cela vous permet de désactiver un site sans supprimer sa configuration.
Comment gérer www vs non-www ?
Ajoutez les deux au server_name et redirigez l’un vers l’autre :
server {
listen 80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
Pourquoi mon certificat SSL ne fonctionne-t-il pas ?
Causes courantes : le DNS ne pointe pas vers le serveur, les ports 80/443 sont bloqués par le pare-feu, mauvais server_name, ou Certbot n’a pas pu vérifier la propriété. Vérifiez avec sudo certbot certificates pour connaître le statut.
Puis-je utiliser Nginx avec Docker ?
Absolument ! Vous pouvez soit exécuter Nginx dans un conteneur, soit l’installer sur l’hôte pour proxyfier vers des conteneurs Docker. Consultez notre guide Docker Compose pour plus de détails.
Prochaines étapes : Mettez en place la surveillance pour suivre les performances de votre Nginx et détecter les problèmes avant qu’ils ne deviennent critiques.
Ready to get started?
Get the best VPS hosting deal today. Hostinger offers 4GB RAM VPS starting at just $4.99/mo.
Get Hostinger VPS — $4.99/mo// up to 75% off + free domain included
// related topics
// related guides
$1 VPS Hosting 2026: Cheapest VPS Servers Starting at $1/Month
Looking for $1 VPS hosting? Compare the cheapest VPS providers starting from $1-3/month. Real specs, no hidden fees, honest reviews of budget VPS options.
tutorialCaddy Reverse Proxy Guide 2026: Automatic HTTPS Made Easy
Set up Caddy as a reverse proxy with automatic HTTPS, zero-config SSL, and simple Caddyfile syntax. Complete VPS deployment guide.
tutorialCloudflare Tunnel VPS Guide 2026: Expose Services Without Opening Ports
Set up Cloudflare Tunnel on your VPS to expose web apps securely without opening ports or revealing your server IP. Complete guide with Docker and DNS config.
tutorialCoolify VPS Setup Guide 2026: Self-Hosted Vercel Alternative
Deploy Coolify on your VPS for a self-hosted Vercel/Netlify experience. Complete setup guide with Docker, SSL, and app deployments.
Andrius Putna
I am Andrius Putna. Geek. Since early 2000 in love tinkering with web technologies. Now AI. Bridging business and technology to drive meaningful impact. Combining expertise in customer experience, technology, and business strategy to deliver valuable insights. Father, open-source contributor, investor, 2xIronman, MBA graduate.
// last updated: February 6, 2026. Disclosure: This article may contain affiliate links.