Reverse proxy : plusieurs applications sur une seule adresse
Comment partager une seule adresse publique de VDS entre plusieurs applications par domaines et par chemins, transmettre correctement les en-têtes, et ne pas casser WebSocket.
Mis à jour le 23 août 2026
Une machine dispose d'une seule adresse IPv4 publique, mais exécute généralement plusieurs applications. Un reverse proxy accepte toutes les requêtes sur les ports 80 et 443 et les achemine vers les services internes selon le nom de domaine ou le chemin. Il détient aussi l'unique certificat et les journaux partagés.
Disposition
Chaque application écoute sur son propre port local et uniquement sur 127.0.0.1 :
- le site frontend —
127.0.0.1:3000; - l'API —
127.0.0.1:8000; - le tableau de bord de supervision —
127.0.0.1:9090.
Seul Nginx est exposé vers l'extérieur. Pour vérifier qu'une application n'est pas exposée directement :
ss -tulpn | grep LISTEN
Des lignes comme 0.0.0.0:3000 signifient que le service est joignable depuis internet, en contournant le proxy et sans chiffrement.
Par domaine
server {
listen 80;
server_name app.example.ru;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
server {
listen 80;
server_name api.example.ru;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Sans X-Forwarded-For, l'application voit chaque requête comme provenant de 127.0.0.1, et toute restriction basée sur l'IP cesse de fonctionner.
Par chemin
location /api/ {
proxy_pass http://127.0.0.1:8000/;
}
La barre oblique finale dans proxy_pass a ici son importance : avec elle, le préfixe /api est supprimé et l'application reçoit /users ; sans elle, elle reçoit /api/users. La moitié des « 404 mystérieux » sur un proxy viennent exactement de là.
WebSocket et réponses longues
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_read_timeout 3600s;
}
Sans la paire Upgrade/Connection, la connexion tombe juste après le handshake ; sans délai d'attente augmenté, elle tombe après une minute de silence.
Erreurs courantes
| Symptôme | Cause |
|---|---|
502 Bad Gateway | L'application n'est pas lancée ou écoute sur un autre port |
504 Gateway Time-out | L'application met plus de temps à répondre que proxy_read_timeout |
| Redirection infinie | L'application ne sait pas qu'HTTPS est utilisé — transmettez X-Forwarded-Proto |
| L'envoi de fichiers échoue | client_max_body_size est trop petit ; la valeur par défaut est 1 Mo |
| La même IP dans les journaux de l'application | X-Forwarded-For n'est pas transmis |
Ensuite : plusieurs sites, certificat, Caddy avec HTTPS automatique.
Un seul certificat sur le proxy couvre toutes les applications derrière lui. Les connexions internes via
127.0.0.1n'ont pas besoin de chiffrement — elles ne quittent jamais la machine.