Docker Composeチュートリアル: herokuのPostgresをローカルにさくっとコピーする

Docker使ってますか? ファイルベース(Dockerfileやdocker-compose.yml)で環境を構成できるので、ミニマム&シンプルで重宝してます。 本稿では主にDocker Composeで手軽に開発環境をつくるための手順を書きたいと思います。

この記事でやること

  • Docker Hubからほしい環境を探す
  • PostgresのDB環境をDockerにコピーする

この記事でやらないこと

  • Docker/Docker Composeのインストール

既出の記事が多いため、あえてこの記事では書きません。 一応公式のリンクを貼っておきます。

https://docs.docker.com/install/#supported-platforms

環境

筆者はmacOS High Sierra 10.13.4で動作を確認しています。 Dockerのインストールできる環境であれば基本問題ないはずですが、Windows環境の場合Postgresコンテナのボリュームを永続化できないissueがあるようです。


下準備

Heroku上のPostgresをローカルへ

DockerコンテナへコピーするPostgresのDBデータを用意します。 今回はHeroku上にあるPostgresからDBデータをダンプして使います。

PostgresからDBデータをダンプ

herokuコマンドのインストールは割愛します。 PostgresのHerokuアプリ名はhoge-appとします。

これでダンプデータをdb.dumpに保存できました。楽ちんですね。

Dockerの準備

Dockerで環境を構築する際は大まかに以下の流れで作成しています。

  1. Docker Hubでほしいイメージを探す
  2. docker-compose.ymlに設定を書き込む

順にみていきます。

Docker Hub

Dockerのイメージは主にDocker Hubで公開されています。

https://hub.docker.com

ログインしないと各イメージを見ることができないので、アカウントを取得しておいてください。

ほしいイメージを探す

Docker Hubのページでログイン済なら、かわいいクジラのアイコンの横の検索窓に、「postgres」と入力してEnterを押します。

DockerHub検索窓

ほしいイメージを見つける

Postgresのイメージが見つかりました。

https://hub.docker.com/_/postgres/

postgresの検索結果 「official」と書いてあれば、Docker公式のイメージです。業務で使うのであればこの表示があるものを選ぶのが無難かと思います1

必要な設定をDocker Composeに記述する

押さえておくべき項目は下記のとおりです。

  • タグ
  • 環境変数
  • volume

順に見ていきます。

タグ

タグはイメージのバージョンやOSごとに分けられたラベルと考えるとわかりやすいです。

postgresイメージのタグ

officialイメージであれば上のように、利用できるイメージタグのリストが記載されています。ほとんどが利用できるアプリのバージョンに対応した書き方なので、直感的に理解できると思います。

alpineがついているタグはAlpine Linuxをベースに作られており、一言でいうとイメージサイズが非常に小さいです。ダウンロードやコンテナ起動がスマートになるので、OSにこだわらなければこちらの利用をおすすめします2

環境変数

アプリケーションの基本設定まわりは環境変数で与えることが多いです3

Postgresイメージ環境変数

環境変数の用途には大まかに3つのケースがあります。

  1. 設定自体が必須
  2. 設定すると設定値を上書きする
  3. オプションで設定を付け加える

設定必須の環境変数を省略してコンテナを起動した場合エラー終了します4。環境変数自体を必須とするイメージはあまりありませんが、複数あるうちのいずれかの環境変数が必須になるケースもあります5

今回のpostgresのイメージのドキュメントを読み解くと、必須の環境変数はないようです。一応メインとなりそうな環境変数を下記にピックアップしました。

  • POSTGRES_USER
    • DBユーザ名を設定します。指定しない場合はpostgresになります。
  • POSTGRES_PASSWORD
    • DBユーザのパスワードを設定します。設定しない場合はPOSTGRES_USERの値が使われます。
  • POSTGRES_DB
    • コンテナ起動時に作成するDB名を指定します。設定しない場合はPOSTGRES_USERの値が使われます。

つまり上記環境変数を何も設定しなければDBユーザ、パスワード、DB名がすべてpostgresになります。

volume

volumeは、コンテナ内のディレクトリをホスト側(コンテナ起動元環境)へマウントすることで、 ホストとコンテナとでファイルを共有したり、コンテナ内のデータを永続化する仕組みです6

postgresイメージのドキュメントを読むと環境変数PGDATAの説明にこう書かれています。

This optional environment variable can be used to define another location – like a subdirectory – for the database files. The default is /var/lib/postgresql/data, but if …

(意訳)

これはデータベースファイルを別の場所 – サブディレクトリといった - へ設定することができる省略可能な環境変数です。そのデフォルトは/var/lib/postgresql/dataであり、…

つまりPGDATAを設定しなければコンテナ内のDBデータは/var/lib/postgresql/dataに作られることがわかります。これをマウントしておけばDBのデータを永続化できるということです。

また、特定のディレクトリに配置されたファイルを読み込むといった機能を提供している場合もあります。postgresイメージの場合、/docker-entrypoint-initdb.dに配置されたシェルやsqlを読み込めるようになっています。

If you would like to do additional initialization in an image derived from this one, add one or more *.sql, *.sql.gz, or *.sh scripts under /docker-entrypoint-initdb.d (creating the directory if necessary). After the entrypoint calls initdb to create the default postgres user and database, it will run any *.sql files and source any *.sh scripts found in that directory to do further initialization before starting the service.

(意訳)

このイメージを利用した起動に追加の初期化処理を追加したい場合、/docker-entrypoint-initdb.d(ディレクトリは作成してください)配下に *.sql*.sql.gz*.shスクリプトを配置してください。entrypointがinitdbをコールしデフォルトのpostgresユーザとデータベースを作成したあと、このディレクトリに配置されたすべての*.sqlファイルと*.shは、サービス起動前にさらなる初期化処理として実行されます。

ここでentrypointとはDockerコンテナ起動時に実行されるコマンド7のことです。

docker-compose.ymlを書く

docker runコマンドで直接コンテナを起動することもできますが、ファイルで記述した方がスッキリと理解しやすく共有しやすいので、Docker Composeを利用して環境をセットアップします。 Docker Composeはデフォルトでdocker-compose.ymlを読み込んでコンテナを起動します。 これまで確認したことを踏まえてサンプルを示します。

ディレクトリ構成は以下のようにします。各ファイルについては後述します。

db/shdocker-compose.ymlvolumesの設定により、 コンテナ内の/docker-entrypoint-initdb.dにマウントされます。 先程のDockerHubのドキュメントに、このディレクトリ中にある.shの拡張子をもつファイルはコンテナ起動時に自動実行されるとありました。

これを利用して起動させるdb/sh/init.shに下記を記述します。

このシェルスクリプトではdocker-compose.ymlで設定した環境変数IMPORT_FROM_DIRを利用し、 コンテナ内のディレクトリ/dataに配置された.dumpの拡張子ファイルをすべてDBへリストアします。

以上で最低限の設定が整いました。

DBを起動してみる

準備が整ったら、docker-compose.ymlのあるディレクトリでdocker-compose upコマンドを実行するとコンテナが起動します。

上記のようにログが出力され、db.dumpを読み込むログが流れたら成功です。

docker-compose.ymlの下記設定により、ローカルの5432ポートがコンテナ内へフォワードされているので、

psqlコマンドを使うことができれば接続してみましょう。

あとがき

Docker Composeを使った開発は、最初の構成さえ多少頑張れば同じ環境を量産&使い捨てできる上、 基本ymlファイルで管理できるのがきもちよく気に入っています。

今回は最低限の機能を使った紹介でしたが、また多少応用的な使い方も紹介出来たらと思います。


  1. https://docs.docker.com/docker-hub/official_repos/#should-i-use-official-repositories

  2. ロケールを日本語にできないなど、一部機能が利用出来ないこともあります。

  3. Dockerコンテナ起動時、指定されたシェルスクリプトが自動実行されることがほとんどです。このシェルスクリプトが環境変数を使うことで、静的なイメージに対し動的な設定がコンテナ内で行われます。

  4. コンテナ内でプロセスがエラーステータスを返すとコンテナが停止します。

  5. 例えばMySqlのdockerイメージでは、rootパスワードを設定する環境変数を必ず1つは設定する必要があります。

  6. 基本的にコンテナは使い捨てなので、永続化させたいデータがある場合はvolumeの設定をすることでそれを実現します。

  7. 大抵はイメージ提供元が用意したシェルスクリプトです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

12 + 14 =