いろいろ書いていく

やってみたなど

DockerでTomcatその2 ( docker build )

前回の記事で,docker image pullで公式イメージを取ってくる手順を書いた
DockerでTomcatその1 - いろいろ書いていくつもり

今回はdocker buildを使ってみる.
公式のコードそのままではうまくいかないことがあったので,その辺りも書く.

環境

コンテナで立てるアプリはApache Tomcat.
Apache Tomcat - Wikipedia

公式イメージの使用可能なバージョン等はDocker Hubで確認できる
https://hub.docker.com/_/tomcat/
今回は執筆時点におけるlatestバージョンである8.5.35を用いる.

手順

  • Docker HubのDockerfileリンクを辿って,8.5.35のDockerfileをダウンロードする

https://hub.docker.com/_/tomcat/

github.com

  • ファイル名は"Dockerfile"のままにする.(変更してもよいが,その場合は後のbuildコマンドで-fオプションで指定する)
  • Dockerfileのあるディレクトリでターミナルを開く
  • ここでdocker buildすればイメージ完成..のはずなのだが,このままだとうまくいかなかった.
$ docker build -t tomcat:8.5.35 .
 (sniped)
...returned a non-zero code: 2
  • -tオプションによりTAG名"tomcat:8.5.35"でイメージ作成しているが,リストにも中間生成物的なものしか見当たらない
$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
<none>              <none>              b334452e1e39        About a minute ago   447MB
openjdk             8-jre               dd20fb277e3c        3 weeks ago          443MB
  • 実行時のエラーを追ってみると,gpg鍵の検索に失敗した後終了しているっぽい
(sniped)
+ mktemp -d
+ export GNUPGHOME=/tmp/tmp.QmRGq0ytuG
+ gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys XXXXXXXX
gpg: keybox '/tmp/tmp.QmRGq0ytuG/pubring.kbx' created
gpg: keyserver receive failed: Cannot assign requested address
(sniped)

最後のエラー文で検索すると,同じような現象が多数報告されている
Key server down for get.docker.com · Issue #13555 · moby/moby · GitHub

keyserverをpgp.mit.edu や keyserver.ubuntu.comにしてみろとのこと

  • Dockerfileのkeyserverの値を上記のいずれかに変更して保存
                gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \

↓↓↓

                gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
  • 再度buildする前に,中間生成物的なものを削除する(しなくてもよいが,あとでゴミが残るので・・・詳しくは後ほど)
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              b334452e1e39        36 minutes ago      447MB
  • IMAGE ID指定で削除しようとすると,停止中のコンテナで使っていると怒られる
$ docker image rm b334452e1e39
Error response from daemon: conflict: unable to delete b334452e1e39 (must be forced) - image is being used by stopped container 2642a25811d8
  • 中間生成物として作られた不要なコンテナなので,削除する
$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
2642a25811d8        b334452e1e39        "/bin/sh -c 'set -eu…"   36 minutes ago      Exited (2) 36 minutes ago                       objective_engelbart

$ docker container rm 2642a25811d8
2642a25811d8

$ docker image rm b334452e1e39
Deleted: sha256:b334452 ...
 (sniped)

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
  • 綺麗にしたところで,もう一度buildコマンドを実行
$ docker build -t tomcat:8.5.35 .
 (sniped)
Successfully built 5734bc644c71
Successfully tagged tomcat:8.5.35
  • 成功すると指定したタグのイメージが一覧に追加される.
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
tomcat              8.5.35              5734bc644c71        About a minute ago   475MB
openjdk             8-jre               dd20fb277e3c        4 weeks ago          443MB
  • 同じエラーが出た場合は,他のkey serverを試してみるか,コメントアウトするしかない・・・
  • 前回同様,追加されたイメージを用いてコンテナを起動する
$ docker container run -p 80:8080 --name my-tomcat-2 tomcat:8.5.35
 (snip)
XX-Dec-2018 XX:XX:XX.XXX INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 2327 ms
  • コンテナ一覧でも見えるはず
$ docker container ls
  • 最後にブラウザでhttp://localhost/にアクセスし, Tomcat/8.3.35のトップページが表示されることを確認

http://localhost/examples/にあるJavaアプリも動くはず

  • 終わり.
  • コンテナとイメージを(目的は果たしたので)削除
# コンテナ停止
$ docker container stop my-tomcat-2
# コンテナ削除
$ docker container rm my-tomcat-2
$ docker container ls
# イメージ削除
$ docker image rm tomcat:8.5.35
$ docker image ls
  • 他の公式Dockerfileでも上記のkey serverをつかっているのが見受けられたので,同じような現象が起きるかも.

余談

  • docker buildコマンドはDockerfileのRUNなどの処理を1行ずつ実行し,その度に中間イメージおよびコンテナを生成している
  • そのため,上記手順の中で中間生成物を削除しないで継続すると,エラーで落ちたところから再開してくれるので少し速くなる.
  • 楽でいいかなと思ったが,後でイメージを削除する際に中間生成物が残っており,ちょっと微妙だったので先に削除した.