Systemctl показывает failed — и непонятно почему. В большинстве случаев причина в одном из пяти мест. Разбираем по порядку.
Быстрая диагностика: три команды
# 1. Статус сервиса
sudo systemctl status nginx
# 2. Последние записи журнала
sudo journalctl -u nginx -n 50 --no-pager
# 3. Проверить конфиг самого сервиса
sudo nginx -t
Ключевое: вывод systemctl status показывает последние строки лога. Часто причина видна сразу: «bind() to 0.0.0.0:80 failed (98: Address already in use)».
Причина 1: порт уже занят
# Кто занимает порт 80?
sudo ss -tlnp | grep :80
sudo lsof -i :80
# Найти и остановить конкурирующий процесс
sudo kill PID
# или
sudo systemctl stop apache2 # если другой веб-сервер
Причина 2: ошибка в конфиге
# Nginx
sudo nginx -t
# PHP-FPM
sudo php-fpm8.2 -t
# PostgreSQL
sudo -u postgres pg_lsclusters
# Любой systemd-сервис
sudo systemd-analyze verify /etc/systemd/system/myservice.service
Причина 3: нет файла или директории
# Журнал покажет путь
sudo journalctl -u myservice -n 100 --no-pager | grep -E 'No such|Permission|Error|error'
# Проверить что файл существует
ls -la /path/from/error/message
# Проверить права
stat /var/log/myapp/
Причина 4: недостаточно прав
# Посмотреть под каким пользователем работает сервис
grep -E 'User|Group' /etc/systemd/system/myservice.service
# или
sudo systemctl cat myservice | grep -E 'User|Group'
# Исправить владельца директории
sudo chown -R www-data:www-data /var/log/myapp/
sudo chmod 755 /var/log/myapp/
Причина 5: зависимость не запущена
# Посмотреть зависимости
sudo systemctl list-dependencies myservice
# Статус всех зависимостей
sudo systemctl status myservice --no-pager
# В блоке Requires/After — имена зависимостей
# Запустить зависимость вручную
sudo systemctl start postgresql
sudo systemctl start myservice
Перезапуск после исправления
# Перечитать unit-файлы (если изменяли .service)
sudo systemctl daemon-reload
# Запустить
sudo systemctl start myservice
# Проверить статус
sudo systemctl status myservice
# Если OK — включить автозапуск
sudo systemctl enable myservice
Итог
Порядок: systemctl status → journalctl -u СЕРВИС → проверка конфига → порт → права. В 90% случаев причина видна в журнале после второй команды.