Dockerイメージ内のコードを直接編集する方法
programmingはじめに
急ぎの修正対応のために本番環境で動いているDockerコンテナ内のコードを編集したかったのですが、訳あってコードを修正してDockerイメージのビルドをし直すのが大変だったため、緊急的、一時的に、既にあるイメージ内のコードを直接変更して対応するということをしたので、そのやり方を備忘録として残しておきます。
方法
基本的な流れとしては docker exec
などでコンテナに入りコードを編集してから、 docker commit
コマンドを使って新しくイメージを作成します。
大抵の場合Dockerイメージには entrypoint
が設定されているため、 docker run
では vim
や sh
などを開いてコードを編集することはできないと思います。
そのため僕は docker exec
を利用しています。
まずはバックグラウンドで docker run
します。
今回編集したいDockerイメージを DOCKER_IMAGE_TO_EDIT:v1.0
とし、コンテナには edit-code-in-image
と名前をつけておきます。
docker run -d --name edit-code-in-image DOCKER_IMAGE_TO_EDIT:v1.0
次に docker exec
で sh
などを起動します。
docker exec -it edit-code-in-image sh
もしコンテナで既にVimやEmacsなどのエディタが利用できればそれを使ったり、なければ入れるか sed
コマンドなどでコードを直接編集します。
編集し終わったら exit
します。
vim XXX.py
sed ...
# 編集し終わったら
exit
これで現在動いているコンテナ edit-code-in-image
はコードが編集された状態になっています。
ここで docker commit
コマンドを利用してこのコンテナをもとに新たなイメージ DOCKER_IMAGE_TO_EDIT:v1.1
を作成します。
以下のコマンドで可能です。
docker commit edit-code-in-image DOCKER_IMAGE_TO_EDIT:v1.1
これにて完了です!
別解
docker run -d
からの docker exec
の流れをしなくても、 docker run --entrypoint ''
などで entrypoint
を上書きすれば自由なコマンドを実行できるので一気にコード編集まで可能です。
ですが、後に docker commit
したときにDockerイメージの entrypoint
も ''
に上書きされてしまいます。
この場合は、 docker commit
の --change
オプションで entrypoint
を上書きしつつイメージを作成するという方法で対処できます。(公式マニュアル)
docker commit --change='ENTRYPOINT ["/bin/entrypoint.sh"]' edit-code-in-image DOCKER_IMAGE_TO_EDIT:v1.1
(ENTRYPOINT ["/bin/entrypoint.sh"]
の部分はもともとイメージに設定されていた entrypoint
に読み替えてください。)
おわりに
公式のマニュアルに
Generally, it is better to use Dockerfiles to manage your images in a documented and maintainable way. https://docs.docker.com/engine/reference/commandline/commit/
とあるように、今回のように直接イメージを編集してコミットするという方法は推奨されている方法では無いと思います。
あくまでも緊急用ですね。