Nginx는 nginx: [emerg] 바인딩()을 0.0.0.0:80으로 계속 던집니다. 실패함(98: 주소가 이미 사용 중임)

Nginx는 nginx: [emerg] 바인딩()을 0.0.0.0:80으로 계속 던집니다. 실패함(98: 주소가 이미 사용 중임)

저는 이 문제에 대해 많은 웹사이트와 여기 ServerFault에서 많은 질문/답변을 확인했습니다. 그러나 구성 오류의 근본 원인을 파악하지 못하는 것 같습니다.

내 nginx 서버에는 4개의 도메인이 있습니다.

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

포트 80과 443 모두에서 모두 실행 중입니다. 이것은 , 및 지시문 만 nginx.conf변경하여 모든 항목에 사용한 템플릿입니다 . 몇 가지 다른 변경 사항이 있지만 원칙적으로 영향을 미치지 않아야 합니다. 다른 것처럼 .server_namerooterror_logaccess_logfastcgi_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 인증서를 갱신할 수 없다는 것입니다(비록 다른 이유가 있을 수 있고 이것이 이유일 수 있기 때문에 여기에 입력하고 싶지 않지만).

편집하다

SSL 인증서 데이터에 주석을 달았다는 점을 제외하고는 완전히 동일한 구성으로 Vagrant를 사용하여 로컬 컴퓨터를 설정했습니다. 문제없이 서버를 다시 시작할 수 있습니다. 따라서 아마도 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과 새 포함 폴더를 추가했을 수도 있습니다. 각 도메인/하위 도메인에 대해 별도의 구성 파일이 있습니다. 좋다:

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

이는 동일한 도메인에 속한 별도의 웹사이트라고 가정하기 때문입니다. 동일한 웹사이트에 있고 소위 하위 페이지인 경우 위치 옵션을 사용하여 하위 페이지만 만드는 것이 더 나을 것입니다.

구성을 재구성하기 위해 3개의 별도 서버 섹션이 포함된 파일을 nginx만듭니다 . com.example.conf첫 번째는 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;
    }
}

(index.php 위치에 있는 fastcgi 부분이 이상해 보이지만 그건 여러분에게 맡기겠습니다.)

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

바인딩()을 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 서버를 다시 시작할 수 있었습니다.

내가 설정한 방랑 서버에는 IPV6이 활성화되어 있지 않았으므로 동일한 방식으로 작동하지 않았다는 사실과 관련이 있을 수 있습니다.

관련 정보