nginx:[emerg]bind()到docker上的0.0.0.0:80失败(98:地址已在使用)

nginx:[emerg]bind()到docker上的0.0.0.0:80失败(98:地址已在使用),nginx,docker,Nginx,Docker,我正在尝试从nginx加载默认网页,但在容器运行后,我无法通过http连接到端口80 我正在运行docker 1.9.9 我采取的步骤如下: 我创建了一个Docker文件: FROM ubuntu:15.10 RUN echo "Europe/London" > /etc/timezone RUN dpkg-reconfigure -f noninteractive tzdata ENV DEBIAN_FRONTEND noninteractive RUN apt-get updat

我正在尝试从nginx加载默认网页,但在容器运行后,我无法通过http连接到端口80

我正在运行docker 1.9.9

我采取的步骤如下:

我创建了一个Docker文件:

FROM ubuntu:15.10

RUN echo "Europe/London" > /etc/timezone
RUN dpkg-reconfigure -f noninteractive tzdata

ENV DEBIAN_FRONTEND noninteractive

RUN apt-get update
RUN apt-get install -y nginx
RUN apt-get install -y supervisor
RUN apt-get update && apt-get -q -y install lsof
RUN apt-get install net-tools
RUN apt-get install psmisc
RUN apt-get -y install curl

ADD supervisor.nginx.conf /etc/supervisor.d/nginx.conf

CMD /usr/bin/supervisord -n

RUN rm -Rf /etc/nginx/conf.d/*
RUN rm /etc/nginx/sites-enabled/default

RUN mkdir /etc/nginx/logs/
RUN touch /etc/nginx/logs/error.log

RUN mkdir /usr/share/nginx/logs/
RUN touch /usr/share/nginx/logs/error.log

ADD ./conf/nginx.conf /etc/nginx/sites-available/default
RUN ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

copy ./dist /usr/share/nginx/html

CMD /usr/bin/supervisord -n
docker文件将下面的nginx配置文件复制到
/etc/nginx/sites available/default
中,并为
/etc/nginx/sites enabled/default
创建指向此文件的符号链接

server {
  root /usr/share/nginx/html;
  index index.html index.htm;

  # redirect server error pages to the static page /50x.html
  #
  error_page 500 502 503 504 /50x.html;
  location = /50x.html {
    root /usr/share/nginx/html;
  }

  location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
    access_log        off;
    log_not_found     off;
    expires           5d;
  }

  # deny access to . files, for security
  #
  location ~ /\. {
     access_log off;
     log_not_found off;
     deny all;
  }
}
然后,我用以下方法构建了图像:

docker build -t dnginx 
我从以下内容开始创建容器:

docker run --name d3 -d -p 80:80 dnginx
然后我找到了ip地址并尝试连接

curl http://172.17.0.2
返回的

curl:(7)连接到172.17.0.2端口80失败:操作超时

我在容器中打开了一个bash shell,然后运行
nginx
,返回:

nginx: [emerg] bind() to 0.0.0.0: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 0.0.0.0: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 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
如果我运行netstat--listen我会得到:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 *:80                    *:*                     LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -
如果我运行netstat-ltnp | grep:80

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 *:80                    *:*                     LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -
我完全不知道发生了什么事


如果我只连接到nginx映像,也会发生同样的情况。

我已经尝试了你的
Dockerfile
,它已经按预期工作了。我所做的唯一更改是删除了与
supervisord
相关的任何内容,并添加了

CMD ["nginx", "-g", "daemon off;"]
Dockerfile
的末尾

当容器启动时,其网络名称空间与主机和其他容器完全隔离,唯一的进程是由ENTRIPOINT或CMD指令及其子进程启动的进程,因此,我认为您在容器中看到的
nginx
进程正是由
supervisord
运行的进程

您确定
172.17.0.2
是docker容器的当前IP吗? 容器IP不稳定,这取决于主机上运行的容器数量及其启动顺序


您使用run选项'-p80:80'在主机上公开http端口,因此您应该能够使用
curl127.0.0.1

在docker主机上访问它。这些天我遇到了同样的问题,但我必须运行多进程,因此删除supervisord对我来说不是一个解决方案

只需将
-g“daemon off;”“
标志添加到supervisor nginx程序命令即可解决此问题。就是

[程序:nginx]
command=/usr/sbin/nginx-g“守护进程关闭”


看起来容器中的所有进程都必须在前台运行,即使由supervisord工具管理

如果在主机操作系统上运行netstat--listen端口80上监听的是什么?我得到:tcp 0:http*:listen这意味着在端口80上监听的是什么…lsof-I:80返回:nginx 1 root 6u IPv4 2392140 0t0 tcp*:http(听)我应该杀死它吗?98:已经在使用意味着有一个进程正在使用这个特定的IP/端口地址。你应该知道哪个进程是,你可以通过
sudo netstat-ltnp | grep:80
。一旦你知道它是哪个进程,如果你对它不感兴趣,你可以杀死它,然后再试一次。这是actu当需要supervisor时,使用al解决方案。谢谢!此解决方案适用于使用supervisor的用户。谢谢!我的收获:当supervisor在后台程序模式下启动nginx时(后台),它启动并进入后台。Supervisor现在认为nginx已死亡并尝试重新启动它。由于nginx已在后台运行,它抱怨端口已被占用。解决方法是告诉nginx在前台运行,以便Supervisor可以跟踪它(对于运行nginx而没有Supervisor的普通docker映像,情况也是如此)-这可以通过本回答中建议的CLI选项以及nginx配置文件来完成。这对我不起作用,我正在使用supervisord来运行命令,我还尝试将nginx端口更改为8080。它给出了相同的错误