どうも、nippa です。
前回の内容:
timesaving.hatenablog.com
docker で postgreSQL の構築を行いましたが、より便利に使うためにホストのストレー
ジとコンテナのストレージの共有設定を行いたいと思います。
コンテナの初回起動時に、データベース構築 SQL を読み込み、2 回目以降のコンテナ起
動では、前回データが読み込まれるように設定します。
今回はついでに PostgreSQL 14 がリリースされたので、14 を使ってみたいと思います。
PostgreSQL 14 Released!
環境
今回は下記のようなディレクトリ構造になります。
.
├── dockerfile
├── data/
└── init/
└── init.sql
init には初回起動に実行するスクリプトを配置します。
data はコンテナの PostgreSQL データをホストと共有して保存するためのディレクトリ
になります。
dockerfile でイメージをpostgres:14-alpine
を指定してください。
FROM postgres:14-alpine
ENV TZ Asia/Tokyo
dockerfile の内容をpostgresql
というイメージ名でビルドします。
docker build -t postgresql .
コンテナの初回起動時の SQL の作成
初回実行時の SQL init/init.sql
は以下のような内容を書き込みます。
\set user_name [ユーザー]
\set user_password [ユーザーのパスワード]
\set database_name [データベース名]
\set schema_name public
\set table_name users
CREATE ROLE :user_name WITH LOGIN PASSWORD :'user_password';
CREATE DATABASE :database_name OWNER = :user_name TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.utf8' LC_CTYPE = 'en_US.utf8';
ALTER DATABASE :database_name SET timezone to 'Asia/Tokyo';
GRANT ALL ON DATABASE :database_name TO :user_name;
ALTER ROLE :user_name SET search_path TO :schema_name;
\c :database_name
CREATE TABLE IF NOT EXISTS :schema_name.:table_name (
id serial PRIMARY KEY,
username VARCHAR ( 50 ) UNIQUE NOT NULL,
password VARCHAR ( 50 ) NOT NULL,
email VARCHAR ( 255 ) UNIQUE NOT NULL,
created_on TIMESTAMP NOT NULL
);
GRANT ALL ON :schema_name.:table_name TO :user_name;
今回は簡単な user テーブルを作成しています。
コンテナの起動時にボリュームとポートを指定します。また、postgres ユーザーのパス
ワード指定は必須なので指定します。
docker run --name postgres -it -p 5432:5432 -e POSTGRES_PASSWORD=[パスワード] -v $(pwd)/init:/docker-entrypoint-initdb.d -v $(pwd)/data:/var/lib/postgresql/data -d postgresql
起動の確認を行います。
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a22e709fd827 postgresql "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:5432->5432/tcp postgres
データベースの確認
以下のコマンドでコンテナの PosgreSQL にログインします。
psql -U [ユーザー名] -h localhost -p 5432 -d [データベース名]
Password for user [ユーザー名]: <--- パスワードを入力
psql (14.0, server 14.1)
Type "help" for help.
[データベース名]=>
データベースにログインしたら、テーブルの確認を行います。
[データベース名]=>\d
# 出力
List of relations
Schema | Name | Type | Owner
public | user | table | postgres
public | user_id_seq | sequence | postgres
(2 rows)
初回起動時の SQL が読み込まれ、user テーブルと user_id_seq テーブルが作成されて
います。今回 admin ユーザーを指定していないので、初回起動時の SQL は posgres ユ
ーザーで作成されています。権限の確認をします。
[データベース名]=> \z
# 出力
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
public | users | table | postgres=arwdDxt/postgres+ | |
| | | [ユーザー名]=arwdDxt/postgres | |
public | users_id_seq | sequence | | |
(2 rows)
権限が正しくついています。select 文を実行してみます。
[データベース名]=> select * from users;
id | username | password | email | created_on
----+----------+----------+-------+------------
(0 rows)
テーブルが空になっています。ここデータを挿入します。
[データベース名]=> INSERT INTO users (username, password, email, created_on) VALUES ('Yamada Taro', 'yamadatraro', 'yamada-taro@example.com', now());
# 出力
INSERT 0 1
[データベース名]=> select * from users;
id | username | password | email | created_on
1 | Yamada Taro | yamadatraro | yamada-taro@example.com | 2021-11-13 14:28:24.695819
(1 row)
データ挿入が確認できたので、コンテナを停止・削除を行ったのちに再度起動します。
docker stop postgres
docker rm postgres
docker ps
コンテナを再度起動させます。
docker run --name postgres -it -p 5432:5432 -e POSTGRES_PASSWORD=[パスワード] -v $(pwd)/init:/docker-entrypoint-initdb.d -v $(pwd)/data:/var/lib/postgresql/data -d postgresql
データベースにアクセスしてデータが残っているかを確認します。
psql -U [ユーザー名]] -h localhost -d [データベース名]
Password for user [ユーザー名]]:
psql (14.0, server 14.1)
Type "help" for help.
[データベース名]=> select * from users;
id | username | password | email | created_on
----+-------------+-------------+-------------------------+----------------------------
1 | Yamada Taro | yamadatraro | yamada-taro@example.com | 2021-11-20 21:28:24.695819
(1 row)
データが残っていることが確認できました。
感想
今回、docker Postgresql を開発でより使いやすくするために、ホスト側とストレージを
共有して、データ部分を残す方法をご紹介しました。
これで、必要なときに必要なデータベースを切り替えて開発することができるので、非常
に便利です。
docker-compose を使うと更に便利になりますので、こちらも紹介したいと思います。
ではでは、また次回。