Подтвердить что ты не робот

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

Я пытаюсь загрузить веб-страницу по умолчанию из nginx, но я не могу подключиться к порту 80 через http после запуска контейнера.

Я запускаю докер 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 в контейнере и запустил 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

Если я запустил netstat -ltnp | grep :80, я получаю:

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -

Я понятия не имею, что происходит.

То же самое происходит, если я подключаюсь только к изображению nginx.

4b9b3361

Ответ 1

Я пробовал ваш Dockerfile, и он работал так, как ожидалось. Единственные изменения, которые я сделал, - удалить что-либо, относящееся к supervisord, и добавить

CMD ["nginx", "-g", "daemon off;"]

в конце Dockerfile.

Когда контейнер запускается, его пространство имен сетей полностью изолировано от хоста и других контейнеров, и единственными процессами являются тот, который запускается директивами ENTRIPOINT или CMD и его дочерними элементами, поэтому я считаю, что процесс nginx что вы видите, что запуск в контейнере - это тот, который выполняется supervisord.

Вы уверены, что 172.17.0.2 - текущий IP-адрес контейнера докеров? IP-адрес контейнера нестабилен и зависит от того, сколько контейнеров запущено на вашем хосте и порядок их запуска.

Вы показываете порт http на хосте с параметром запуска "-p 80:80", поэтому вы должны иметь доступ к нему на хосте docker с помощью curl 127.0.0.1.

Ответ 2

У меня такая же проблема в наши дни, но я должен запускать многопроцессорный процесс, поэтому удаление supervisord не является решением для меня.

Просто добавьте флаг -g "daemon off;" в команду диспетчера nginx, чтобы решить эту проблему. Это

[program:nginx] command=/usr/sbin/nginx -g "daemon off;"

Кажется, что весь процесс в контейнере должен выполняться на переднем плане, даже управляемый средствами супервизора