「Nginx」- nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)

  CREATED BY JENKINSBOT

问题描述

在启动 Nginx 服务时,产生如下错误:

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
...

问题原因

导致该问题的原因有很多,我们这里将列举我们的场景,以及解决方案。

原因一、端口被占用

这是最常见的原因,80 端口被占用,导致 Nginx 服务进行绑定。

解决方案

找到占用 80 端口的进程,并将其结束。

原因二、Dual-Stack Sockets for IPv6

这是 IPv4 到 IPv6 过渡期经常发生的问题。如下配置也将导致上述错误:

server {
    listen [::]:80 ipv6only=off;
    server_name dual-stack.example.com;
}
server {
    listen 0.0.0.0:80;
    server_name ipv4.example.com;
}

通过 ipv6only=off 选项,当前创建的 Socket 是双栈的,IPv4 将被映射到 IPv6,此时只能创建一条监听,不能再监听 IPv4。

相关文献:
IPv4-Mapped IPv6 Address – Teknologisk videncenter
c – Dual stack with one socket – Stack Overflow

解决方案

既然不能监听 IPv4,并且现在是双栈,我们能够放心的监听 IPv6 地址(同时也保证 IPv4 访问):

server {
    listen [::]:80 ipv6only=off;
    server_name dual-stack.example.com;
}
server {
    listen [::]:80;
    server_name ipv4.example.com;
}
# 因为场景特殊,我们无法修改第一个 Server 的配置
# 当然,还可以关闭双栈。

参考文献

IPv4-Mapped IPv6 Address – Teknologisk videncenter
c – Dual stack with one socket – Stack Overflow
Module ngx_http_core_module