Докеры не открыты
Я установил простой сервер узлов в Docker.
Dockerfile
FROM node:latest
RUN apt-get -y update
ADD example.js .
EXPOSE 1337
CMD node example.js
example.js
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n'+new Date);
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
Теперь создадим образ
$ docker build -t node_server.
Теперь запустите контейнер
$ docker run -p 1337: 1337 -d node_server
Долл. США
Убедитесь, что контейнер запущен и отображаются порты:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5909e87302ab node_server "/bin/sh -c 'node exa" 7 seconds ago Up 6 seconds 0.0.0.0:1337->1337/tcp grave_goldberg
Теперь добавьте в контейнер и убедитесь, что сервер запущен внутри:
$ docker exec -it 5909e87302ab7520884060437e19ef543ffafc568419c04630abffe6ff731f70/bin/bash
И в командной строке контейнера введите:
[email protected]:/# curl http://localhost:1337
Hello World
Mon Feb 15 2016 16:28:38 GMT+0000 (UTC)
Выглядит хорошо?
Проблема
Когда я выполняю ту же команду curl на хосте (или перемещаюсь с моим браузером на http://localhost: 1337), я ничего не вижу.
Любая идея, почему сопоставление портов между контейнером и хостом не работает?
Вещи, которые я уже пробовал:
Ответы
Ответ 1
Ваши порты отображаются правильно, но ваш сервер прослушивает соединения на 127.0.0.1
внутри вашего контейнера:
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n'+new Date);
}).listen(1337, '127.0.0.1');
Вам нужно запустить сервер следующим образом:
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n'+new Date);
}).listen(1337, '0.0.0.0');
Обратите внимание на 0.0.0.0 вместо 127.0.0.1.
Ответ 2
Добавление EXPOSE 1337 в файл докеров
EXPOSE
обязательное если вы хотите "выставить" этот порт в другие контейнеры.
Как комментирует BMitch:
Expose
не требуется для публикации порта или для подключения контейнера к контейнеру через общую сеть докеров.
Это метаданные для публикации всех портов с помощью -P
и проверки изображения/контейнера.
Так:
Запуск с --expose 1337
Не совсем: вам нужно докер запустить его с -P 1337:1337
Вам нужно:
- постройте изображение с директивой
EXPOSE
в нем (используется -P
) - или запустить его с портом, опубликованным на хосте
-P 1337:1337
Тестовый curl http://localhost:1337
было сделано из контейнера (нет EXPOSE
или публикации).
Если вы хотите, чтобы он работал с хостом Linux, вам нужно EXPOSE+-P
или вам нужно -P 1337:1337
.
Или.
Заявить, что он разоблачен в одиночку, хорошо для документирования намерения, но не делает ничего в одиночку.
Например:
На этой фигуре 8080 EXPOSE'd, опубликованной на хосте Linux 8888.
И если этот хост Linux не является фактическим хостом, тот же порт должен быть быстро перенесен на фактический хост. См. " Как получить доступ к tomcat в контейнере докера из браузера? ".
Если localhost не работает с хостом Linux, попробуйте его IP-адрес:
CID=$(docker run -p 1337:1337 -d node_server)
CIP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' ${CID})
curl http://${CIP}:1337
Или, как упоминалось выше, заставьте ваш сервер прослушивать соединения, исходящие от любого IP: 0.0.0.0
который является широковещательным адресом или нулевой сетью.