前回に引き続き、今回もDockerまわりのトラブルシューティングです。
Dockerfileやdocker-compose.ymlの内容を更新した場合、基本的にはリビルドして内容をコンテナに反映させます。
docker-compose build --no-cache
docker-compose up -d --build --force-recreate
docker-compose
の場合、上記のようなコマンドを発行するとキャッシュを無視(--no-cache
)してリビルドしたり、ymlの内容に変更がなくてもイメージの強制再作成(--force-recreate
)から実行してくれます。
ところが、場合によってはこれだけでは反映されないことがあります。
version: '3'
services:
postgres:
image: postgres
container_name: postgres_hoge
restart: always
environment:
TZ: "Asia/Tokyo"
POSTGRES_USER: admin
POSTGRES_PASSWORD: admin
POSTGRES_DB: hoge
ports:
- 30000:5432
volumes:
- postgres:/var/lib/postgresql/data
- ./postgres/initdb:/docker-entrypoint-initdb.d
pgadmin:
image: dpage/pgadmin4
container_name: pgadmin_hoge
restart: always
ports:
- 30001:80
environment:
PGADMIN_DEFAULT_EMAIL: admin@example.com
PGADMIN_DEFAULT_PASSWORD: admin
volumes:
- pgadmin:/var/lib/pgadmin
depends_on:
- postgres
volumes:
postgres:
pgadmin:
上記は、PostgreSQLとpgAdminのコンテナを立ち上げるdocker-compose.ymlファイルです。このファイルのうち、environment
の部分を変更して、コンテナをリビルドしたのですが変更が反映されませんでした。
environment:
PGADMIN_DEFAULT_EMAIL: hogehoge@example.com
PGADMIN_DEFAULT_PASSWORD: hogehoge
PGADMIN_DEFAULT_EMAIL
は、pgAdminにログインするメールアドレスを記述する箇所。PGADMIN_DEFAULT_PASSWORD
は、その名の通りパスワードを記述する箇所。これらについて、admin@example.com
をhogehoge@example.com
に変更するなどして、docker-compopse.ymlを更新しましました。
本来であれば、単純にコンテナをリビルドして新しいメールアドレスとパスワードでログインすればいいと思うのですが、なぜか反映されませんでした。つまりdocker-compose.ymlの変更前のメールアドレスやパスワードでないとpgAdminにログインできないわけです。ワケわからん。
environment
は、コンテナ内で利用する単なる環境変数です。ということは、ここではpgAdminのコンテナを立ち上げる際の初期設定にしか利用していないはず。そのわりに、docker-compose down --rmi all
などでイメージの削除を行ってから、再度pull
しても駄目。そもそも、本来はイメージの再取得は必要なくて、docker-compose up --build -d
とかでいいと思うのですが、どちらにせよなぜか反映されません。許さん。
原因はデータボリュームにゴミが残っていたこと。
volumeの内容は、コンテナをリビルドしたりイメージを削除するだけでは消えません。「volumeの内容を削除する」コマンドを発行しないかぎり残り続けます。今回は、ログインに必要なアカウント情報がvolume側に残存していたため、いくらコンテナをリビルドして新しい環境変数にしてもイメージを再取得しても、それらは残存し続けるvolumeには関係ないため反映されなかったわけです。マジか。
ゴミが残ってるなら、捨てればいいわけです。やったるぞー。
docker volume ls
docker volume rm hogehoge
docker volume ls
で、volumeの一覧が参照できます。このうち削除したいvolumeをdocker volume rm hogehoge
と指定します。これでvolumeが削除可能です。
ちなみに、volume rm
のコマンドは削除対象のボリュームがコンテナで利用されているときは削除できません。
# docker volume rm hogehoge
Error response from daemon: remove hogehoge: volume is in use - [xxx]
利用中のボリュームを削除しようとすると上記のようなエラーメッセージが表示されます。そのため、削除対象のボリュームを利用しているコンテナを落とすなどして未使用の状態にしてから、再度volume rm
を実行します。なお、-f
オプションをつけることで強制的にボリュームを削除できるのですが、ボリュームが利用中である場合はこのオプションをつけても削除できません。いいんだか悪いんだか・・・。
何はともあれ、これで残存していたデータボリュームを削除しコンテナをリビルドしたところ、無事に新しいアカウント情報でログインできました。
やった。
「docker volume rm hogehoge
」を実行するということは、そのコンテナで利用していたデータボリュームをまるっと削除することになるので、重要なデータは事前に別コンテナなどに退避させる必要があります。
コンテナを作ったばっかりならいいかもしれませんが、ある程度運用しているようなコンテナについてvolumeをいじる場合は、データボリュームに重要なデータが格納されていないか一応確認した方がいいかもしれません。