Comment utiliser systemd pour démarrer un service Linux au démarrage
S’assurer que les services critiques démarrent automatiquement lors du redémarrage de votre serveur est l’une des responsabilités les plus fondamentales de tout administrateur système Linux. Que vous exécutiez une application web, un moteur de base de données ou un daemon personnalisé sur un environnement VPS Hosting, un redémarrage inattendu ne devrait jamais signifier un temps d’arrêt prolongé. Avec systemd — le système init moderne qui alimente la majorité des distributions Linux actuelles — vous pouvez définir précisément comment, quand et en tant que qui vos services se lancent, tout cela via un fichier d’unité déclaratif et propre.
Ce guide complet vous guide à travers chaque étape : comprendre ce qu’est systemd, créer un fichier d’unité de service prêt pour la production, vérifier les permissions, tester votre exécutable et gérer le cycle de vie du service. À la fin, votre application personnalisée survivra à chaque redémarrage automatiquement.
Qu’est-ce que systemd et pourquoi est-ce important ?
systemd est un système init et un gestionnaire de services qui a remplacé les anciennes alternatives telles que SysVinit et Upstart sur la plupart des principales distributions Linux, notamment Ubuntu, Debian, CentOS, Rocky Linux, AlmaLinux et Fedora. Plutôt que d’exécuter une chaîne séquentielle de scripts shell au démarrage, systemd parallélise le démarrage des services, résout l’ordre des dépendances et gère l’ensemble du cycle de vie des processus système à partir d’une interface unique et unifiée.
Avantages clés de systemd pour les environnements serveur
| Fonctionnalité | Avantage |
|---|---|
| Démarrage parallèle des services | Temps de démarrage plus rapides sur les serveurs multi-services |
| Gestion des dépendances | Les services ne démarrent que lorsque leurs prérequis sont prêts |
| Politiques de redémarrage automatique | Les services défaillants se rétablissent sans intervention manuelle |
| Journalisation centralisée via journald | Toute la sortie du service est capturée dans un journal interrogeable |
| Contrôle des ressources basé sur cgroup | Les limites de CPU et de mémoire sont appliquées par service |
| Activation par socket et appareil | Les services démarrent à la demande, pas inconditionnellement |
Pour quiconque gère des applications sur des Serveurs Dédiés ou des instances VPS, ces capacités se traduisent directement par un temps d’activité plus élevé et un comportement plus prévisible sous charge.
Comprendre les fichiers d’unité systemd
Tout ce que systemd gère est représenté par un fichier d’unité — un fichier de configuration en texte brut divisé en sections. Un fichier d’unité .service indique à systemd :
- Quoi est le service (métadonnées, description, dépendances)
- Comment l’exécuter (chemin exécutable, répertoire de travail, contexte utilisateur)
- Quand le démarrer (cible de démarrage, ordre par rapport aux autres unités)
- Quoi faire s’il échoue (politique de redémarrage, délai de redémarrage)
Les fichiers d’unité de service pour les services à l’échelle du système se trouvent dans /etc/systemd/system/. Les fichiers placés ici ont la priorité sur les unités fournies par le fournisseur dans /lib/systemd/system/ et persistent lors des mises à niveau de paquets.
Étape par étape : Créer une unité de service systemd
La procédure suivante utilise une application fictive appelée myapp. Remplacez chaque instance de myapp, myuser et /usr/bin/myapp par des valeurs appropriées pour votre propre environnement.
Étape 1 : Préparer le répertoire de travail
Avant d’écrire le fichier d’unité, décidez d’où votre application s’exécutera. Un répertoire de travail dédié garde les fichiers de configuration, les journaux et les données d’exécution organisés et rend la gestion des permissions simple.
Créez le répertoire s’il n’existe pas déjà :
sudo mkdir -p /opt/myapp> Pourquoi /opt/ au lieu de /etc/systemd/ ?
> L’arborescence /etc/systemd/ est réservée à la propre configuration de systemd. Placer les données d’application là-bas n’est pas standard et peut causer de la confusion. Utilisez /opt/myapp, /srv/myapp ou /var/lib/myapp selon la catégorie de la Norme de hiérarchie du système de fichiers qui convient le mieux à votre charge de travail.
Attribuez la propriété à l’utilisateur qui exécutera le service :
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myuser
sudo chown -R myuser:myuser /opt/myappUtiliser un compte système dédié (pas de shell de connexion, pas de répertoire personnel) est une meilleure pratique de sécurité. Cela limite le rayon d’explosion si l’application est jamais compromise.
Vérifiez le résultat :
ls -ld /opt/myapp
# Expected output: drwxr-xr-x 2 myuser myuser 4096 Jan 1 00:00 /opt/myappÉtape 2 : Créer le fichier d’unité de service
Ouvrez un nouveau fichier d’unité avec votre éditeur préféré :
sudo nano /etc/systemd/system/myapp.serviceCollez le contenu suivant, en ajustant les valeurs pour correspondre à votre application :
[Unit]
Description=My Custom Application
Documentation=https://example.com/docs
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/myapp --config /opt/myapp/myapp.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
User=myuser
Group=myuser
WorkingDirectory=/opt/myapp
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.targetEnregistrez le fichier avec Ctrl+O, puis quittez avec Ctrl+X.
Étape 3 : Comprendre chaque directive
Section [Unit]
| Directive | Objectif |
|---|---|
Description | Nom lisible par l’homme affiché dans la sortie systemctl status |
Documentation | Référence URL ou page man pour le service |
After | Assure que le service démarre *après* que l’unité listée soit active |
Wants | Dépendance faible — systemd *essaiera* de démarrer l’unité listée mais n’échouera pas si elle n’est pas disponible |
> network-online.target vs network.target : Utilisez network-online.target (combiné avec Wants=network-online.target) pour les services qui ont vraiment besoin d’une interface réseau entièrement configurée — par exemple, une application qui se connecte à une base de données distante ou à une API externe au démarrage. network.target garantit seulement que le sous-système réseau a été *démarré*, pas que les interfaces sont actives et que les adresses sont assignées.
Section [Service]
| Directive | Objectif |
|---|---|
Type=simple | Le processus démarré par ExecStart est le processus principal (par défaut pour la plupart des applications) |
ExecStart | Chemin complet du binaire et tous les arguments. Utilisez toujours des chemins absolus. |
ExecReload | Commande pour recharger la configuration sans un redémarrage complet (optionnel mais recommandé) |
Restart=on-failure | Redémarrer le service uniquement lorsqu’il se termine avec un code non nul ou est tué par un signal. Utilisez always si vous voulez des redémarrages même en cas de sortie propre. |
RestartSec | Secondes à attendre avant de tenter un redémarrage |
User / Group | Exécuter le processus en tant que cet utilisateur/groupe au lieu de root |
WorkingDirectory | Définir le répertoire courant avant d’exécuter ExecStart |
StandardOutput / StandardError | Acheminer stdout/stderr vers le journal systemd |
SyslogIdentifier | Balise utilisée pour filtrer les entrées de journal pour ce service |
NoNewPrivileges | Empêche le processus d’obtenir des privilèges supplémentaires via les binaires setuid |
ProtectSystem=strict | Monte /usr, /boot et /etc en lecture seule pour le service |
ProtectHome | Rend /home, /root et /run/user inaccessibles |
PrivateTmp | Donne au service son propre espace de noms /tmp privé |
Section [Install]
| Directive | Objectif |
|---|---|
WantedBy=multi-user.target | Active le service lorsque le système atteint le niveau d’exécution multi-utilisateur standard (non graphique). C’est la cible correcte pour pratiquement tous les daemons serveur. |
Étape 4 : Vérifier les permissions des fichiers et répertoires
Avant de recharger systemd, confirmez que l’utilisateur du service peut réellement accéder à tout ce dont il a besoin :
# Check working directory ownership and permissions
ls -ld /opt/myapp
# Confirm the executable exists and is executable
ls -l /usr/bin/myapp
# Verify the config file is readable by myuser
sudo -u myuser cat /opt/myapp/myapp.confSi l’une de ces vérifications échoue, corrigez les permissions avant de continuer :
# Make the binary executable
sudo chmod +x /usr/bin/myapp
# Grant read access to the config file
sudo chmod 640 /opt/myapp/myapp.conf
sudo chown myuser:myuser /opt/myapp/myapp.confÉtape 5 : Tester l’exécutable manuellement
Vérifiez toujours que votre application s’exécute correctement *avant* de confier le contrôle à systemd. Cela isole les bogues d’application des problèmes de configuration systemd :
sudo -u myuser /usr/bin/myapp --config /opt/myapp/myapp.confSi l’application démarre sans erreurs, appuyez sur Ctrl+C pour l’arrêter et continuer. Si elle échoue, dépannez l’application elle-même — vérifiez que toutes les dépendances sont installées, que les variables d’environnement sont définies et que les ports requis sont disponibles.
Étape 6 : Recharger systemd et activer le service
Après avoir enregistré le fichier d’unité, demandez à systemd de relire sa configuration :
sudo systemctl daemon-reloadActivez le service pour qu’il démarre automatiquement à chaque redémarrage ultérieur :
sudo systemctl enable myapp.serviceCette commande crée un lien symbolique dans le répertoire .wants approprié, liant votre fichier d’unité dans la séquence de démarrage multi-user.target. Vous devriez voir une sortie similaire à :
Created symlink /etc/systemd/system/multi-user.target.wants/myapp.service → /etc/systemd/system/myapp.service.Démarrez le service immédiatement sans redémarrer :
sudo systemctl start myapp.serviceÉtape 7 : Vérifier que le service est en cours d’exécution
Vérifiez l’état actuel du service :
sudo systemctl status myapp.serviceUn service sain produit une sortie comme celle-ci :
● myapp.service - My Custom Application
Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2025-01-01 12:00:00 UTC; 5s ago
Main PID: 12345 (myapp)
Tasks: 4 (limit: 4915)
Memory: 12.3M
CPU: 45ms
CGroup: /system.slice/myapp.service
└─12345 /usr/bin/myapp --config /opt/myapp/myapp.confChamps clés à vérifier :
Loaded— confirme que le fichier d’unité a été analysé avec succès et indique s’il estenabledoudisabledpour le démarrageActive: active (running)— le service est actuellement en cours d’exécutionMain PID— l’ID de processus de votre application
Étape 8 : Surveiller les journaux avec journalctl
systemd achemine toute la sortie du service vers le journal, un magasin de journaux structuré et interrogeable. Utilisez journalctl pour l’inspecter :
# View all logs for myapp (most recent last)
journalctl -u myapp.service
# Follow live log output (like tail -f)
journalctl -u myapp.service -f
# Show only logs since the last boot
journalctl -u myapp.service -b
# Show the last 50 lines
journalctl -u myapp.service -n 50
# Show logs since a specific time
journalctl -u myapp.service --since "2025-01-01 12:00:00"Si votre service ne démarre pas, le journal contient presque toujours le message d’erreur exact expliquant pourquoi. C’est le premier endroit à regarder avant de faire des modifications.
Étape 9 : Tester le comportement au démarrage
Pour confirmer que le service survit à un redémarrage sans inspecter manuellement la séquence de démarrage, vous pouvez le simuler :
# Reboot the server (only if safe to do so)
sudo rebootAprès que le serveur soit revenu en ligne, vérifiez à nouveau l’état du service :
sudo systemctl status myapp.serviceS’il affiche active (running), votre service est correctement configuré pour le démarrage automatique.
Gérer le cycle de vie du service
Une fois que votre service est en cours d’exécution, vous utiliserez régulièrement les commandes suivantes :
Commandes systemctl courantes
# Start the service
sudo systemctl start myapp.service
# Stop the service gracefully
sudo systemctl stop myapp.service
# Restart the service (stop + start)
sudo systemctl restart myapp.service
# Reload configuration without restarting (if ExecReload is defined)
sudo systemctl reload myapp.service
# Enable automatic startup at boot
sudo systemctl enable myapp.service
# Disable automatic startup at boot
sudo systemctl disable myapp.service
# Check whether the service is enabled
sudo systemctl is-enabled myapp.service
# Check whether the service is currently active
sudo systemctl is-active myapp.service
# View the full unit file as systemd interprets it
sudo systemctl cat myapp.service
# Edit the unit file and reload in one step
sudo systemctl edit --full myapp.serviceDépannage des problèmes courants
Le service ne démarre pas : « Aucun fichier ou répertoire »
Cela signifie généralement que ExecStart pointe vers un binaire inexistant ou que WorkingDirectory n’existe pas. Vérifiez les deux chemins :
which myapp
ls -l /opt/myappLe service démarre mais se termine immédiatement
Vérifiez le journal pour la sortie d’erreur de l’application elle-même :
journalctl -u myapp.service -n 100 --no-pagerVérifiez également que Type=simple est correct pour votre application. Si votre binaire se divise lui-même en arrière-plan, utilisez Type=forking à la place.
Erreurs « Permission denied »
L’utilisateur du service n’a pas accès à un fichier ou répertoire requis. Utilisez ls -l pour auditer les permissions et sudo -u myuser pour tester l’accès de manière interactive.
Port déjà utilisé
Un autre processus est lié au port dont votre application a besoin. Identifiez-le avec :
sudo ss -tlnp | grep :<port>Le service redémarre en boucle
Si Restart=on-failure provoque des boucles de redémarrage rapides, systemd finira par limiter les redémarrages. Vérifiez StartLimitIntervalSec et StartLimitBurst dans la section [Unit] pour affiner ce comportement, et enquêtez toujours sur la cause première dans le journal.
Modèles systemd avancés pour les serveurs de production
Variables d’environnement et fichiers d’environnement
Ne codez jamais en dur les secrets dans les fichiers d’unité. Utilisez plutôt un fichier d’environnement :
[Service]
EnvironmentFile=/etc/myapp/myapp.env
ExecStart=/usr/bin/myappCréez /etc/myapp/myapp.env avec chmod 600 et chown root:myuser pour restreindre l’accès :
DATABASE_URL=postgresql://user:password@localhost/mydb
API_KEY=supersecretkeyDépendances de service et ordre
Si votre application dépend d’un service de base de données (par exemple, PostgreSQL ou MySQL), déclarez cette dépendance explicitement :
[Unit]
After=network-online.target postgresql.service
Requires=postgresql.serviceRequires est une dépendance stricte — si PostgreSQL ne démarre pas, systemd ne tentera pas non plus de démarrer votre service.
Intégration du watchdog
Pour les services critiques, activez le watchdog intégré de systemd pour détecter les processus bloqués :
[Service]
WatchdogSec=30s
Restart=on-watchdogVotre application doit appeler sd_notify(0, "WATCHDOG=1") périodiquement pour réinitialiser le minuteur du watchdog. S’il ne le fait pas dans WatchdogSec, systemd tue et redémarre le service.
Choisir le bon environnement d’hébergement
Les modèles de configuration systemd décrits dans ce guide s’appliquent également à tous les types de serveurs Linux, mais votre choix d’infrastructure d’hébergement affecte le contrôle que vous avez sur le système init et la gestion des services.
- VPS Hosting — Accès root complet, contrôle systemd complet, idéal pour les déploiements d’applications personnalisées. Les plans VPS d’AlexHost s’exécutent sur la virtualisation KVM, vous donnant un véritable environnement de noyau isolé.
- Serveurs Dédiés — Performance maximale et isolation pour les services gourmands en ressources. Accès matériel complet sans voisins bruyants.
on All Hosting Services
