LoginSignup
10
7

More than 5 years have passed since last update.

PostgreSQLをデータごとDockerコンテナ化する

Posted at

Dockerの正しい使い方ではないのでしょうが、開発環境では便利なシーンがありそうな「DBをデータごとまるっとコンテナ化する」アイデアを紹介します。

背景

  • 機能開発と不具合修正を並行するためにDBの現行バージョンと次期バージョンを何度も切り替えたり、マイグレーションツールの検証のために何回もDBをクリーンな状態に戻したり、といったケースで可能な限り高速にDBをある時点の状態に切り替えたい
  • DBの環境構築手順が十分に自動化されていないようなプロジェクトであっても、一度がんばって構築すれば、その時点のDBをスナップショットとしてあとで何度でも使いまわせるようにしたい

課題

  • 一見すると、PostgreSQLの 公式Dockerイメージ を使ってDB構築し、気に入った状態になったら再利用できるよう docker commit でイメージ化しておけばよさそうです。しかし、実際にはDBのデータ領域 /var/lib/postgresql/dataVOLUME 指定されており、イメージ化の対象からは除外されてしまいます(=再度 docker run したときにDBは初期状態に戻ってしまう)

解決策

VOLUME 指定のないPostgreSQLイメージからコンテナを起動することで、DBのデータ領域も含めてある時点のスナップショットを完全に丸ごとDockerイメージ化できるようにします。

  1. PostgreSQL公式イメージの Dockerfile を改変して、VOLUME 指定を除外する

    $ git clone https://github.com/docker-library/postgres
    $ cd ./postgres/9.6/
    $ vi Dockerfile
    $ git diff
    
    @@ -131,7 +131,7 @@ RUN mkdir -p /var/run/postgresql && chown -R postgres:postgres /var/run/postgres
     ENV PATH $PATH:/usr/lib/postgresql/$PG_MAJOR/bin
     ENV PGDATA /var/lib/postgresql/data
     RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" # this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values)
    -VOLUME /var/lib/postgresql/data
    +#VOLUME /var/lib/postgresql/data
    
     COPY docker-entrypoint.sh /usr/local/bin/
     RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat
    
  2. Dockerイメージをビルドする

    $ docker build -t postgres-embed:9.6 .
    
  3. 改変したDockerイメージからDBを起動する

    $ docker run -d --rm -p 5432:5432 —-name=temp-db postgres-embed:9.6
    
  4. DBを初期セットアップする

    • マイグレーションツールで自動構築するなり、SQLを1つずつ実行して手動構築するなりお任せ
  5. 新しいDockerイメージとしてDBの状態を保存する

    $ docker commit temp-db my-awesome-db:1.0
    $ docker images my-awesome-db
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    my-awesome-db       1.0                 55f54dadb483        5 seconds ago       273MB
    
  6. イメージ作成用の実行中コンテナを停止する

    $ docker stop temp-db
    
  7. 作成したDockerイメージから爆速でDBを起動する(必要になるたび)

    $ docker run -d --rm -p 5432:5432 --name=awesome-db my-awesome-db:1.0
    

まとめ

VOLUME 指定をもたないPostgreSQLイメージからコンテナを起動することで、コンテナ起動中にDBに発生したデータ修正も含めて丸ごと docker commit でDockerイメージ化するアイデアを紹介しました。コンテナに状態をもたせないという定石からは外れてしまうものの、VirtualBoxなどのVMで実現した場合よりも圧倒的に速く、頻繁にDBを構築し直さなければならない現場では役に立つかもしれません。

10
7
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
10
7