# Настройка скрипта автозапуска через SystemD-юнит (серверный подход)

# Предисловие

### Какие существуют подходы к автозагрузке в Linux?

Есть 3 самых популярных подхода решения задачи "я хочу, чтобы скрипт запускался после перезагрузки сервера":

1. Через файл <span style="color: rgb(45, 194, 107);">rc.local</span> - устаревший подход, да и правка системных конфигов, даже таких, всегда чревата;
2. <span style="color: rgb(45, 194, 107);">@reboot в cron</span> - это явный костыль, хотя многие со мной не согласятся;
3. Скрипты в духе "<span style="color: rgb(45, 194, 107);">sleep 60 &amp;&amp; ...</span>" - это зло. Они не дают контроля и работают буквально "на шару". Слишком много ответственности для простого bash-скрипта.

<p class="callout info">**ИМХО автора**  
Для серверов единственно правильный путь решения этой проблемы сейчас - <span style="color: rgb(45, 194, 107);">**systemd unit**</span>  
</p>

##### Почему это лучше, чем альтернативные подходы?

Подход автора лучше, потому что он:

1. Дает значительно больше контроля над сервисом: его остановка, внеплановый запуск или сбор информации о его работе становятся значительно проще для администратора - для этого будут использоваться стандартные утилиты, к которым все привыкли (<span style="color: rgb(45, 194, 107);">systemctl</span> и <span style="color: rgb(45, 194, 107);">journalctl</span>);
2. Разделяет ответственность: логика скрипта находится отдельно от логики, которая ответственна за его запуск;
3. Позволяет менять логику скрипта отдельно, не меняя любой внешней логики (атомарность в подходе).

# Пример настройки скрипта для перезапуска сервисов

## Пишем сервисный файл (SystemD-юнит)

Я редактирую файл юнита. Допустим, он будет называться <span style="color: rgb(45, 194, 107);">post-reboot-tasks</span>, тогда:

```bash
nano /etc/systemd/system/post-reboot-tasks.service
```

 В самом юните я делаю следующее:

```ini
[Unit]
Description=Post reboot tasks
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/opt/scripts/post-reboot.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
```

#### Почему это работает?

Тут у читателя может возникнуть **вопрос**: А с чего ты взял, что оно сработает только при перезагрузке? Где ты здесь указываешь, что он будет выполнен именно и только после ребута системы?

**Отвечаю**:

В SystemD это делается не отдельной строкой в духе "<span style="color: rgb(45, 194, 107);">AfterReboot=true</span>", а самим фактом, что юнит включён в target, который достигается при загрузке. В этом примере вот эта строчка и говорит, "запускать при старте системы":

```ini
WantedBy=multi-user.target
```

Когда вы делаете:

```bash
systemctl enable post-reboot-tasks
```

SystemD создаёт symlink юнита в:

```bash
/etc/systemd/system/multi-user.target.wants/post-reboot-tasks.service
```

А <span style="color: rgb(45, 194, 107);">multi-user.target</span> - это стандартная "нормальная загрузка **сервера без GUI**" (условно, <span style="color: rgb(45, 194, 107);">runlevel=3</span>). Каждый раз, когда система доходит до этого Target'а (то есть после ребута/бут-цикла), SystemD подхватит юнит и запустит его.

Здесь "после ребута" = "после каждой загрузки", т.е. юнит будет выполняться каждый boot.

## Подготовка скрипта

Здесь все просто. Я:

1. Создаю директорию, которую ранее указывал в сервисном файле;
2. Создаю и заполняю скрипт внутри нее (см. пример ниже);
3. Выдаю необходимые права для запуска скрипта;
4. Применяю изменения для SystemD, чтобы юнит появился в списке и попал в пул активных.

[![image.png](https://info.elijahkamsky.ru/uploads/images/gallery/2026-01/scaled-1680-/AZDimage.png)](https://info.elijahkamsky.ru/uploads/images/gallery/2026-01/AZDimage.png)

Команда, которой я это сделал:

```bash
mkdir -p /opt/scripts/ && \
nano /opt/scripts/post-reboot.sh && \
chmod +x /opt/scripts/post-reboot.sh && \
systemctl daemon-reexec && systemctl daemon-reload && \
systemctl enable --now post-reboot-tasks
```

<p class="callout success">Теперь, когда создан скрипт и юнит-файл попал в реестр SystemD, он будет запускаться при каждой перезагрузке</p>

#### Пример наполнения скрипта

Перейдем к примерам скриптов. В моем случае, я бы хотел автоматический перезапуска ряда сервисов после того, как система загрузилась и получила IP-адрес. Именно это я и делаю здесь:

[![image.png](https://info.elijahkamsky.ru/uploads/images/gallery/2026-01/scaled-1680-/aX6image.png)](https://info.elijahkamsky.ru/uploads/images/gallery/2026-01/aX6image.png)

В случае, если вы захотите изменить его логику, вы можете просто отредактировать скрипт. Перезапускать юнит или указывать SystemD о его изменении не нужно.

##### <span style="color: rgb(255, 255, 255); background-color: rgb(224, 62, 45);"> **Важное уточнение, которое я вынесу отдельно**<span style="color: rgb(255, 255, 255); background-color: rgb(224, 62, 45);"> </span><span style="color: rgb(255, 255, 255); background-color: rgb(224, 62, 45);"> </span><span style="color: rgb(255, 255, 255); background-color: rgb(224, 62, 45);"> </span><span style="color: rgb(255, 255, 255); background-color: rgb(224, 62, 45);"> </span><span style="color: rgb(255, 255, 255); background-color: rgb(224, 62, 45);"> </span></span>

Скрипт будет запускаться при загрузке системы только в том случае, если его статус - <span style="color: rgb(45, 194, 107);">enabled</span>. **В противном случае скрипт не попадет в автозагрузку**. Проверить это можно командой:

```bash
systemctl status post-reboot-tasks
```

[![image.png](https://info.elijahkamsky.ru/uploads/images/gallery/2026-01/scaled-1680-/7p5image.png)](https://info.elijahkamsky.ru/uploads/images/gallery/2026-01/7p5image.png)