Служба systemd не удается запустить проект на Python.

Вопрос или проблема

Я пытаюсь запустить проект, написанный на Python, на сервере. Я создал следующий файл службы:

[Unit]
Description=My bot service
After=multi-user.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/python3.10 /home/path/to/bot.py
[Install]
WantedBy=multi-user.target

Но этот код не работает. Если я проверяю статус службы, он возвращает следующее:

● test.service - My bot service
     Loaded: loaded (/etc/systemd/system/test.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Fri 2022-10-21 08:16:07 UTC; 15s ago
    Process: 156695 ExecStart=/usr/bin/python3.10 /home/path/to/bot.>
   Main PID: 156695 (code=exited, status=1/FAILURE)

Oct 21 08:16:07 instance-1 systemd[1]: test.service: Scheduled restart job, restart coun>
Oct 21 08:16:07 instance-1 systemd[1]: Stopped My bot service.
Oct 21 08:16:07 instance-1 systemd[1]: names.service: Start request repeated too quickly.
Oct 21 08:16:07 instance-1 systemd[1]: test.service: Failed with result 'exit-code'.
Oct 21 08:16:07 instance-1 systemd[1]: Failed to start My bot service.

Когда я запускаю бота напрямую (/usr/bin/python3.10 /home/path/to/bot.py), он работает.

Когда я запускаю простой скрипт на Python как службу, он тоже работает.

Я просто не понимаю, что может быть причиной проблемы внутри проекта. Добавление параметра WorkingDirectory в конфигурационный файл ничего не изменило

bot.py возвращает 1.

Вам нужно исследовать код, чтобы увидеть, при каких условиях он может завершиться с этим кодом.

Первое, что я бы сделал, это удалил Restart=always. Вы можете видеть, что ваш скрипт неудачно завершился, затем перезапустился, затем перезапустился, затем перезапустился, затем перестал пытаться. Скорее всего, если он не сработает в первый раз, он не сработает и позже. Так что в этой строке мало необходимости, пока у вас все не заработает достаточно хорошо. Все, что она делает, это засоряет вывод и вызывает путаницу во время разработки. Без этой строки systemctl status мог бы выдать ваши последние несколько строк stdout.

Следующее, что я бы сделал, это запустил эту службу и проверил журнал:

$ sudo systemctl start test.service
$ journalctl -u test.service --since "5 minutes ago"

Это может дать подсказки о том, что происходит, через stdout или stderr. Особенно проверьте трассировки исключений.

Если в журнале нет никакого вывода, это может быть потому, что python завершил работу до того, как мог сбросить свой буфер. Используйте опцию -u в python, чтобы обеспечить неблокированный вывод:

ExecStart=/usr/bin/python3.10 -u /home/path/to/bot.py

Наконец, если этот бот создает окно и имеет GUI, есть специальные шаги, которые нужно предпринять (запустить это на --user bus или установить переменную окружения DISPLAY=). Я могу дать больше информации, если вы ожидаете GUI. Это сверхраспространенная причина проблем “Я могу запустить это, но systemd не может”.

.

Ответ или решение

Для успешного решения проблемы с запуском Python проекта в качестве systemd службы следует тщательно проанализировать и тестировать каждый элемент, чтобы выявить причину сбоя. Рассмотрим основные шаги, которые помогут в данной ситуации.

Теория

1. Структура systemd службы:
Systemd файлы подразделяются на три основных секции:

  • [Unit]: информация о сервисе, его зависимостях и порядке запуска.
  • [Service]: инструкция по запуску программы, как она будет реагировать на события и как будет перезапускаться.
  • [Install]: определяет, когда сервис должен быть активирован.

Ключевой параметр в вашем файле — это ExecStart, который определяет команду запуска Python скрипта.

2. Проблема выхода с кодом 1:
Код возврата 1 обычно указывает на общую ошибку. Это может быть связано с логикой программы, отсутствием необходимых ресурсов или зависимостей.

3. Буферизация вывода:
Python по умолчанию буферизует вывод, что может привести к тому, что ошибки или информация не сразу видны. Это можно изменить, используя опцию -u для небуферизированного вывода.

Пример

  1. Проверка статуса и журнала службы:

    Используйте команду для проверки статуса:

    sudo systemctl status test.service

    Журнал событий поможет понять, что происходит при запуске:

    journalctl -u test.service --since "5 minutes ago"
  2. Настройка файла сервиса с небуферизированным выводом:

    Измените строку запуска в вашем файле сервисов:

    ExecStart=/usr/bin/python3.10 -u /home/path/to/bot.py
  3. Отладка Python кода:

    Если скрипт использует дополнительные ресурсы (файлы, соединения с базами данных, API и др.), убедитесь, что все они доступны службе. Возможно, потребуется задать переменные окружения или изменить права доступа.

Применение

1. Удаление Restart=always:

Временно уберите строку Restart=always из вашего файла службы. Это позволит получить исчерпывающую информацию о первоначальном состоянии после сбоя, без попыток повторных перезапусков, которые усложняют отладку.

2. Проверка зависимостей и доступов:

Проверьте все зависимости скрипта. Возможно, необходимы специальные разрешения или доступ к ресурсам, таким как Connect к базе данных, доступ к файлам, API и т.д. Важно, чтобы служба имела необходимые разрешения.

3. Проверка путей и окружения:

Убедитесь, что все пути указаны корректно. Помните, что пути указываются относительно корневой папки, поскольку systemd запускается как системный процесс. Если скрипт зависит от виртуального окружения, убедитесь, что оно правильно активировано в контексте службы.

Для установки корректного окружения можно использовать Environment в секции [Service] в файле сервиса, например:

[Service]
Environment="PYTHONPATH=/path/to/dependencies"

4. Работа с GUI приложениями:

В случае, если ваш бот имеет графический интерфейс, systemd требуется дополнительных настроек. Наиболее частая причина — это необходимость использования DISPLAY= переменной. Для этого её также можно задать в секции Environment.

Воспользуйтесь предложенными методами и техниками для постепенного устранения неисправности. Важно действовать поэтапно: сначала отладить и убедиться, что код работает в изолированном запуске; затем внимательно настроить systemd сервис. Это поможет вам не только выявить проблему, но и устранить её.

Оцените материал
Добавить комментарий

Капча загружается...