29
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

docker-composeでマウント先を間違えると大変なことになる。

Last updated at Posted at 2018-04-04

とあるシステムをDocker-Composeで構築し、運用していました。
サンプルとして、gitbucketをpostgresqlで運用したものを上げます。
中身はこんな感じです。

version: '2'
volumes:
  gitbucket_postgres_data:
    driver: local
  gitbucket_data:
    driver: local
services:
  # gitbucket postgres
  gitbucket_postgres:
    restart: always
    image: postgres:9.6
    volumes:
      - gitbucket_postgres_data:/var/lib/postgresql
    environment:
      POSTGRES_PASSWORD: passwd
      POSTGRES_USER: gitbucket
      POSTGRES_DB: gitbucket
      POSTGRES_INITDB_ARGS: --encoding=UTF-8 --locale=C
  # gitbucket
  gitbucket:
    restart: always
    image: f99aq8ove/gitbucket
    depends_on:
      - gitbucket_postgres
    environment:
      GITBUCKET_DB_URL: "jdbc:postgresql://gitbucket_postgres/gitbucket"
      GITBUCKET_DB_USER: gitbucket
      GITBUCKET_DB_PASSWORD: passwd
      GITBUCKET_OPTS: --prefix=/
      VIRTUAL_HOST: gitbucket.example.com
      VIRTUAL_PORT: 8080
    volumes:
      - gitbucket_data:/gitbucket
    ports:
      - "29418:29418"
networks:
  default:
    external:
      name: common_link

ある日、そろそろバージョンアップするかなと、

docker-compose pull && docker-compose down && docker-compose up -d

とし、コンテナを作り替えたところ・・・
データベースが吹っ飛びました
おかしいと思い、

docker exec -it sample_gitbucket_postgres_1 /bin/bash

としたところ・・・

root@62656ba04baa:/# ls -lah /var/lib/postgresql/data/
total 128K
drwx------ 19 postgres postgres 4.0K Apr  4 11:29 .
drwxr-xr-x  3 postgres postgres 4.0K Apr  4 11:29 ..
drwx------  6 postgres postgres 4.0K Apr  4 11:29 base
drwx------  2 postgres postgres 4.0K Apr  4 11:31 global
drwx------  2 postgres postgres 4.0K Apr  4 11:29 pg_clog
以下略

ファイルはあります。しかし妙です。容量があからさまに少ないです。
ではコンテナがどうなっているか見てみます。

docker inspect sample_gitbucket_postgres_1 
・・・・・
        "Mounts": [
            {
                "Name": "sample_gitbucket_postgres_data",
                "Source": "/var/lib/docker/volumes/sample_gitbucket_postgres_data/_data",
                "Destination": "/var/lib/postgresql",
                "Driver": "local",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Name": "1b9b7b263e28161c2484b5a3becff652045aba3ea093cf54731c30aecb549a56",
                "Source": "/var/lib/docker/volumes/1b9b7b263e28161c2484b5a3becff652045aba3ea093cf54731c30aecb549a56/_data",
                "Destination": "/var/lib/postgresql/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
・・・・・

うん???何故かマウントされている2つデータコンテナがあります。
うち1つはどう見ても自動生成されているようです。
dockerはデータボリュームを明示的にマウントしない限りデータは永続化されないはずですが・・
作成したデータコンテナの中身を見てみます。

root@ubuntu-docker:~# ls -lah /var/lib/docker/volumes/sample_gitbucket_postgres_data/_data/data/
合計 8.0K
drwxrwxrwx 2 999 docker 4.0K  3月 15 01:56 .
drwxr-xr-x 3 999 docker 4.0K  4月  4 20:29 ..

・・・・・・(滝汗

オチ

オチとしては、マウント先ディレクトリを間違えて、/var/lib/postgresql/dataとすべきところを/var/lib/postgresqlとしてしまい、たまたま普段の運用でdocker-compose stop/startだったので、作成されたボリュームとコンテナが生きていていままで動いていただけで、データコンテナの中身は空っぽでした
その結果、コンテナ吹っ飛ばした所再度新たに作成されたデータコンテナにてデータが初期化されてしまいました。

復旧へ・・

気づいたのが早かったのと、幸いデータコンテは吹っ飛ばしていなかったので、サーバ上にあるすべてのデータボリュームに対しgrepをかけて、コンテナを作り替える直前あたりのタイムスタンプがあった、PostgreSQLデータコンテナを特定。
docker-composeを正しいマウントポイントに修正後、そのまま動かすと既にデータコンテナがあるのでエラーになるので、データコンテナをdocker volume rmで削除。docker-composeで再作成した後、今度は中身が正しくできていること、変なマウントがないことをdocker inspectで確認をし、いったん終了させた後、データコンテナの中身をすべて、更新前ボリュームの中身でコピーし、無事復旧できました。

参考

元のPostgreSQL公式コンテナのDockerfileにはこうあります。

VOLUME /var/lib/postgresql/data

Dockerfile内でVOLUMEで述したディレクトリは、外部とのマウントポイントとなります。
それ以外のディレクトリはマウントできないわけではないのですが、特にエラーもなくこのように無視されることもあります
ドキュメントによると、

VOLUME 命令は指定した名前でマウントポイントを作成し、他のホストやコンテナから外部マウント可能なボリュームにします。
docker run コマンドは、ベース・イメージから指定した場所に、データを保存する場所として新規作成したボリュームを初期化します。

つまり、明示的にマウントしないものは、docker runした時点で自動的にボリュームが作成され、初期化されるようです。
ただし、このボリュームは明示的に指示していないのでランダムな文字列で作成され、コンテナ再作成時に別名で作られます。以前のは明示的に消さない限りは残るようですが、当時のコンテナを消してしまっていると、docker inspectで調べることもできず、特定作業は困難となります・・

最後に

ちゃんと作成したデータボリュームにデータが格納されているか確認しよう。
面倒でも、バックアップを取りましょう。
自分はコンテナはどうせ作り替えだし、データボリュームは消えないからと、どうせなら全部きれいにしてしまえとバックアップ取らずdocker image pruneしたりしたので、頭の中もまっさらになりました(涙

追記

Dockerを長く運用していると不要なイメージがたまって容量を食うので、ググると最近は

docker system prune 

でOK!みたいなのが結構引っかかるのですが、
これは停止中のコンテナ、関連リソースすべて吹っ飛ばします

停止中=不要とはかならずしもならないと思いますので、盲目的にググってコピペして実行しないようにしましょう。

29
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?