![Nginx は nginx: [emerg] bind() to 0.0.0.0:80 に失敗しました (98: アドレスは既に使用されています) というエラーを出し続けます](https://rvso.com/image/718755/Nginx%20%E3%81%AF%20nginx%3A%20%5Bemerg%5D%20bind()%20to%200.0.0.0%3A80%20%E3%81%AB%E5%A4%B1%E6%95%97%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%20(98%3A%20%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AF%E6%97%A2%E3%81%AB%E4%BD%BF%E7%94%A8%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99)%20%E3%81%A8%E3%81%84%E3%81%86%E3%82%A8%E3%83%A9%E3%83%BC%E3%82%92%E5%87%BA%E3%81%97%E7%B6%9A%E3%81%91%E3%81%BE%E3%81%99.png)
私はこの問題について、多くの Web サイトや 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 証明書を更新できないことです (ただし、これは別の理由による可能性があり、それが原因である可能性があるため、ここには書きたくありません)。
編集
私は、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 と新しい include フォルダーを追加して、Web サイト用に別の場所を用意しただけかもしれません。ドメイン/サブドメインごとに個別の設定ファイルがあります。次のようになります:
example.com
&www.example.com
api.example.com
blog.example.com
これは、これらが同じドメインの下にある別々の Web サイトであると想定しているためです。これらが同じ Web サイトにあり、いわゆるサブページである場合は、場所オプションを使用してサブページのみを作成した方がよいでしょう。
設定を再編成するには、 3 つの独立したサーバー セクションを持つファイルnginx
を作成しますcom.example.conf
。まず、www を使用しないユーザーを www Web サイトにリダイレクトします。
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;
}
3 番目のセクションにはメイン サイトが含まれます。
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
。前と同様に、前の設定から最初の 2 つのセクションを追加し、各サブドメインに場所ごとに異なる設定を追加するだけです。
たとえば、私の 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 が有効になっていなかったため、同じように動作しなかったのはそれが原因である可能性があります。