From 9c3e33510dffbfcec6b2acddb710e33c2fb40055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zachary=20Gu=C3=A9not?= Date: Mon, 14 Sep 2026 01:22:15 +0200 Subject: [PATCH] chore(ops): give the unprivileged instance its own proxy unit Co-Authored-By: Claude Opus 5 --- ops/README.md | 2 +- ops/homarr-dev-proxy.nginx.conf | 48 +++++++++++++++++++++++++++++++++ ops/homarr-dev-proxy.service | 28 +++++++++++++++++++ ops/homarr-proxy.nginx.conf | 41 ---------------------------- 4 files changed, 77 insertions(+), 42 deletions(-) create mode 100644 ops/homarr-dev-proxy.nginx.conf create mode 100644 ops/homarr-dev-proxy.service delete mode 100644 ops/homarr-proxy.nginx.conf diff --git a/ops/README.md b/ops/README.md index e361d5f64..fcf018f2d 100644 --- a/ops/README.md +++ b/ops/README.md @@ -194,7 +194,7 @@ sudo cp /var/lib/homarr/trusted-certificates/*.pem /var/lib/homarr-dev/trusted-c sudo chown -R homarr:homarr /var/lib/homarr-dev ``` -Reste le proxy, qui ne peut pas tourner sous `homarr` : `ops/homarr-proxy.nginx.conf` +Reste le proxy, qui ne peut pas tourner sous `homarr` : `ops/homarr-dev-proxy.nginx.conf` est à déposer dans `/etc/nginx/sites-available/` et à activer. Il n'est pas optionnel — le client appelle `ws://:/websockets` sur la même origine que la page, alors que le serveur WebSocket écoute sur 3001. Sans lui, diff --git a/ops/homarr-dev-proxy.nginx.conf b/ops/homarr-dev-proxy.nginx.conf new file mode 100644 index 000000000..dd51d8853 --- /dev/null +++ b/ops/homarr-dev-proxy.nginx.conf @@ -0,0 +1,48 @@ +# Proxy inverse d'une instance Homarr lancée sous un utilisateur ordinaire. +# +# Configuration COMPLÈTE et autonome, destinée à `nginx -c`. Elle ne passe pas +# par /etc/nginx/nginx.conf : ce fichier-là est réécrit par le `run.sh` de +# l'instance de production à chaque démarrage, et n'inclut pas sites-enabled. +# Tout site déposé là disparaîtrait au premier redémarrage de la prod. +# +# Le proxy n'est pas un confort : le client se connecte à +# ws://:/websockets, sur la même origine que la page, alors que le +# serveur WebSocket écoute sur 3001. Sans ces deux emplacements, l'application +# se charge et perd ses mises à jour en direct, sans message d'erreur. + +user www-data; +worker_processes auto; +pid /run/nginx-homarr-dev.pid; + +events { + worker_connections 1024; +} + +http { + access_log /var/log/nginx/homarr-dev-access.log; + error_log /var/log/nginx/homarr-dev-error.log; + + server { + listen 80; + listen [::]:80; + + server_name _; + + location /websockets { + proxy_pass http://127.0.0.1:3001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $http_host; + } + + location / { + proxy_pass http://127.0.0.1:3000; + proxy_set_header Host $http_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 $http_x_forwarded_proto; + client_max_body_size 256M; + } + } +} diff --git a/ops/homarr-dev-proxy.service b/ops/homarr-dev-proxy.service new file mode 100644 index 000000000..4c86fadfa --- /dev/null +++ b/ops/homarr-dev-proxy.service @@ -0,0 +1,28 @@ +# Proxy de l'instance Homarr non privilégiée. +# +# Séparé du service applicatif parce qu'il lui faut root — écouter le port 80 et +# écrire dans /var/log/nginx — alors que l'application, elle, tourne sous +# `homarr`. C'est la découpe qui permet à l'application de n'avoir aucun droit +# particulier. +# +# À installer dans /etc/systemd/system/ : +# sudo install -m 644 ops/homarr-dev-proxy.service /etc/systemd/system/ +# sudo install -m 644 ops/homarr-dev-proxy.nginx.conf /etc/nginx/ +# sudo systemctl daemon-reload && sudo systemctl enable --now homarr-dev-proxy + +[Unit] +Description=Homarr Dev reverse proxy +After=network.target homarr-dev.service +# Lié au service applicatif : le proxy seul n'a aucun sens, et le laisser +# répondre alors que l'application est arrêtée ne servirait que des 502. +PartOf=homarr-dev.service + +[Service] +Type=exec +ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/homarr-dev-proxy.nginx.conf +ExecStart=/usr/sbin/nginx -c /etc/nginx/homarr-dev-proxy.nginx.conf -g 'daemon off;' +ExecReload=/usr/sbin/nginx -s reload +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/ops/homarr-proxy.nginx.conf b/ops/homarr-proxy.nginx.conf deleted file mode 100644 index ceb5d7ae2..000000000 --- a/ops/homarr-proxy.nginx.conf +++ /dev/null @@ -1,41 +0,0 @@ -# Proxy inverse pour une instance Homarr lancée sous un utilisateur ordinaire. -# -# À déposer dans /etc/nginx/sites-available/ et à lier dans sites-enabled/, puis -# `sudo systemctl reload nginx`. C'est le nginx du système qui le sert — celui de -# l'image est lancé par son run.sh, ce que l'utilisateur `homarr` ne peut pas -# faire. -# -# Les deux emplacements ne sont pas interchangeables : le serveur WebSocket est -# un processus distinct sur le port 3001, embarqué dans le serveur Next mais -# écoutant à part, et le client l'appelle sur la MÊME origine que la page. Sans -# la première règle, l'application se charge et les mises à jour en direct -# meurent silencieusement. -# -# Le port 80 est déjà pris par l'instance de production. Tant qu'elles -# alternent, ça va ; pour les faire cohabiter il faudrait aussi déplacer les -# ports applicatifs, or celui du WebSocket est écrit en dur dans le code (3001), -# donc deux instances ne peuvent pas tourner en même temps. - -server { - listen 8080; - listen [::]:8080; - - server_name _; - - location /websockets { - proxy_pass http://127.0.0.1:3001; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - proxy_set_header Host $http_host; - } - - location / { - proxy_pass http://127.0.0.1:3000; - proxy_set_header Host $http_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 $http_x_forwarded_proto; - client_max_body_size 256M; - } -}