Automatyczne uruchamianie programów przy starcie serwera (systemd i cron)
Tak sprawisz, że aplikacje, serwery gier i skrypty po każdym restarcie wstają same: przez jednostkę usługi systemd, czyli dzisiejszy standard, albo alternatywnie przez wpis w cronie z @reboot.
Ręczne podnoszenie wszystkich usług po każdym restarcie serwera kosztuje czas i prędzej czy później kończy się pomyłką. Linux ma na to własny mechanizm. W tym poradniku pokażemy, jak automatycznie uruchamiać własne aplikacje, serwery gier, boty i skrypty przy starcie serwera.
Omówimy dwie drogi: jednostkę usługi systemd, czyli dzisiejsze rozwiązanie standardowe, oraz starszy sposób przez wpis w cronie z @reboot. Obie działają niezależnie od dystrybucji, a więc tak samo na Debianie, Ubuntu, AlmaLinux oraz Rocky Linux.
systemd czy cron: który sposób wybrać?
systemd jest standardem zarządzania usługami we wszystkich aktualnych dystrybucjach Linuksa. Wpis w cronie z @reboot również uruchomi twoją aplikację, ale nic ponadto nie potrafi.
| Cecha | Jednostka systemd | Cron z @reboot |
|---|---|---|
| Uruchomienie przy starcie systemu | tak | tak |
| Restart po awarii | tak, automatycznie | nie |
| Sprawdzenie statusu | tak, przez systemctl | nie |
| Log wyjścia programu | tak, w journalu | tylko przy własnym przekierowaniu |
| Sterowanie kolejnością startu | tak, na przykład po sieci | tylko zgrubnie przez sleep |
Do wszystkiego, co ma działać na stałe, lepszym wyborem jest jednostka systemd. Wpis w cronie pozostaje szybkim obejściem do prostych, jednorazowych poleceń.
Wymagania
- Dostęp root przez SSH do twojego serwera wirtualnego lub serwera root.
- Skrypt startowy albo program, który już bez zarzutu uruchamia się z wiersza poleceń. Przetestuj to najpierw ręcznie, zanim zaczniesz automatyzować.
- Bezwzględna ścieżka do tego skryptu. Ścieżki względne nie sprawdzają się przy starcie systemu.
Tworzenie jednostki usługi systemd
Własne jednostki leżą w /etc/systemd/system/ i mają rozszerzenie .service. Utwórz plik:
nano /etc/systemd/system/mojausluga.service
Prosty, od razu gotowy do użycia szkielet wygląda tak:
[Unit]
Description=Moja własna usługa
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=mojuzytkownik
WorkingDirectory=/opt/mojausluga
ExecStart=/bin/bash /opt/mojausluga/start.sh
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
Co oznaczają poszczególne wiersze
- Description: czytelna nazwa, którą pokazuje
systemctl status. - After i Wants: usługa startuje dopiero wtedy, gdy sieć jest dostępna. Odpada dzięki temu sztuczka z
sleep, którą znasz z crona. - Type=simple: program pozostaje na pierwszym planie. Jeśli twój skrypt startowy sam przechodzi w tło, potrzebujesz zamiast tego
Type=forkingoraz wpisuPIDFile. - User: użytkownik, na którego koncie działa usługa. Nigdy nie uruchamiaj aplikacji jako root bez potrzeby.
- WorkingDirectory: zastępuje
cdze skryptu startowego. - Restart=on-failure: systemd restartuje usługę po awarii. Z
Restart=alwayszrobi to również wtedy, gdy program zakończy się normalnie. - WantedBy=multi-user.target: sprawia, że usługa wstaje razem ze zwykłym startem systemu.
Aktywacja i test usługi
Po każdej zmianie w pliku jednostki systemd musi wczytać go na nowo. Następnie włącz usługę do automatycznego startu i od razu ją uruchom:
systemctl daemon-reload
systemctl enable --now mojausluga.service
Czy wszystko działa, sprawdzisz poleceniem:
systemctl status mojausluga.service
Wyjście aplikacji trafia do journala. Poniższym poleceniem czytasz je na żywo, co przy szukaniu błędów jest najszybszą drogą:
journalctl -u mojausluga.service -f
Do zatrzymania, restartu albo trwałego wyłączenia:
systemctl stop mojausluga.service
systemctl restart mojausluga.service
systemctl disable mojausluga.service
Przykład: automatyczny start serwera TeamSpeak 3
Dołączony skrypt startowy TeamSpeaka sam przechodzi w tło i zakłada plik PID. Dlatego właściwy jest tutaj Type=forking:
[Unit]
Description=TeamSpeak 3 Server
After=network-online.target
Wants=network-online.target
[Service]
Type=forking
User=teamspeak
WorkingDirectory=/home/teamspeak
ExecStart=/home/teamspeak/ts3server_startscript.sh start
ExecStop=/home/teamspeak/ts3server_startscript.sh stop
PIDFile=/home/teamspeak/ts3server.pid
Restart=on-failure
RestartSec=15
[Install]
WantedBy=multi-user.target
Dopasuj nazwę użytkownika i katalog do własnej instalacji. Ważne, żeby podany użytkownik faktycznie był właścicielem tego katalogu.
Przykład: serwer gier albo bot ze skryptu startowego
Dla Minecrafta, ARK, Army 3, serwerów LinuxGSM albo własnoręcznie napisanego bota wystarcza z reguły wariant prosty. Usługa działa na pierwszym planie, a systemd przejmuje nadzór i restart:
[Unit]
Description=Serwer gry
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=gameserver
WorkingDirectory=/home/gameserver/server
ExecStart=/bin/bash /home/gameserver/server/start.sh
Restart=always
RestartSec=15
[Install]
WantedBy=multi-user.target
Jeśli kilka usług startuje jednocześnie i wzajemnie się spowalnia, rozłóż start w czasie różnymi wartościami RestartSec albo uzupełnij After= o nazwę jednostki, która ma ruszyć jako pierwsza.
Alternatywa: autostart przez cron z @reboot
Jeśli chcesz wykonać przy starcie tylko jedno polecenie i nie potrzebujesz nadzoru, wystarczy wpis w cronie. Ustaw najpierw edytor i otwórz crontaba:
export VISUAL=nano; crontab -e
Wpisz tam wiersz z @reboot:
@reboot sleep 60 && cd /<KATALOG-ZE-SKRYPTEM>/ && bash <TWÓJ-SKRYPT>.sh
@reboot odpowiada za to, żeby polecenie wykonywało się raz przy każdym starcie systemu. Fragment sleep 60 czeka 60 sekund, aby sieć i baza danych zdążyły się wcześniej podnieść. Potem polecenie przechodzi do katalogu twojego skryptu i go uruchamia.
Przykład dla serwera głosowego, który ma działać na własnym koncie użytkownika:
@reboot sleep 45 && cd /home/<KATALOG-TEAMSPEAK>/ && sudo -u <UŻYTKOWNIK-TEAMSPEAK> bash ts3server_startscript.sh start
Jeśli wpisujesz kilka wierszy, nadaj każdemu inną wartość sleep (minimum 45), żeby wszystkie usługi nie startowały naraz. Wartość podaje się w sekundach.
Najczęstsze błędy
- Usługa nie startuje, choć ręcznie działa: najczęściej brakuje bezwzględnej ścieżki. W jednostce oraz w cronie zmienna środowiskowa PATH jest ustawiona bardzo skąpo, dlatego zawsze pisz
/bin/bash /pelna/sciezka/skrypt.sh. - „Unit not found” po utworzeniu pliku: zabrakło polecenia
systemctl daemon-reload. - Usługa natychmiast się kończy: program przechodzi w tło. Użyj
Type=forkingz pasującymPIDFilealbo uruchom program w trybie pierwszoplanowym. - Błąd uprawnień przy starcie: użytkownik podany w
User=nie ma dostępu do katalogu. Sprawdź właściciela poleceniemls -la. - Po starcie systemu nic nie działa: usługa została uruchomiona, ale nie aktywowana. To
systemctl enablejest krokiem, który wpisuje ją na stałe.
Na koniec najlepszy test: zrestartuj serwer raz poleceniem reboot, a potem sprawdź przez systemctl status, czy wszystkie usługi działają zgodnie z oczekiwaniem.
Najczęstsze pytania
Co jest lepsze: systemd czy cron z @reboot?
Gdzie umieścić własną jednostkę systemd?
Moja usługa działa ręcznie, ale nie startuje przy starcie systemu. Dlaczego?
Jak podejrzeć wyjście mojej usługi?
Czy do serwera gier potrzebuję jeszcze screena albo tmuxa?
2024-2026 KernelHost GmbH. Wszelkie prawa zastrzeżone. Ten poradnik jest chroniony prawem autorskim. Publikowanie go w innych serwisach, w całości, we fragmentach lub w zmienionej formie, wymaga naszej pisemnej zgody. Cytaty z podaniem źródła i z linkiem są jak najbardziej mile widziane.

