頑張らないために頑張る

ゆるく頑張ります

コンテナやイメージを削除してもDockerfileやdocker-compose.ymlの内容が反映されない場合はvolumeを削除する

Posted at — Apr 4, 2021

コンテナをリビルドしても反映されないんだけど

前回に引き続き、今回も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.comhogehoge@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をいじる場合は、データボリュームに重要なデータが格納されていないか一応確認した方がいいかもしれません。

参考

  1. Use volumes
  2. Dockerのイメージ、コンテナおよびボリュームを削除する方法
  3. docker volume rmコマンドの使い方(実例付)
comments powered by Disqus