retlat's blog

Dockerのポートバインドで使用するホストIPを指定する

普段はDockerを使った開発環境で、ホストとコンテナのポートをバインドして他の端末から繋いでいる
公衆無線LANの環境で作業する必要が出てきて、これ他の接続してるユーザーから見えてダメじゃんと思ったのでIPを縛るように変えてみる

とりあえず普段使う感じで確認
0.0.0.0 にバインドされているのがわかる

$ docker run --rm -d -p 80:80 nginx:alpine
$ docker ps --format "table {{.Image}}\t{{.Ports}}"
IMAGE               PORTS
nginx:alpine        0.0.0.0:80->80/tcp

リファレンスに書いてある通りホストのIPを指定する
これだとホストの外からはアクセスできない

$ docker run --rm -d -p 80:80 nginx:alpine
$ docker ps --format "table {{.Image}}\t{{.Ports}}"
IMAGE               PORTS
nginx:alpine        127.0.0.1:80->80/tcp

Docker Composeでも同じようにホストのIPを指定できるので、場所に応じて適切に使い分けたい

LighthouseをDockerで動かす

Lighthouseでサイトの評価は見たかったものの, なんとなくChromeを端末にインストールしたくなかったのでコマンドラインで使ってみた
せっかくなのでコンテナとして動かしてみた
環境は

  • macOS 10.15
  • Docker Desktop 2.1.0.4

実践

LighthouseのCLIはnpmで提供されているので, とりあえず以下のDockerfileを使って

FROM node:10.17.0

RUN npm install -g lighthouse

こんなDocker Composeの構成にして

version: '3'
services:
  nginx:
    image: nginx:1.17.5
  lighthouse:
    build: ./
    tty: yes

使ってみる

$ docker-compose up -d
$ docker-compose exec lighthouse lighthouse http://nginx/
~~~ 略 ~~~
Runtime error encountered: The environment variable CHROME_PATH must be set to executable of a build of Chromium version 54.0 or later.
~~~ 略 ~~~

実行にはChromeが必要だったので, ChromiumをインストールするようにDockerfileを修正し

- RUN npm install -g lighthouse
+ RUN apt-get update && \
+     apt-get install -y chromium && \
+     npm install -g lighthouse

リトライ

$ docker-compose down
$ docker rmi ${ディレクトリ名}_lighthouse:latest
$ docker-compose up -d
$ docker-compose exec lighthouse lighthouse http://nginx/
~~~ 略 ~~~
  ChromeLauncher Waiting for browser....................................................................................................... +503ms
  ChromeLauncher:error connect ECONNREFUSED 127.0.0.1:34953 +1ms
  ChromeLauncher:error Logging contents of /tmp/lighthouse.luZObZw/chrome-err.log +0ms
  ChromeLauncher:error [23:23:1027/054400.061948:ERROR:zygote_host_impl_linux.cc(89)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.
  ChromeLauncher:error  +0ms

Chromeをrootで使う場合のオプション不足とエラーに出ているので追加してリトライ
ついでにGUIで起動しようとして失敗していると思ったのでheadlessのフラグも追加

$ docker-compose exec lighthouse lighthouse --chrome-flags="--no-sandbox --headless" http://nginx/
~~~ 略 ~~~
  ChromeLauncher Waiting for browser.....✓ +3ms
  config:warn IFrameElements gatherer requested, however no audit requires it. +171ms
  config:warn MainDocumentContent gatherer requested, however no audit requires it. +1ms
  status Connecting to browser +10ms
  status Resetting state with about:blank +17ms
  status Benchmarking machine +55ms
  status Initializing… +512ms
  status Resetting state with about:blank +44ms
  status Setting up network for the pass trace +15ms
  status Cleaning browser cache +4ms
  status Beginning devtoolsLog and trace +10ms
  method <= browser ERR:error Tracing.start  +2ms
  status Disconnecting from browser... +2ms
  ChromeLauncher Killing Chrome instance 22 +1ms
Runtime error encountered: Protocol error (Tracing.start): 'Tracing.start' wasn't found
Error: Protocol error (Tracing.start): 'Tracing.start' wasn't found
~~~ 略 ~~~

Chromeが起動して実行できたけどエラーが出る
検索してみるとDebianの問題とのこと
Node.jsのコンテナイメージがDebianベースなので, Ubuntuベースにした以下のDockerfileに切り替えて

FROM ubuntu:bionic-20191010

RUN apt-get update && \
    apt-get install -y curl ca-certificates && \
    curl -sL https://deb.nodesource.com/setup_10.x | bash - && \
    apt-get install -y nodejs chromium-browser && \
    npm install -g lighthouse

再チャレンジ

$ docker-compose down
$ docker rmi ${ディレクトリ名}_lighthouse:latest
$ docker-compose up -d
$ docker-compose exec lighthouse lighthouse --chrome-flags="--no-sandbox --headless" http://nginx/
~~~ 略 ~~~
  status Generating results... +1ms
  Printer html output written to /nginx_2019-10-28_20-00-00.report.html +121ms
  CLI Protip: Run lighthouse with `--view` to immediately open the HTML report in your browser +0ms
  ChromeLauncher Killing Chrome instance 32 +0ms

正常終了したので結果のHTMLをコンテナから回収して見てみるとちゃんと評価できていた

$ docker-compose exec lighthouse cat /nginx_2019-10-28_20-00-00.report.html > ./report.html

感想

雑にDockerfileを書いた割にNode.jsのイメージよりコンテナが小さかったのは意外