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
$ 5909e87302ab7520884060437e19ef543ffafc568419c04630abffe6ff731f70
コンテナーが実行されており、ポートがマップされていることを確認します。
$ 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
そして、コンテナのコマンドラインに次のように入力します:
root@5909e87302ab:/# curl http://localhost:1337
Hello World
Mon Feb 15 2016 16:28:38 GMT+0000 (UTC)
良さそうですか?
問題
ホストで同じcurlコマンドを実行する(またはブラウザーで http:// localhost:1337 に移動する)とき、何も表示されません。
コンテナとホスト間のポートマッピングが機能しない理由は何ですか?
私がすでに試したこと:
--expose 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, '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');
127.0.0.1ではなく0.0.0.0に注意してください。
EXPOSE 1337をdockerファイルに追加する
EXPOSE
は 必須 そのポートを他のコンテナに「公開」したい場合。
BMitch コメントとして:
Expose
は、ポートを公開したり、共有ドッカーネットワーク経由でコンテナーをコンテナーに接続したりするために必要ではありません。
これは、-P
ですべてのポートを公開し、イメージ/コンテナを検査するためのメタデータです。
そう:
--expose 1337
フラグを使用して実行する
正確ではありません: docker run it with -p 1337:1337
次のいずれかが必要です。
EXPOSE
ディレクティブを使用してイメージをビルドします(-P
で使用)-p 1337:1337
で公開されているポートで実行しますテストcurl http://localhost:1337
は、コンテナ内から実行されました(EXPOSE
または発行は不要です)。
Linuxホストから動作させるには、EXPOSE+-P
or-p 1337:1337
が必要です。
どちらか。
単独で公開することは、意図を文書化するのに適していますが、単独では何もしません。
例えば:
その図では、8080が公開され、Linuxホスト8888に公開されています。
そのLinuxホストが実際のホストではない場合、同じポートを実際のホストに早送りする必要があります。 「 ブラウザからdockerコンテナで実行されている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
( ブロードキャストアドレスまたはゼロネットワーク )。