![Nginx продолжает выдавать ошибку nginx: [emerg] bind() to 0.0.0.0:80 failed (98: адрес уже используется)](https://rvso.com/image/718755/Nginx%20%D0%BF%D1%80%D0%BE%D0%B4%D0%BE%D0%BB%D0%B6%D0%B0%D0%B5%D1%82%20%D0%B2%D1%8B%D0%B4%D0%B0%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D1%83%20nginx%3A%20%5Bemerg%5D%20bind()%20to%200.0.0.0%3A80%20failed%20(98%3A%20%D0%B0%D0%B4%D1%80%D0%B5%D1%81%20%D1%83%D0%B6%D0%B5%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D1%82%D1%81%D1%8F).png)
Я проверил множество веб-сайтов и много вопросов/ответов здесь, в ServerFault, по этой проблеме. Однако, похоже, я не докопался до сути ошибки конфигурации.
У меня на сервере nginx 4 домена:
example.com
www.example.com
api.example.com
blog.example.com
Они все запущены и работают, как в портах 80, так и 443. Это шаблон, nginx.conf
который я использовал для всех них, изменив только директивы server_name
, root
, error_log
и access_log
. Есть и другие изменения, но в принципе они не должны влиять. Например, разные fastcgi_param
.
Это шаблон для example.com
и www.example.com
:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/public_html/web;
if ($http_host = example.com) {
return 301 https://www.example.com$request_uri;
}
location / {
# try to serve file directly, fallback to front controller
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
fastcgi_param DATABASE_NAME some_database;
fastcgi_param DATABASE_USER some_user;
fastcgi_param DATABASE_PASSWORD some_pwd;
}
#return 404 for all php files as we do have a front controller
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/www.example.com_error.log;
access_log /var/log/nginx/www.example.com_access.log;
# Redirect non-https traffic to https
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
И вот именно такую ошибку я получаю при перезапуске сервера:
root@vps_server:/etc/nginx# journalctl -xe
Mar 09 09:17:16 vps_server systemd[1]: Starting A high performance web server and a reverse proxy server...
-- Subject: Unit nginx.service has begun start-up
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- Unit nginx.service has begun starting up.
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:18 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:18 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:18 vps_server nginx[30764]: nginx: [emerg] still could not bind()
Mar 09 09:17:18 vps_server systemd[1]: nginx.service: Control process exited, code=exited status=1
Mar 09 09:17:18 vps_server systemd[1]: Failed to start A high performance web server and a reverse proxy server.
-- Subject: Unit nginx.service has failed
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- Unit nginx.service has failed.
--
-- The result is failed.
Mar 09 09:17:18 vps_server systemd[1]: nginx.service: Unit entered failed state.
Mar 09 09:17:18 vps_server systemd[1]: nginx.service: Failed with result 'exit-code'.
Когда я пытаюсь обновить сертификаты с помощью , sudo certbot renew --dry-run
я получаю похожую ошибку, хотя и не совсем ту же самую.
Если я убью потоки nginx, то смогу перезапустить сервер. Но в следующий раз, когда я попытаюсь перезапустить его, он выдаст ту же ошибку. И самое ужасное, что я не могу обновить свои SSL-сертификаты (хотя это может быть связано с другой причиной, и я не хотел бы указывать ее здесь, так как это может быть причиной).
РЕДАКТИРОВАТЬ
Я настроил локальную машину с помощью Vagrant с точно такой же конфигурацией, за исключением того, что я прокомментировал данные SSL-сертификатов. Я могу перезапустить сервер без проблем. Так что, возможно, это как-то связано с конфигурацией Certbot/SSL.
Чтобы помочь с отладкой этой проблемы, вот вывод netstat -tulpn
(только nginx использует порты 80 и 443, что, насколько я понимаю, является ожидаемым выводом):
/var/log/nginx# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 16700/mysqld
tcp 0 0 0.0.0.0:5355 0.0.0.0:* LISTEN 1578/systemd-resolv
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 30608/nginx: master
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1675/sshd
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 10001/master
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 30608/nginx: master
tcp6 0 0 :::5355 :::* LISTEN 1578/systemd-resolv
tcp6 0 0 :::22 :::* LISTEN 1675/sshd
tcp6 0 0 :::25 :::* LISTEN 10001/master
udp 0 0 127.0.0.53:53 0.0.0.0:* 1578/systemd-resolv
udp 0 0 0.0.0.0:68 0.0.0.0:* 1343/dhclient
udp 0 0 0.0.0.0:5355 0.0.0.0:* 1578/systemd-resolv
udp6 0 0 :::5355 :::* 1578/systemd-resolv
решение1
Как выглядит ваш nginx.conf
? Я предполагаю, что вы не меняли конфигурацию, возможно, просто добавили gzip и новую папку include, чтобы иметь отдельное расположение для веб-сайтов. Для каждого вашего домена / поддомена есть отдельный файл конфигурации. Например:
example.com
&www.example.com
api.example.com
blog.example.com
Это потому, что я предполагаю, что это отдельные веб-сайты под одним доменом. Если они находятся на одном веб-сайте и являются просто так называемой подстраницей, то вам лучше создать только подстраницы с вариантами местоположения.
Чтобы реорганизовать вашу nginx
конфигурацию, я бы создал com.example.conf
файл с 3 отдельными разделами сервера. Во-первых, перенаправить пользователей без www на сайт с www:
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
Третий раздел будет содержать основной сайт:
server {
listen 443 ssl;
server_name example.com www.example.com;
root /var/www/example.com/public_html/web;
index index.php;
error_log /var/log/nginx/www.example.com_error.log;
access_log /var/log/nginx/www.example.com_access.log;
location / {
# try to serve file directly, fallback to front controller
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
fastcgi_param DATABASE_NAME some;
fastcgi_param DATABASE_USER some_user;
fastcgi_param DATABASE_PASSWORD some_pwd;
}
location ~ \.php$ {
return 404;
}
}
(Должен сказать, что часть fastcgi в вашем файле index.php кажется мне странной, но я предоставлю это вам)
Затем создайте отдельные файлы конфигурации как com.example.api.conf
и com.example.blog.conf
. Добавьте первые два раздела из предыдущей конфигурации аналогично тому, как это было сделано ранее, затем вы можете просто добавить себе для каждого поддомена отдельную конфигурацию для местоположений.
Например, у меня для сайтов Laravel это так:
rewrite ^/index\.php?(.*)$ /$1 permanent;
location / {
try_files $uri @rewrite;
}
location @rewrite {
rewrite ^(.*)$ /index.php/$1 last;
}
location ~ ^/index.php(/|$) {
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS on;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_read_timeout 299;
}
Надеюсь, это вам поможет. Если нет, оставляйте свои вопросы в комментариях.
решение2
Исправление bind() для 0.0.0.0:80 или 443 не удалось (98: адрес уже используется)
Выполните следующие команды:
sudo pkill -f nginx & wait $!
sudo systemctl start nginx
решение3
Я наконец решил проблему. Оказалось, что на сервере включен IPV6, и для этого нужно было немного изменить конфигурацию nginx.
Вместо этого используйте:
listen 80;
listen 443 ssl;
Мне пришлось использовать следующее:
listen [::]:80;
listen [::]:443 ssl;
На этом сайте я получил более точное и подробное объяснение:https://chrisjean.com/fix-nginx-emerg-bind-to-80-failed-98-address-already-in-use/
Любопытно, что моя ошибка была в следующем:
nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
вместо описанного (в предоставленном мной URL):
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
Однако это решило проблему, и мне удалось перезапустить сервер nginx без каких-либо проблем.
На сервере Vagrant, который я настроил, не был включен IPV6, так что это могло быть связано с тем, что он вел себя не так, как раньше.