Dockerイメージのビルド中にExitedしたコンテナに入る方法

  • 2015-09-29 (Tue)
  • namikingsoft

長めのansible-playbookをRUNしてる途中でエラーが出た時に役立ったので、まとめておく。

どういう時に使う?

例えば、docker build途中によくわからない理由でエラー落ちした時、 直前状態のコンテナに入ってデバッグしたい事がある。

ビルドに失敗した後、docker ps -aすると、 Exitedしたビルド作業用のコンテナが消されずに残っているので、 このコンテナの中にシェルで入れれば、エラーの詳細を調べられる。

コンテナだけでなく、直近のイメージも残っているが、 Dockerコマンド単位でコミットされるため、 数珠つなぎのRUNとか、ansibleやchefなどのプロビジョニングツールを併用した時に、 大幅にロールバックしていることがある。

ビルド途中にエラーで落ちるDockerfileの例

FROM busybox

RUN touch /step1
RUN touch /step2 && errcmd && touch /step3
RUN touch /step4

errcmdという架空のコマンドで、わざとエラーを起こしてみる。

docker build の途中で落ちる

$ docker build . -t tset

Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM busybox
latest: Pulling from library/busybox
cfa753dfea5e: Pull complete
d7057cb02084: Pull complete
library/busybox:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:16a2a52884c2a9481ed267c2d46483eac7693b813a63132368ab098a71303f8a
Status: Downloaded newer image for busybox:latest
 ---> d7057cb02084
Step 1 : RUN touch /step1
 ---> Running in f1ca76c9072d
 ---> ef649ff08895
Removing intermediate container f1ca76c9072d
Step 2 : RUN touch /step2 && errcmd && touch /step3
 ---> Running in d117aa39bacd
/bin/sh: errcmd: not found
The command '/bin/sh -c touch /step2 && errcmd && touch /step3' returned a non-zero code: 127

途中にある---> Running in d117aa39bacdの次で止まっている。

$ docker ps -q --filter status=exited

d117aa39bacd

d117aa39bacdコンテナが消されずに残っている。
これが直近の作業コンテナでtouch /step2までのコマンドを実行されているはず。

Exitedなコンテナには入れない?

生きているコンテナであれば、docker exec+シェルでコンテナの中に入れるが、 Exitedしていると、以下の様なエラーが出る。

$ docker exec -it d117aa39bacd sh

Error response from daemon: Container d117aa39bacd is not running

解決手順

1.Exitedコンテナを一旦コミットして、イメージ化する

死んでいるコンテナをコミットするという機会があまりなかったので、 ちょっと戸惑ったが、以下のコマンドでイメージ化できる。

$ docker commit -t exited d117aa39bacd

2.インタラクティブ+TTYモードで実行する

そのままdocker runしても速攻で死ぬので、-it bashをつけて実行。

$ docker run --rm -it exited sh
# ls / | grep step
step1
step2

ちょっとまどろっこいが、一応エラーコマンド直前の状態のコンテナに入れた。 同じRUNコマンドの中でエラーが起きても、touch /step2までは実行されているようだ。

comments powered by Disqus

この記事について

書いた人
Written by

namikingsoft

何かを残して逝きたい
フロントエンドエンジニア