Назад | Перейти на главную страницу

Nginx продолжает бросать nginx: [emerg] bind () до 0.0.0.0:80 не удалось (98: адрес уже используется)

Я проверял множество веб-сайтов и много вопросов / ответов здесь, в ServerFault, по этой проблеме. Однако, похоже, я не вникаю в суть ошибки конфигурации.

У меня на сервере nginx 4 домена:

Все они запущены и работают на портах 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

Какой твой nginx.conf выглядит как? Я предполагаю, что вы не изменили конфигурацию, возможно, просто добавили gzip и новую папку include, чтобы иметь отдельное расположение для веб-сайтов. Для каждого вашего домена / поддомена есть отдельный файл конфигурации. Подобно:

  • example.com & www.example.com
  • api.example.com
  • blog.example.com

Это потому, что я предполагаю, что это отдельные веб-сайты в одном домене. Если они находятся на одном веб-сайте и представляют собой просто так называемую подстраницу, тогда вам будет лучше создать только подстраницы с параметрами местоположения.

Чтобы реорганизовать ваш nginx config я бы создал 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;
}

Надеюсь, это поможет вам, если нет, прокомментируйте свои вопросы.

Я наконец решил проблему. Казалось, что на сервере включен 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.

На бродячем сервере, который я установил, не был включен IPV6, так что это могло иметь какое-то отношение к тому факту, что он вел себя иначе.