55
48

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 Hub公式PostgreSQLで初期化ずみデータベースコンテナを作る

Last updated at Posted at 2016-10-07

はじめに

Docker Hub公式PostgreSQL( https://hub.docker.com/_/postgres/ )で初期化ずみデータベースコンテナを作ります。
意外と日本語で書かれたものがなかったのでメモを残します。

環境

  • Ubuntu 16.04
  • Docker 1.12.1

PostgreSQLはすでに別環境にあって、それをまるっと載せたデータベースコンテナを作る想定。

手順

Dockerfileの準備

  • 空ディレクトリ~docker/postgresを作成し、その中に以下のように記述したDockerfileを配置。
Dockerfile
FROM postgres:9.3
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
COPY *.sql /docker-entrypoint-initdb.d/

Postgresのバージョンは今別環境で使っているものとあわせたので9.3に。
RUNとENVはlocaleのために必要。
COPYで同じディレクトリにおいた初期化用の *.sql を imageの所定のディレクトリにコピーしている。

  • 初期化用SQLをdocker/postgres に配置。

公式Docker HubのPostgreSQLを使うと、 コンテナを作ったときに /docker-entrypoint-initdb.d/ の下の *.sh, *.sql, *.sql.gz が実行されます。なので、初期化用のsqlを一緒においておきます。

こちらはユーザ作成とデータベース作成だけやるSQL。

01_createdb.sql
create role user1 login password 'user1';
create database user1;
grant all privileges on database user1 to user1;

こちらは既存のPostgreSQLのDBから$ pg_dump -U postgres -Fp user1 して作成したダンプ。ファイルの先頭にuser1 dbにつなぐための \c user1; だけ追加してある。

02_restore.sql
\c user1;
--
-- PostgreSQL database dump
--

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;

--
-- Name: user1; Type: SCHEMA; Schema: -; Owner: user1
--

CREATE SCHEMA user1;


ALTER SCHEMA user1 OWNER TO user1;
-- 後略

ちなみにsqlファイル名の先頭に01とか02をつけているのは、実行を順番にしたいため。コンテナ作成時の初期化スクリプトで for f in /docker-entrypoint-initdb.d/*; do しているので、数字をつけたら順番にやってくれるかな、という姑息な手段。

docker builld

~/docker/postgresでビルド

$ docker build -t xxx/postgres .
Sending build context to Docker daemon 6.656 kB
Step 1 : FROM postgres:9.3
 ---> db4057098cc9
Step 2 : RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
 ---> Running in 3ad41c50d769
 ---> 427b06ac1197
Removing intermediate container 3ad41c50d769
Step 3 : ENV LANG ja_JP.UTF-8
 ---> Running in 27b2492a5365
 ---> ff2f1175f3d5
Removing intermediate container 27b2492a5365
Step 4 : COPY *.sql /docker-entrypoint-initdb.d/
 ---> 1e02da327a9f
Removing intermediate container 23e15cd44a29
Successfully built 1e02da327a9f

コンテナ作成

$ docker run -d --name postgres xxx/postgres
2131dcf553de2f67c0d9ae990d99c811de1b2dd8aa399204a34e65a6760e0947

コンテナ作成時に docker-entrypoint.sh が実行されて、initdb等が行われます。同時に、 /docker-entrypoint-initdb.d の下にある、 *.sh, *.sql, *.sql.gz が順次実行されています。
なので長いsqlを流した場合は docker run でプロンプトが返ってきてもまだ初期化中だったりします。
docker logs -f postgres で見ていました。

コンテナの起動を確認。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
2131dcf553de        xxx/postgres        "/docker-entrypoint.s"   10 minutes ago      Up 10 minutes       5432/tcp            postgres

初期化スクリプトで失敗するとコンテナはstopします。logsで原因を調べてファイルを修正して、コンテナとイメージを削除して( docker rm コンテナ名, docker rmi イメージ名) build からやり直し。

接続確認

user1 データベースに user1ユーザで接続して確認。

$ docker run -it --rm --link postgres:postgres xxx/postgres psql -h postgres -U user1 -n user1
psql (9.3.14)
Type "help" for help.

user1=> \d
            List of relations
 Schema |     Name     |   Type   | Owner 
--------+--------------+----------+-------
 user1  | distributors | table    | user1
 user1  | films        | table    | user1
 user1  | serial       | sequence | user1
(3 rows)

無事初期化できたようです。

そのほか

ちょっと困ったことなど。

psqlで日本語入らない

docker run で動かしたpsqlで日本語が入らなかったのですよ。
軽くぐぐったら
https://pasero.net/~mako/blog/s/229
にあたって、とりあえずpsqlに-nオプションを足したら日本語入りました。でもreadlineないと超不便。

create role多すぎた

これは元のDBの構成のせいですが、roleが多すぎて、記憶に頼ってcreate roleをぽちぽち書いていたら足りないユーザがいて、何度も初期化の途中でコケるはめに。最後は面倒になってpg_dumpのファイルから以下のようにしてcreate role文を作りました。

$ grep -e '^GRANT' 02_restore.sql |awk '{print $7}'|sort |uniq| sed -e "s/\(.*\);/create role \1 login password '\1';/g"

PUBLICとかpostgresとかが入っちゃったら削る必要があります。

55
48
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
55
48

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?