-
Docker Composeチュートリアル: herokuのPostgresをローカルにさくっとコピーする
- 2018年5月23日
- docker
- docker compose
- Heroku
- PostgreSQL
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
とします。
$ heroku pg:backups capture --app hoge-app # 現在のDBデータをheroku上でダンプ
$ curl -o db.dump $(heroku pg:backups public-url --app hoge-app) # ダンプデータをダウンロード
これでダンプデータをdb.dump
に保存できました。楽ちんですね。
Dockerの準備
Dockerで環境を構築する際は大まかに以下の流れで作成しています。
- Docker Hubでほしいイメージを探す
- docker-compose.ymlに設定を書き込む
順にみていきます。
Docker Hub
Dockerのイメージは主にDocker Hubで公開されています。
ログインしないと各イメージを見ることができないので、アカウントを取得しておいてください。
ほしいイメージを探す
Docker Hubのページでログイン済なら、かわいいクジラのアイコンの横の検索窓に、「postgres」と入力してEnterを押します。
ほしいイメージを見つける
Postgresのイメージが見つかりました。
https://hub.docker.com/_/postgres/
「official」と書いてあれば、Docker公式のイメージです。業務で使うのであればこの表示があるものを選ぶのが無難かと思います1。
必要な設定をDocker Composeに記述する
押さえておくべき項目は下記のとおりです。
- タグ
- 環境変数
- volume
順に見ていきます。
タグ
タグはイメージのバージョンやOSごとに分けられたラベルと考えるとわかりやすいです。
officialイメージであれば上のように、利用できるイメージタグのリストが記載されています。ほとんどが利用できるアプリのバージョンに対応した書き方なので、直感的に理解できると思います。
alpine
がついているタグはAlpine Linuxをベースに作られており、一言でいうとイメージサイズが非常に小さいです。ダウンロードやコンテナ起動がスマートになるので、OSにこだわらなければこちらの利用をおすすめします2。
環境変数
アプリケーションの基本設定まわりは環境変数で与えることが多いです3。
環境変数の用途には大まかに3つのケースがあります。
- 設定自体が必須
- 設定すると設定値を上書きする
- オプションで設定を付け加える
設定必須の環境変数を省略してコンテナを起動した場合エラー終了します4。環境変数自体を必須とするイメージはあまりありませんが、複数あるうちのいずれかの環境変数が必須になるケースもあります5。
今回のpostgresのイメージのドキュメントを読み解くと、必須の環境変数はないようです。一応メインとなりそうな環境変数を下記にピックアップしました。
POSTGRES_USER
- DBユーザ名を設定します。指定しない場合は
postgres
になります。
- DBユーザ名を設定します。指定しない場合は
POSTGRES_PASSWORD
- DBユーザのパスワードを設定します。設定しない場合は
POSTGRES_USER
の値が使われます。
- DBユーザのパスワードを設定します。設定しない場合は
POSTGRES_DB
- コンテナ起動時に作成するDB名を指定します。設定しない場合は
POSTGRES_USER
の値が使われます。
- コンテナ起動時に作成するDB名を指定します。設定しない場合は
つまり上記環境変数を何も設定しなければ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 callsinitdb
to create the defaultpostgres
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
を読み込んでコンテナを起動します。 これまで確認したことを踏まえてサンプルを示します。
version: '3'
services:
postgres: # 起動コンテナを区別する名称。コンテナネットワーク上でのホスト名になる
image: postgres:10.3-alpine # ここでDockerHubから取得したいイメージ:タグを指定する
environment:
IMPORT_FROM_DIR: /data # db/sh/init.shで使う環境変数
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: db
ports:
- 5432:5432 # ポート転送の設定 ... ホスト側ポート:コンテナ内ポート
volumes: # マウントの設定 ... ホスト側ディレクトリ:コンテナ側ディレクトリ
- ./db/sh:/docker-entrypoint-initdb.d # この中の.sh、.sqlファイルは自動実行される
- ./db/data:/data # db.dumpを配置する
- ./db/storage:/var/lib/postgresql/data # データベースデータを永続化する
ディレクトリ構成は以下のようにします。各ファイルについては後述します。
db/sh
はdocker-compose.yml
のvolumes
の設定により、 コンテナ内の/docker-entrypoint-initdb.d
にマウントされます。 先程のDockerHubのドキュメントに、このディレクトリ中にある.sh
の拡張子をもつファイルはコンテナ起動時に自動実行されるとありました。
これを利用して起動させるdb/sh/init.sh
に下記を記述します。
#!/bin/bash
# set -eu
for dumpfile in $IMPORT_FROM_DIR/*.dump; do
pg_restore -C -d $POSTGRES_DB $dumpfile
done
このシェルスクリプトではdocker-compose.yml
で設定した環境変数IMPORT_FROM_DIR
を利用し、 コンテナ内のディレクトリ/data
に配置された.dump
の拡張子ファイルをすべてDBへリストアします。
以上で最低限の設定が整いました。
DBを起動してみる
準備が整ったら、docker-compose.yml
のあるディレクトリでdocker-compose up
コマンドを実行するとコンテナが起動します。
$ ls
db docker-compose.yml
$ docker-compose up
Creating network "hoge-db_default" with the default driver
Creating hoge-db-fullsandbox_postgres_1 ... done
Attaching to hoge-db-fullsandbox_postgres_1
postgres_1 | The files belonging to this database system will be owned by user "postgres".
postgres_1 | This user must also own the server process.
postgres_1 |
postgres_1 | The database cluster will be initialized with locale "en_US.utf8".
postgres_1 | The default database encoding has accordingly been set to "UTF8".
postgres_1 | The default text search configuration will be set to "english".
postgres_1 |
postgres_1 | Data page checksums are disabled.
postgres_1 |
postgres_1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok
postgres_1 | creating subdirectories ... ok
postgres_1 | selecting default max_connections ... 100
...
上記のようにログが出力され、db.dump
を読み込むログが流れたら成功です。
docker-compose.yml
の下記設定により、ローカルの5432
ポートがコンテナ内へフォワードされているので、
psql
コマンドを使うことができれば接続してみましょう。
$ psql -d db -h localhost -U user
Password for user postgres: # passwordと入力(docker-compose.ymlの設定に合わせる)
psql (10.1, server 10.3)
Type "help" for help.
postgres=#
あとがき
Docker Composeを使った開発は、最初の構成さえ多少頑張れば同じ環境を量産&使い捨てできる上、 基本ymlファイルで管理できるのがきもちよく気に入っています。
今回は最低限の機能を使った紹介でしたが、また多少応用的な使い方も紹介出来たらと思います。
https://docs.docker.com/docker-hub/official_repos/#should-i-use-official-repositories↩
ロケールを日本語にできないなど、一部機能が利用出来ないこともあります。↩
Dockerコンテナ起動時、指定されたシェルスクリプトが自動実行されることがほとんどです。このシェルスクリプトが環境変数を使うことで、静的なイメージに対し動的な設定がコンテナ内で行われます。↩
コンテナ内でプロセスがエラーステータスを返すとコンテナが停止します。↩
基本的にコンテナは使い捨てなので、永続化させたいデータがある場合はvolumeの設定をすることでそれを実現します。↩
大抵はイメージ提供元が用意したシェルスクリプトです。↩
この記事を書いた人 : 上田直諒
AWS bluebird css CSV docker docker compose electron ES6 es2015 Git Heroku ITコンサルティング JavaScript justinmind less mongoDB Node.js php PostgreSQL Private Space Promise React react-router reactjs Salesforce scss Selenium Builder selenium IDE Selenium WebDriver stylus TypeScript VirtualBox VisualStudioCode vue vuejs webpack システム開発プロジェクト セキュリティ ワイヤーフレーム 上流工程 卒FIT 帳票 要件定義 設計 電力小売業界