Automatyczne uruchamianie programów przy starcie serwera (systemd i cron)

Opublikowano Zaktualizowano 4 min czytania

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.

CechaJednostka systemdCron z @reboot
Uruchomienie przy starcie systemutaktak
Restart po awariitak, automatycznienie
Sprawdzenie statusutak, przez systemctlnie
Log wyjścia programutak, w journalutylko przy własnym przekierowaniu
Sterowanie kolejnością startutak, na przykład po siecitylko 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=forking oraz wpisu PIDFile.
  • User: użytkownik, na którego koncie działa usługa. Nigdy nie uruchamiaj aplikacji jako root bez potrzeby.
  • WorkingDirectory: zastępuje cd ze skryptu startowego.
  • Restart=on-failure: systemd restartuje usługę po awarii. Z Restart=always zrobi 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=forking z pasującym PIDFile albo 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 poleceniem ls -la.
  • Po starcie systemu nic nie działa: usługa została uruchomiona, ale nie aktywowana. To systemctl enable jest 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?
Do wszystkiego, co ma działać na stałe, systemd jest wyraźnie lepszy. Restartuje aplikację po awarii, pokazuje jej status i zapisuje wyjście do logu. Wpis w cronie uruchamia polecenie tylko raz, przy starcie systemu.
Gdzie umieścić własną jednostkę systemd?
Własne pliki jednostek trafiają do /etc/systemd/system/ i mają rozszerzenie .service. Po każdej zmianie musisz wykonać systemctl daemon-reload, inaczej systemd w ogóle nie zobaczy tego pliku.
Moja usługa działa ręcznie, ale nie startuje przy starcie systemu. Dlaczego?
Najczęściej brakuje bezwzględnej ścieżki, bo zmienna środowiskowa PATH jest przy starcie systemu ustawiona bardzo skąpo. Drugi najczęstszy powód: usługa została tylko uruchomiona, ale nigdy nie aktywowana na stałe przez systemctl enable.
Jak podejrzeć wyjście mojej usługi?
systemd zapisuje wszystko do journala. Poleceniem journalctl -u mojausluga.service -f czytasz wyjście na żywo, co przy szukaniu błędów jest najszybszą drogą.
Czy do serwera gier potrzebuję jeszcze screena albo tmuxa?
Nie. systemd sam utrzymuje proces przy życiu, zapisuje jego wyjście do logu i automatycznie restartuje go po awarii. Do zwykłej pracy ciągłej screen i tmux są tym samym zbędne.

Autostart systemd Crontab Linux Serwery gier TeamSpeak 3 Start serwera