docker-compose runでport mappingされず小一時間悩む

開発部のTです。

docker-composeを使っていたらタイトル通りの内容で悩みました。結論としてはドキュメントをよく読んで使おうって話なだけなのですが。。。

経緯

以下の様なdocker-compose.ymlを作って、dockerコンテナ上でNode.jsプロジェクトのインストール、起動すると、コンテナ内で起動しているサーバーにアクセスできずに悩みました。。。

# docker-compose.yml
version: '2'
services:
  graphql:
    image: node:alpine
    volumes:
      - .:/usr/src
    ports:
      - "3000:3000"
    privileged: true
# Node.jsプロジェクトをcheckout
git clone https://github.com/kadirahq/graphql-blog-schema.git
cd graphql-blog-schema
git checkout build-schema

# 作成したdocker-composeでインストール、起動
docker-compose run --rm graphql npm install --prefix=/usr/src
docker-compose run --rm graphql npm start --prefix=/usr/src

# 別ターミナルでコンテナ内のサーバーにアクセスするとConnection refused
curl http://localhost:3000
curl: (7) Failed to connect to localhost port 3000: Connection refused

原因と解決

調べてみると(というかリファレンスに書いてありました)、docker-compose run --service-portsとしないと、docker-compose.ymlファイルのport mappingが無視されるようです。以下引用です。

The second difference is the docker-compose run command does not create any of the ports specified in the service configuration. This prevents the port collisions with already open ports. If you do want the service’s ports created and mapped to the host, specify the --service-ports flag:

docker-compose run --service-portsを指定して無事動きました。

docker-compose run --rm --service-ports graphql npm start --prefix=/usr/src

# curlでコンテナ内のサーバーにアクセスできる
curl http://localhost:3000
<html>
  <head>
    <title>Sample App</title>
    <link rel="stylesheet" type="text/css" href="/static/graphiql.css">
  </head>
  <body>
    <div id='root'>
    </div>
    <script src="/static/bundle.js"></script>
  </body>
</html>

以上、ドキュメントをよく読んで使おうという話でした。