Вопрос или проблема
У меня есть API на golang, который должен работать круглосуточно для обратного прокси nginx.
У меня есть скрипт..
#!/usr/bin/bash
cd /root/api && go run .
Он запускается нормально вручную.
Но /etc/systemd/system/api.service не удается запустить
.service:
[Unit]
Description=API на Go для фронтенда www
[Service]
Type = simple
ExecStart=/root/api.sh
systemctl status сообщает
× api.service - API на Go для фронтенда www
Loaded: загружен (/etc/systemd/system/api.service; статически)
Active: неудачно (Результат: код выхода) с Thu 2024-11-21 18:55:03 UTC; 2 мин 17 с назад
Duration: 118 мс
Invocation: e6e602afee2b4bf6b2d623c15fcbb65e
Process: 343565 ExecStart=/root/api.sh (код=вышел, статус=1/НЕУДАЧА)
Main PID: 343565 (код=вышел, статус=1/НЕУДАЧА)
Mem peak: 2.8M
CPU: 50 мс
Ответ или решение
Чтобы разобраться с проблемой запуска вашего Go API через systemd, необходимо проанализировать несколько аспектов конфигурации вашего сервиса. Ваша ситуация описывает сценарий, когда скрипт работает нормально при ручном запуске, но не запускается через systemd. Мы рассмотрим ключевые моменты, которые могут вызывать эту проблему.
1. Ошибки в скрипте
Первое, на что стоит обратить внимание — это сам скрипт api.sh
. Вы используете конструкцию cd /root/api && go run .
, что подразумевает равенство относительных путей и рабочей директории. Попробуйте добавить явный указатель на использование абсолютного пути к исполняемому файлу Go. Вот как можно изменить ваш скрипт:
#!/usr/bin/env bash
cd /root/api
exec /usr/local/go/bin/go run .
2. Права доступа
Убедитесь, что скрипт api.sh
имеет необходимые права на выполнение. Выполните команду:
chmod +x /root/api.sh
Кроме того, проверьте разрешения для каталога /root/api
и всех его компонентов, чтобы убедиться, что у пользователя, под которым работает systemd (обычно это root
), есть возможность доступа к этим файлам.
3. Конфигурация systemd
Ваш файл /etc/systemd/system/api.service
выглядит неплохо, но важно также задать параметры пользовательского окружения. Попробуйте добавить следующие строки:
[Service]
Type=simple
User=root
WorkingDirectory=/root/api
ExecStart=/root/api.sh
Restart=on-failure
StandardOutput=journal
StandardError=journal
Здесь мы указываем User=root
, чтобы явным образом задать пользователя, под которым будет выполняться скрипт, а WorkingDirectory
позволяет избежать потенциальных путаниц с относительными путями.
4. Логирование
Чтобы получить более детальную информацию о любой ошибке, которая может происходить при запуске вашего сервиса, вы можете использовать системный журнал. После попытки запуска сервиса выполните команду:
journalctl -xe -u api.service
Это позволит вам увидеть полные логи и, возможно, выявить основную причину сбоя.
5. Депендентности
Если ваш сервис зависит от других сервисов (например, сети или базы данных), убедитесь, что они запущены до старта вашего API. Для этого можно добавить зависимости в секцию [Unit]
, например:
[Unit]
Description=A go-lang API for the www frontend
After=network.target
Requires=network.target
Заключение
Следуя данным рекомендациям, вы должны быть в состоянии решить проблему с запуском вашего скрипта через systemd. Не забудьте после изменений перезагрузить демон systemd:
sudo systemctl daemon-reload
После этого попробуйте снова запустить ваш сервис:
sudo systemctl start api.service
Каждый из приведённых шагов поможет вам определить и устранить проблемы, которые мешают вашему сервису работать должным образом. Убедитесь в том, что вы проверяете каждую часть конфигурации, чтобы добиться стабильной работы вашего Go API.