nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
#Что означает ошибка
Nginx при запуске пытается занять порты, указанные в listen. Если порт уже слушает другой процесс (Apache, второй экземпляр nginx, Docker-контейнер, Caddy, старый зависший nginx), система отвечает «Address already in use» (код 98), и nginx не запускается. Иногда это ваша же дублирующая директива listen в двух файлах, а иногда порт удерживает зависший процесс после некорректной остановки.
#Возможные причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Запущен Apache или другой веб-серверОба на 80. | ss показывает apache2/httpd. | Остановите один. |
| Зависший процесс nginxСтарый master. | Порт занят, служба не запущена. | pkill, затем запуск. |
| Контейнер публикует порт-p 80:80. | docker ps показывает порт. | Остановите контейнер или смените порт. |
| Дубль listenДва блока одинаково. | В uniq -c больше 1 для default_server. | Объедините. |
| Конфликт IPv4/IPv6listen [::]:80 без ipv6only. | Ошибка на IPv6. | Добавьте ipv6only=on. |
| Порт ниже 1024 без правЗапуск не от root. | Permission denied (13). | Запуск через systemd/capabilities. |
#Порядок
- Узнайте, какой процесс слушает портПодключитесь к серверу по SSH с правами администратора и выполните
sudo ss -tlnp | grep -E ":80 |:443 "в Linux. Найдите строкиLISTENи имя процесса возле занятого порта. Еслиssнедоступна, воспользуйтесьsudo lsof -nP -iTCP:80 -sTCP:LISTEN. Запишите PID и программу — это диагностика без изменений. Учитывайте, что Nginx может штатно слушать 80 вместе с 443: ошибка часто вызвана вторым экземпляром службы. - Решите, какой из сервисов должен остатьсяЕсли порт занят Apache, сначала проверьте, не является ли он штатным backend для Nginx: откройте конфигурацию Nginx и найдите
proxy_passна Apache. На серверах с Nginx+Apache останавливать Apache нельзя без риска отключить PHP-сайты. Только если Apache действительно лишний и согласован простой, администратор может выполнитьsudo systemctl stop apache2, проверить сайт и при ошибке сразу запуститьsudo systemctl start apache2. Командуdisableбез решения владельца не выполняйте. - Остановите конфликтующий сервис или смените портЕсли
ssпоказывает Nginx, проверьте число основных процессов и службу командойsystemctl status nginx --no-pagerиps -ef | grep "[n]ginx: master". Не применяйтеpkillили массовое завершение: они обрывают соединения и могут вмешаться в панель хостинга. Если обнаружен второй экземпляр, выясните, какой именно конфигурационный файл он использует и кто его запустил; остановку выполняйте штатным средством этого экземпляра только после проверки. - Проверьте дубли listen в конфигурацииПосмотрите конфигурацию чтением
sudo nginx -T 2>&1 | grep -n -E "listen |server_name"и найдите одинаковый адрес:порт у конфликтующих конфигураций. Несколькоserverна одном порту допустимы; проблема возникает, например, если два процесса одновременно пытаются занять порт или используются несовместимые вариантыlisten. Сохраните копию файла, изменяйте только подтверждённую настройку и повторитеsudo nginx -t. - Убедитесь, что старые процессы nginx завершеныЕсли работает Docker или Podman, проверьте опубликованные порты:
docker ps --format "table {{.Names}}\t{{.Ports}}"в терминале хоста (не контейнера). Строка с0.0.0.0:80->...означает, что контейнер занимает внешний 80-й порт. Не останавливайте контейнер только из-за совпадения числа 80 внутри контейнера. Решите, кто должен принимать внешний трафик, и измените публикацию порта в конфигурации контейнера с возможностью отката. - Запустите nginx и проверьте статусПосле согласованного исправления выполните
sudo nginx -t: ожидаютсяsyntax is okиtest is successful. Только затем выполнитеsudo systemctl start nginx(если служба остановлена) либоsudo systemctl reload nginx(если работала). Проверьтеsystemctl status nginxи откройте сайт по HTTP/HTTPS. При ошибке верните сохранённую конфигурацию и изучитеsudo journalctl -u nginx -n 50 --no-pager. - Для IPv6 проверьте отдельную директиву listen [::]:80Если ошибка возвращается после перезагрузки, выполните
systemctl list-unit-files --state=enabled | grep -Ei "nginx|apache|httpd|caddy"и проверьте автозапуск каждого владельца порта. На панели хостинга два веб-сервера могут быть намеренно включены. Зафиксируйте сервис, который неожиданно стартует первым, и согласуйте его роль; не отключайте системные службы по совпадению названия без схемы сайтов и резервной копии настроек. - Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Особенности
Если после перезагрузки порт снова занят, проверьте автозапуск: systemctl list-unit-files --state=enabled | grep -E "apache|httpd|nginx|caddy". Отключите лишнее. Команда sudo fuser -k 80/tcp завершит процесс, держащий порт, но используйте её осознанно: она остановит любой сервис на этом порту, включая рабочие сайты.
#Порты выше 1024 и сокеты
Ошибка возможна не только на 80 и 443: если в listen указан нестандартный порт (8080, 8443) или адрес, которого нет на сервере, nginx выдаст Cannot assign requested address (99) — это уже другая проблема: IP-адрес не назначен на интерфейс. Проверьте, что адрес из listen присутствует в выводе ip -4 addr. Для UNIX-сокетов похожая ошибка выглядит как bind() to unix:/run/app.sock failed (98: Address already in use): тогда удалите устаревший файл сокета и убедитесь, что приложение не запущено дважды.
ip -4 addr show | grep inetls -l /run/*.sock /var/run/*.sock 2>/dev/nullПри использовании systemd убедитесь, что юнит nginx не запускается одновременно с nginx.service из другого пакета (например, OpenResty или Angie): systemctl list-units | grep -iE "nginx|openresty|angie".