本番環境ではDBはコンテナ化することは少いと思いますが、諸事情によりメモ。
前知識
Docker環境でPostgreSQLを扱う場合に事前に知っておいたほうが良い知識。
/docker-entrypoint-initdb.d/
PostgreSQLのイメージ(MySQLも)では、/docker-entrypoint-initdb.d/以下に置かれたファイルを起動時に実行する仕組みがあり、これらを利用してDBの初期設定・初期データの作成などを行うことができる。
サーポートされている拡張子は.sh, .sql, .sql.gzみたい。
/var/lib/postgresql/data
PostgreSQLのデータ保存場所のパスは/var/lib/postgresql/dataとなる。これをローカルにマウントしてデータの永続化を行う。
基本
起動
まずはシンプルにPostgreSQLをDockerで起動してみます。
私の都合上、14.5-bullseyeを指定していますが、単にpostgresでも問題ありません。
docker run --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres:14.5-bullseye
-eは環境変数を指定しています(パスワードを指定)。
-dはバックグラウンドで起動
ログイン
dockerを利用しているホスト環境にpsqlがインストールされていれば以下でログインできます。
$ psql -h localhost -U postgres -d postgres
パスワードはdocker run時に環境変数として与えたものになります(ここではpostgres)。
応用1(初期データ設定および永続化)
準備
cd
mkdir docker-pg-test
cd docker-pg-test
mkdir init data
touch ./init/init.sql
init.sql
create table if not exists members(
id serial primary key,
name text,
age int
);
実行と動作確認
基本時の記述に加え、-vでローカルの./initと./dataをコンテナ上のディレクトリにマップしています。
実行場所は上記docker-pg-testディレクトリの中です。
実行
docker run --name postgres -it -p 5432:5432 -e POSTGRES_PASSWORD=postgres -v $(pwd)/init:/docker-entrypoint-initdb.d -v $(pwd)/data:/var/lib/postgresql/data -d postgres:14.5-bullseye
ログイン
ホストPC上で行います。
$ psql -h localhost -U postgres -d postgres
テーブル確認
\dtでテーブルを確認してみます。membersテーブルが作成されています。
members_id_sqlは自動連番用に自動生成されたテーブルです。
postgres=# \dt;
List of relations
Schema | Name | Type | Owner
--------+----------------+----------+----------
public | members | table | postgres
public | members_id_seq | sequence | postgres
(2 rows)
データの挿入
データを挿入してみます。
select * from members;で内容確認してみてください。
postgres=# insert into members(name,age) values('hoge',99);
DBから抜ける
ここでDBからは一旦抜けておきます(ホストPCでの操作)。
postgres=# \q;
exitでも抜けられる。
データが永続化されているか確認してみましょう。
コンテナの停止
まず、コンテナの停止。
docker stop postgres
コンテナの削除
コンテナの削除。
ここで永続化していなければデータは失われます。
docker rm postgres
コンテナの再実行
では、再度コンテナを立ち上げてみます。
docker run --name postgres -it -p 5432:5432 -e POSTGRES_PASSWORD=postgres -v $(pwd)/init:/docker-entrypoint-initdb.d -v $(pwd)/data:/var/lib/postgresql/data -d postgres:14.5-bullseye
ログインしてデータ確認
ログインしてデータを確認します。上記(以前)で投入したデータが確認できます(=データが永続化されています)。
postgres=# select * from members;
id | name | age
----+------+-----
1 | hoge | 99
(1 row)
応用2(docker-compose化)
ごちゃごちゃしてるのでdocker-composeにまとめてみる。
docker-compose.ymlの記述
version: '3'
services:
postgres:
image: postgres:14.5-bullseye
container_name: my_postgres
ports:
- "5432:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
- ./data:/var/lib/postgresql/data
- ./init:/docker-entrypoint-initdb.d
実行
docker-compose up -d
停止
docker-compose down
応用3(Dockerfileで記述)
docker-composeに比べたらできることは限られるが、クラウドのマネージ環境で動作させることを前提とすると、Dockerfile(イメージ化)でできることはしておいたほうがいいのかも。
Dockerfile
FROM postgres:14.5-bullseye
COPY ./init/init.sql /docker-entrypoint-initdb.d/init.sql
ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD postgres
EXPOSE 5432
DockerfileのVOLUMEでは、名前付きボリュームは指定できないみたい。
イメージのビルド
docker build -t my_postgres .
実行
実行してみる。
docker run --name my_db -p 5432:5432 -d my_postgres
動作確認
まずはログイン(ホストPCから)。
$ psql -h localhost -U postgres -d postgres
init.sqlが適用されているか確認(されているみたい)。
postgres=# select * from members;
id | name | age
----+------+-----
(0 rows)