Exécution comme service
L’installateur laisse une unité systemd activée et démarrée. Cette page lit
cette unité ligne par ligne, montre comment la piloter, et décrit les deux formes
d’échec telles qu’on les voit de l’extérieur : un serveur qui ne démarre pas et
une configuration que le serveur en cours refuse.
🧾 Ce que fait l’unité
Section intitulée « 🧾 Ce que fait l’unité »systemctl cat pingclairLes clés qui comptent sont celles-ci :
[Service]Type=notifyNotifyAccess=mainUser=pingclairGroup=pingclairAmbientCapabilities=CAP_NET_BIND_SERVICECapabilityBoundingSet=CAP_NET_BIND_SERVICEEnvironment="RUST_LOG=info"ExecStart=/usr/local/bin/pingclair run /etc/Pingclair/PingclairfileExecReload=/bin/kill -USR1 $MAINPIDWorkingDirectory=/var/lib/pingclairRestart=on-failureRestartPreventExitStatus=1RestartSec=5sLimitNOFILE=1048576LimitNPROC=512ProtectSystem=fullPrivateTmp=trueNoNewPrivileges=trueLisez-les dans l’ordre :
Type=notifyetNotifyAccess=main: le serveur prévientsystemdquand ses écouteurs sont liés, doncsystemctl startbloque jusqu’à ce que le proxy puisse répondre, et non jusqu’à ce que le processus existe.User=pingclairavecAmbientCapabilities=CAP_NET_BIND_SERVICE: le serveur tourne sans privilèges et peut tout de même se lier aux ports 80 et 443.- Il n’y a délibérément aucun
PINGCLAIR_TLS_STOREici. Le répertoire personnel du compte de service est/var/lib/pingclair, donc les certificats vivent dans/var/lib/pingclair/.local/share/pingclair: la valeur par défaut du binaire, le répertoire que l’installateur crée et dans lequel il migre, et le chemin quepingclair environaffiche. Nommer un magasin ici serait une seconde réponse à une question qui en a déjà une. l’installateur crée, que la documentation désigne et que l’image de conteneur monte. - Il n’y a délibérément aucun
ExecStartPrequi lanceraitvalidate. Cela ressemble à l’endroit sûr pour ce contrôle, et c’est le piège :systemdappliqueRestartPreventExitStatus=au processus principal, pas à une pré-commande qui échoue, donc une configuration que le compilateur refuse était retentée toutes les cinq secondes au lieu de laisser l’unité en échec. Le serveur compile le fichier lui-même avant de lier quoi que ce soit et sort avec le code 1 quand il le refuse, ce qui est exactement le code pour lequel la politique de redémarrage ci-dessus a été écrite —pingclair runexiste pour être ce processus. ExecReloadenvoieSIGUSR1, le signal que le serveur traite comme « relis le fichier ».SIGHUPest ignoré délibérément, et une unité qui l’envoyait annonçait un succès pendant que l’ancienne configuration continuait de servir (issue #66). Commesystemdne peut observer que la sortie dekill, le serveur publie ce qu’il a fait du fichier sur la ligne d’état de l’unité —Serving (reloaded 1 listener(s) in 323.341µs), ouReload rejected: …— quesystemctl statusaffiche. La section sur le rechargement plus bas est la version longue.Restart=on-failureavecRestartPreventExitStatus=1etRestartSec=5s: le code de sortie 1 signifie que la configuration ou le magasin de certificats était inutilisable, donc l’unité restefailedpour qu’un opérateur regarde, au lieu d’être retentée toutes les cinq secondes. Toute autre défaillance est redémarrée.ProtectSystem=full,PrivateTmp,NoNewPrivileges,LimitNPROCetLimitNOFILE: le serveur obtient la vue du système de fichiers et les limites de processus dont il a besoin, et rien de plus.
Les deux chemins d’installation écrivent ce même fichier. La commande en une ligne
embarque une copie octet pour octet de scripts/pingclair.service — just repo-lint échoue si les deux divergent — donc une installation neuve par
curl | bash et une installation depuis un dépôt produisent la même unité, et
systemd-analyze verify /etc/systemd/system/pingclair.service ne dit rien de
cette unité, sur l’un comme sur l’autre chemin.
🎛️ Piloter le service
Section intitulée « 🎛️ Piloter le service »pc service enveloppe systemctl pour cette unité : les deux sont
interchangeables.
| Tâche | Avec pc |
Avec systemctl |
|---|---|---|
| Démarrer | sudo pc service start |
sudo systemctl start pingclair |
| Arrêter | sudo pc service stop |
sudo systemctl stop pingclair |
| Recharger la configuration | sudo pc service reload |
sudo systemctl reload pingclair |
| Redémarrer, après un changement d’écouteur ou de politique globale | sudo pc service restart |
sudo systemctl restart pingclair |
| État | pc service status |
systemctl status pingclair |
| Suivre le journal | — | journalctl -u pingclair -f |
pc service status affiche la vue de l’unité, y compris la ligne de disponibilité
envoyée par le serveur :
● pingclair.service - Pingclair High-Performance Web Server Loaded: loaded (/etc/systemd/system/pingclair.service; enabled; preset: enabled) Active: active (running) Docs: https://github.com/dorianverlaine/pingclair Main PID: 1808 (pingclair) Status: "Serving (reloaded 1 listener(s) in 323.341µs)"🔁 Ce que signifie un rechargement
Section intitulée « 🔁 Ce que signifie un rechargement »Une configuration modifiée dans /etc/Pingclair/Pingclairfile atteint le serveur
en cours d’exécution par un signal, et deux commandes l’envoient.
SIGUSR1 est le signal de rechargement, et il n’exige aucune configuration :
sudo kill -USR1 "$(systemctl show -p MainPID --value pingclair)"pc service reload — ou sudo systemctl reload pingclair, qui est le même appel
— envoie ce signal à votre place. L’ExecReload de l’unité est
/bin/kill -USR1 $MAINPID : la commande évidente est désormais celle qui
fonctionne. Une unité qui envoyait SIGHUP annonçait un succès et n’appliquait
rien, ce que l’issue #66
a enregistré.
pingclair reload atteint le même code par l’Admin API et rapporte ce que le
serveur a pensé du fichier, ce qui exige l’option admin du bloc des options
globales :
✅ Configuration reloaded successfullyError: ❌ Reload failed (400): HTTP/1.1 400 Bad Requestsystemctl reload ne peut rapporter qu’une chose : que kill a délivré le
signal. Le serveur lit le fichier ensuite, donc son verdict part sur la ligne
d’état de l’unité et dans le journal. pc service reload le dit, au lieu
d’affirmer que la configuration a été appliquée :
$ sudo pc service reload✅ Reload signal delivered to pingclair.serviceℹ️ The result lands a moment later: `systemctl status pingclair` or `journalctl -u pingclair -n 20`$ systemctl status pingclair --no-pager | grep Status Status: "Serving (reloaded 1 listener(s) in 323.341µs)"Quand le serveur en cours ne peut pas appliquer ce que le fichier demande,
l’ancienne configuration continue de servir et la ligne d’état dit quel
changement a été refusé. Déplacer le site de :80 vers :8080 est le cas
courant, parce que la topologie des écouteurs est reconstruite avec les sockets
au démarrage :
Status: "Reload rejected: listener topology changed (added: ["[::]:8080"], removed: ["[::]:80"]); restart Pingclair to rebuild H1, H2, H3, and TLS together"Quelle que soit la voie choisie, une configuration qui ne compile pas laisse la précédente en service. Validez d’abord :
sudo pingclair validate /etc/Pingclair/PingclairfileLa politique valable pour tout le processus fait exception. Les options établies
au démarrage, comme trusted_proxies, ne prennent effet qu’après un redémarrage :
sudo pc service restart. Une configuration qui ajoute ou déplace un écouteur est
refusée de la même façon — la ligne d’état nomme les adresses ajoutées et
retirées — parce que le rechargement applique la politique, pas un nouveau socket
d’écoute.
📜 Journaux
Section intitulée « 📜 Journaux »L’unité fixe RUST_LOG=info et envoie tout au journal :
sudo journalctl -u pingclair -fsudo journalctl -u pingclair --since '10 min ago'Le démarrage, les rechargements, le travail sur les certificats et une ligne d’accès par requête y apparaissent :
INFO pingclair::run: 🚀 Starting Pingclair v0.2.0-rc.3INFO pingclair::run: 📄 Loaded configuration from: /etc/Pingclair/PingclairfileINFO pingclair::run: 🔔 Received SIGUSR1, reloading configuration from: /etc/Pingclair/PingclairfileINFO pingclair::run: 📋 Step 1/3: Validating configuration...INFO pingclair::run: ✅ Configuration reload completed successfully in 323.341µsINFO pingclair::run: 📊 1 listener(s) updatedINFO pingclair_proxy::server: 📝 Access request_id="65c09fa25d457-6" method="GET" host="localhost" path="/" status=200 bytes=18747 duration_ms=0 remote_ip=::1 user_agent="curl/8.18.0"Un rechargement que le serveur refuse est journalisé de la même façon, avec la raison et la mention que rien n’a changé :
ERROR pingclair::run: ❌ Configuration reload rejected after 414.491µs: listener topology changed (added: ["[::]:8080"], removed: ["[::]:80"]); restart Pingclair to rebuild H1, H2, H3, and TLS together kind=RestartRequiredERROR pingclair::run: 💡 Previous configuration remains active, unchangedPour un journal à part, avec rotation, configurez une destination log et
écrivez-la sous /var/log/pingclair, que l’installateur crée et attribue à
l’utilisateur de service.
⚠️ Quand le service ne démarre pas
Section intitulée « ⚠️ Quand le service ne démarre pas »is-activeafficheactivatingetNRestartsne cesse d’augmenter. C’est le comportement retiré d’une unité plus ancienne, et il avait deux causes : elle portaitRestart=alwayssansRestartPreventExitStatus, et elle lançaitvalidatecomme commandeExecStartPre, ce queRestartPreventExitStatusne couvre pas — donc une configuration que le compilateur refuse était retentée toutes les cinq secondes et ressemblait à une unité qui ne se stabilise jamais plutôt qu’à une unité en échec. L’unité installée porteRestart=on-failure+RestartPreventExitStatus=1et aucune pré-commande, et un démarrage refusé laisseis-activeàfailedavecNRestartsà zéro. Sur une installation plus ancienne, arrêtez la boucle avant de déboguer :sudo systemctl stop pingclair, corrigez le fichier, puissudo systemctl reset-failed pingclair.Job for pingclair.service failed because the control process exited with error code. Le serveur a refusé la configuration avant de lier quoi que ce soit, et la raison du compilateur est dans le journal, par exempleError: ❌ Configuration Error: Compile error: Unsupported feature: `encode br`: Brotli is not implemented for proxied responses; use `encode zstd gzip`.TLS store /var/lib/pingclair/.local/share/pingclair is not writable: Permission denied. Le magasin appartient au compte de service. Vérifiezsudo ls -ld /var/lib/pingclair/.local/share/pingclair: il doit appartenir àpingclair.systemd-analyze verifysignaleMissing '=', ignoring linepour l’unité installée. Une installation en une ligne plus ancienne écrivait une unité dont les commentaires avaient été développés par le shell — 25 lignes de sortie de--help, quesystemdignore. Réinstaller avec l’installateur actuel écrit l’unité telle quelle et le signalement disparaît.- Rien ne répond alors que l’unité tourne. Les écouteurs sont liés et les requêtes n’arrivent pas. Vérifiez le pare-feu du fournisseur puis celui de l’hôte, comme sur la page d’installation.
🧭 Étapes suivantes
Section intitulée « 🧭 Étapes suivantes »- Mise à jour et désinstallation : ce qu’une réexécution conserve, et comment tout retirer.
- HTTPS : les certificats, où vit le magasin, et pourquoi
pingclair trusta besoin dePINGCLAIR_TLS_STORE. log: la destination de journal d’accès que cette page lit depuis le journal système.
