Comment activer le chargement automatique de scripts dans Ubuntu : trois méthodes prêtes pour la production
Activer le chargement automatique de scripts dans Ubuntu signifie configurer le système d’exploitation pour exécuter automatiquement un ou plusieurs scripts shell ou services au démarrage du système, sans aucune intervention manuelle. Cela est réalisé grâce à trois mécanismes principaux : le répertoire /etc/init.d/ basé sur le SysVinit hérité, le shim de compatibilité /etc/rc.local, et le framework moderne d’unités de service systemd — ce dernier étant l’approche faisant autorité et recommandée sur toutes les versions d’Ubuntu à partir de la 15.04.
Pour les administrateurs système exécutant des charges de travail dans un environnement VPS Hosting, l’automatisation du démarrage n’est pas une commodité — c’est une exigence de fiabilité. Une entrée de démarrage automatique mal configurée ou absente signifie que les démons critiques, les agents de surveillance, les scripts de sauvegarde ou les configurations réseau personnalisées échouent silencieusement à se lancer après un redémarrage, provoquant des interruptions de service difficiles à diagnostiquer après coup.
Pourquoi l’automatisation des scripts de démarrage est importante sur les serveurs Ubuntu
Chaque serveur Ubuntu en production accumule des scripts opérationnels au fil du temps : routines de préchauffage de base de données, déclencheurs de rotation des journaux, initialiseurs de tunnel VPN, chargeurs de règles de pare-feu et vérifications de l’état des applications. Sans mécanisme de chargement automatique structuré, ces scripts dépendent entièrement d’une exécution manuelle — une seule étape manquée après une mise à jour du noyau ou un redémarrage d’urgence peut se transformer en temps d’arrêt.
L’écosystème d’automatisation du démarrage d’Ubuntu a considérablement évolué :
- SysVinit (avant Ubuntu 15.04) : Séquentiel, lent, basé sur des scripts. Chaque service bloquait le suivant.
- Upstart (Ubuntu 6.10–15.04) : Piloté par événements, plus rapide, mais désormais obsolète.
- systemd (Ubuntu 15.04+) : Activation parallèle des services, graphes de dépendances, activation par socket, contrôle des ressources basé sur les cgroups et journalisation structurée via
journald.
Comprendre avec quelle couche vous travaillez — et pourquoi — vous évite de déployer une solution fonctionnelle dans un environnement de test qui échoue silencieusement en production.
Méthode 1 : Utilisation du répertoire /etc/init.d/ (SysVinit / Scripts LSB)
Comment ça fonctionne
Le répertoire /etc/init.d/ est le répertoire traditionnel pour les scripts d’initialisation Linux Standard Base (LSB). Chaque script dans ce répertoire est un script shell qui répond à des commandes standardisées : start, stop, restart, status, et optionnellement reload. L’utilitaire update-rc.d crée des liens symboliques dans les répertoires de niveaux d’exécution /etc/rcN.d/, déterminant quand et dans quel ordre le script s’exécute pendant les séquences de démarrage et d’arrêt.
Sur les systèmes Ubuntu modernes exécutant systemd, ces scripts sont toujours pris en charge via une couche de compatibilité appelée systemd-sysv-generator, qui convertit automatiquement les scripts d’initialisation LSB en unités systemd transitoires. Cela signifie que vos scripts /etc/init.d/ s’exécuteront toujours, mais ils sont encapsulés par systemd plutôt qu’exécutés directement par SysVinit.
Mise en œuvre étape par étape
Étape 1 : Créez votre script
Rédigez votre script et assurez-vous qu’il suit la convention d’en-tête LSB. Un exemple minimal adapté à la production :
#!/bin/bash
### BEGIN INIT INFO
# Provides: examplescript
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Example autoload script
# Description: Runs a custom initialization task at boot
### END INIT INFO
case "$1" in
start)
echo "Starting examplescript..."
/usr/local/bin/examplescript.sh &
;;
stop)
echo "Stopping examplescript..."
pkill -f examplescript.sh
;;
restart)
$0 stop
$0 start
;;
status)
pgrep -f examplescript.sh > /dev/null && echo "Running" || echo "Stopped"
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0Étape 2 : Placez le script dans /etc/init.d/
sudo cp examplescript /etc/init.d/examplescriptÉtape 3 : Rendez-le exécutable
sudo chmod +x /etc/init.d/examplescriptÉtape 4 : Enregistrez-le dans le système de niveaux d’exécution
sudo update-rc.d examplescript defaultsL’argument defaults enregistre le script pour démarrer aux niveaux d’exécution 2, 3, 4 et 5, et s’arrêter aux niveaux d’exécution 0, 1 et 6 — le comportement standard pour la plupart des démons serveur.
Étape 5 : Vérifiez l’enregistrement
ls -la /etc/rc2.d/ | grep examplescriptVous devriez voir un lien symbolique comme S01examplescript pointant vers /etc/init.d/examplescript.
Piège critique
L’erreur la plus courante avec cette méthode est d’omettre le bloc d’en-tête LSB. Sans lui, update-rc.d ne peut pas déterminer l’ordre des dépendances, et systemd-sysv-generator peut attribuer un ordre d’exécution incorrect par rapport à la disponibilité du réseau ou aux montages du système de fichiers. Définissez toujours les dépendances Required-Start explicitement.
Pour supprimer le script du démarrage automatique sans le supprimer :
sudo update-rc.d examplescript disablePour le supprimer complètement :
sudo update-rc.d examplescript removeMéthode 2 : Utilisation de /etc/rc.local (Shim de compatibilité)
Comment ça fonctionne
/etc/rc.local est un mécanisme hérité qui exécute un script shell une seule fois, après que tous les services standard du niveau d’exécution multi-utilisateur ont démarré. C’est la méthode de démarrage automatique la plus simple possible — pas de gestion de service, pas de déclarations de dépendances, pas de logique de redémarrage. Sur Ubuntu 18.04 et versions ultérieures, la prise en charge de rc.local est fournie par l’unité systemd rc-local.service, qui est désactivée par défaut et doit être explicitement activée.
Quand l’utiliser
Utilisez /etc/rc.local uniquement pour :
- Les commandes d’initialisation ponctuelles qui n’ont pas besoin d’être gérées comme des services
- Le prototypage rapide ou les tests avant de formaliser une unité systemd
- Les exportations simples de variables d’environnement ou les ajustements de paramètres du noyau
N’utilisez pas /etc/rc.local pour les démons à longue durée d’exécution. Parce qu’il s’exécute de manière bloquante et séquentielle sans supervision des processus, une commande bloquée dans rc.local retardera ou empêchera la fin de la séquence de démarrage.
Mise en œuvre étape par étape
Étape 1 : Vérifiez si /etc/rc.local existe
ls -la /etc/rc.localS’il n’existe pas, créez-le :
sudo bash -c 'cat > /etc/rc.local << EOF
#!/bin/bash
exit 0
EOF'
sudo chmod +x /etc/rc.localÉtape 2 : Activez l’unité systemd rc-local (Ubuntu 18.04+)
sudo systemctl enable rc-local
sudo systemctl start rc-localÉtape 3 : Ajoutez votre commande avant exit 0
sudo nano /etc/rc.localInsérez votre commande au-dessus de la ligne exit 0 :
#!/bin/bash
/usr/local/bin/examplescript.sh >> /var/log/examplescript.log 2>&1 &
exit 0Le & à la fin est essentiel pour toute commande à longue durée d’exécution — il fait passer le processus en arrière-plan afin que rc.local ne soit pas bloqué.
Étape 4 : Vérifiez l’exécution
sudo systemctl status rc-localPiège critique
Sur Ubuntu 20.04 et 22.04, rc-local.service a un délai d’expiration codé en dur de 30 secondes. Si votre script prend plus de 30 secondes à se terminer, systemd marquera le service comme échoué et les commandes suivantes dans rc.local ne s’exécuteront pas. Redirigez la sortie et mettez explicitement en arrière-plan les processus à longue durée d’exécution.
Méthode 3 : Utilisation des unités de service systemd (Recommandée)
Pourquoi systemd est la bonne approche pour la production
systemd n’est pas simplement un remplacement de SysVinit — c’est un gestionnaire de système et de session complet qui fournit la résolution des dépendances, le démarrage parallèle, l’activation par socket et D-Bus, la création de services à la demande, la supervision des processus avec redémarrage automatique, l’isolation des ressources basée sur les cgroups et l’agrégation structurée des journaux via journald. Pour toute charge de travail s’exécutant sur un Serveur Dédié ou un VPS en production, les unités systemd sont le seul mécanisme approprié pour gérer les scripts chargés automatiquement.
Anatomie d’un fichier d’unité systemd
Un fichier d’unité .service est divisé en trois sections obligatoires :
[Unit]: Métadonnées, description lisible par l’homme et déclarations de dépendances (After=,Requires=,Wants=).[Service]: Paramètres d’exécution — le binaire ou script à exécuter, le type de service, la politique de redémarrage, les variables d’environnement et les options de sandboxing de sécurité.[Install]: Définit quelle cible systemd active cette unité (WantedBy=multi-user.targetest le standard pour les démons serveur).
Mise en œuvre étape par étape
Étape 1 : Préparez votre script
Assurez-vous que votre script est exécutable et situé dans un chemin stable :
sudo cp examplescript.sh /usr/local/bin/examplescript.sh
sudo chmod +x /usr/local/bin/examplescript.shÉtape 2 : Créez le fichier d’unité
sudo nano /etc/systemd/system/examplescript.serviceUn fichier d’unité de qualité production avec durcissement de sécurité :
[Unit]
Description=Example Autoload Script
Documentation=https://your-internal-wiki/examplescript
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/examplescript.sh
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
SyslogIdentifier=examplescript
User=nobody
Group=nogroup
NoNewPrivileges=true
ProtectSystem=strict
PrivateTmp=true
[Install]
WantedBy=multi-user.targetÉtape 3 : Rechargez le démon systemd
Après avoir créé ou modifié un fichier d’unité, vous devez recharger l’index de configuration du démon :
sudo systemctl daemon-reloadÉtape 4 : Activez le service pour le démarrage automatique
sudo systemctl enable examplescript.serviceCela crée un lien symbolique dans /etc/systemd/system/multi-user.target.wants/ pointant vers votre fichier d’unité.
Étape 5 : Démarrez le service immédiatement
sudo systemctl start examplescript.serviceÉtape 6 : Vérifiez l’état et les journaux
sudo systemctl status examplescript.service
sudo journalctl -u examplescript.service -fComprendre les types de services systemd
La directive Type= dans la section [Service] est l’un des paramètres les plus mal compris. Choisir le mauvais type amène systemd à mal rapporter la disponibilité du service, entraînant des échecs de dépendances.
| Type | Comportement | Cas d’utilisation |
|---|---|---|
simple | Le processus démarré par ExecStart est le processus principal. Systemd le considère prêt immédiatement. | Scripts et démons simples qui ne se dupliquent pas |
forking | Le processus se duplique et le parent se termine. Systemd suit l’enfant via le fichier PID. | Démons Unix traditionnels (ex. Apache avec PidFile) |
oneshot | Le processus s’exécute jusqu’à la fin et se termine. Systemd attend avant de démarrer les unités dépendantes. | Tâches d’initialisation ponctuelles, scripts de configuration |
notify | Le processus signale sa disponibilité via sd_notify(). | Démons avec intégration systemd native |
idle | L’exécution est retardée jusqu’à ce que tous les travaux actifs soient distribués. | Tâches en arrière-plan de faible priorité |
Pour un script qui s’exécute une seule fois au démarrage et se termine, utilisez Type=oneshot avec RemainAfterExit=yes pour maintenir l’unité dans un état « actif » après la fin du script.
Avancé : Ordonnancement des dépendances avec After= et Wants=
Un échec courant en production se produit lorsqu’un script nécessitant une connectivité réseau démarre avant que la pile réseau soit entièrement initialisée. La chaîne de dépendances correcte pour les scripts dépendants du réseau est :
After=network-online.target
Wants=network-online.targetCela est distinct de After=network.target, qui garantit uniquement que les interfaces réseau ont été configurées — pas qu’elles sont réellement en ligne et accessibles. La dépendance network-online.target nécessite que systemd-networkd-wait-online.service ou équivalent confirme la connectivité.
Comparaison : Les trois méthodes en un coup d’œil
| Fonctionnalité | /etc/init.d/ | /etc/rc.local | Unité systemd |
|---|---|---|---|
| Recommandé pour la production | Non | Non | Oui |
| Prise en charge du démarrage parallèle | Non | Non | Oui |
| Supervision des processus / redémarrage automatique | Non | Non | Oui |
| Gestion des dépendances | Limitée (en-têtes LSB) | Aucune | Complète |
| Journalisation structurée | Non | Non | Oui (journald) |
| Sandboxing de sécurité | Non | Non | Oui |
| Complexité | Faible | Très faible | Moyenne |
| Pris en charge sur Ubuntu 22.04+ | Via couche de compatibilité | Via rc-local.service | Nativement |
| Adapté aux démons à longue durée d’exécution | Partiellement | Non | Oui |
| Adapté aux tâches d’initialisation ponctuelles | Oui | Oui | Oui (oneshot) |
Erreurs courantes et comment les éviter
Exécuter des scripts en tant que root inutilement. Les directives User= et Group= dans les fichiers d’unité systemd vous permettent de réduire les privilèges. Un script qui n’a besoin que d’écrire dans /var/log/myapp/ n’a pas besoin de root — créez un utilisateur système dédié et attribuez la propriété du répertoire en conséquence.
Ne pas rediriger la sortie dans rc.local. Sans redirection de sortie, toute sortie echo ou sortie d’erreur des commandes rc.local va vers la console système et est perdue. Ajoutez toujours >> /var/log/yourscript.log 2>&1.
Utiliser des chemins absolus de manière incohérente. Les services systemd s’exécutent dans un environnement minimal sans le PATH de l’utilisateur. Utilisez toujours des chemins absolus pour chaque binaire référencé dans ExecStart, y compris les interpréteurs comme /usr/bin/python3 ou /bin/bash.
Oublier daemon-reload après avoir modifié les fichiers d’unité. systemd met en cache le contenu des fichiers d’unité. Si vous modifiez un fichier .service et n’exécutez pas sudo systemctl daemon-reload, systemd continuera à utiliser l’ancienne configuration.
Placer les fichiers d’unité dans /lib/systemd/system/ pour les scripts personnalisés. Le répertoire /lib/systemd/system/ est géré par le gestionnaire de paquets. Les fichiers d’unité personnalisés appartiennent à /etc/systemd/system/, qui a la priorité et survit aux mises à jour des paquets.
Matrice de décision pratique : Quelle méthode utiliser
Utilisez ce cadre pour sélectionner la méthode appropriée à votre scénario spécifique :
- Démon à longue durée d’exécution qui doit redémarrer en cas d’échec — Unité systemd avec
Restart=on-failure - Script de configuration ponctuel qui doit se terminer avant le démarrage des autres services — Unité systemd avec
Type=oneshotet dépendancesBefore= - Script nécessitant que le réseau soit entièrement en ligne — Unité systemd avec
After=network-online.target - Commande rapide pour les tests ou le prototypage —
/etc/rc.local(temporairement) - Application héritée fournie avec un script d’initialisation LSB —
/etc/init.d/avecupdate-rc.d - Tout ce qui s’exécute en production — systemd, toujours
Pour les administrateurs gérant plusieurs serveurs Ubuntu, envisagez de combiner la gestion des unités systemd avec des outils de gestion de configuration tels qu’Ansible, qui peut déployer et activer des fichiers .service de manière idempotente sur l’ensemble de votre parc. Si vous avez besoin d’un environnement géré avec un accès root complet pour implémenter ces configurations, le VPS Hosting avec un Panneau de contrôle VPS offre la flexibilité nécessaire pour gérer les services systemd directement sans restrictions.
Pour les équipes exécutant des charges de travail gourmandes en ressources nécessitant des scripts de démarrage pour initialiser les pilotes GPU, les environnements CUDA ou les serveurs d’inférence ML, les environnements GPU Hosting bénéficient particulièrement des chaînes de dépendances After= de systemd, garantissant que les pilotes sont entièrement chargés avant que les services applicatifs tentent de se lier aux ressources matérielles.
Si vos scripts chargés automatiquement interagissent avec des configurations de serveur web ou des routines d’initialisation de base de données liées à un environnement de panneau de contrôle, les installations VPS avec cPanel nécessitent une attention particulière — cPanel gère sa propre couche de supervision des services, et les unités systemd personnalisées doivent être définies pour éviter les conflits avec les hooks de gestion des services de cPanel.
Liste de contrôle des points techniques essentiels
Avant de déployer un script de démarrage sur un serveur Ubuntu, vérifiez les points suivants :
- Emplacement du fichier d’unité : Les scripts personnalisés vont dans
/etc/systemd/system/, pas dans/lib/systemd/system/ - Bit exécutable : Confirmez avec
ls -la /path/to/script.sh— le bitxdoit être défini - Chemins absolus : Chaque binaire dans
ExecStartutilise un chemin complet ; aucune dépendance à$PATH - Déclarations de dépendances :
After=network-online.targetpour tout script dépendant du réseau - Type de service :
Type=simplepour les démons persistants,Type=oneshotpour les scripts d’exécution et de sortie - Minimisation des privilèges :
User=,Group=,NoNewPrivileges=true,ProtectSystem=strict - Journalisation configurée :
StandardOutput=journaletStandardError=journalpour l’intégrationjournald - daemon-reload exécuté : Exécutez toujours
sudo systemctl daemon-reloadaprès avoir créé ou modifié des fichiers d’unité - Enable vs. start :
enablecrée le lien symbolique de démarrage automatique ;startl’exécute immédiatement — les deux sont nécessaires - Testé avec
journalctl: Confirmez l’exécution réussie avecsudo journalctl -u yourservice.service --since "5 minutes ago"
FAQ
Quelle est la différence entre systemctl enable et systemctl start ?
systemctl enable crée un lien symbolique qui fait démarrer le service automatiquement au prochain démarrage. systemctl start démarre le service immédiatement dans la session en cours. Vous avez généralement besoin des deux commandes lors de la configuration d’un nouveau service pour la première fois.
Pourquoi mon service systemd échoue-t-il avec « executable not found » même si le script existe ?
Cela signifie presque toujours que le chemin ExecStart est incorrect ou que le script n’a pas le bit exécutable. Vérifiez avec which yourscript et ls -la /path/to/script. Confirmez également que la première ligne de votre script est un shebang valide (#!/bin/bash ou #!/usr/bin/env python3), car systemd n’invoque pas un shell par défaut pour ExecStart.
Puis-je exécuter un script au démarrage une seule fois, pas à chaque démarrage ?
Utilisez Type=oneshot avec une directive ConditionPathExists=!/var/run/myscript.done dans la section [Unit]. Le script crée le fichier sentinelle lors de la première exécution ; les démarrages suivants ignorent l’exécution car la condition échoue.
/etc/rc.local est-il toujours pris en charge sur Ubuntu 22.04 ?
Oui, mais il est désactivé par défaut. Vous devez activer manuellement l’unité rc-local.service avec sudo systemctl enable rc-local et vous assurer que le fichier existe et est exécutable. Il est pris en charge comme mesure de compatibilité, et non comme pratique recommandée.
Comment puis-je vérifier pourquoi un script de démarrage n’a pas réussi à s’exécuter ?
Exécutez sudo journalctl -u yourservice.service -b pour afficher toutes les entrées de journal de cette unité depuis le dernier démarrage. Pour les échecs de rc.local, vérifiez sudo systemctl status rc-local.service et consultez /var/log/syslog pour les entrées horodatées pendant la séquence de démarrage.
