背景
使用したファイル
以下のdocker-compose.yaml
とinit.sql
でdockerでDBを起動する際にテーブルの作成と初期データの挿入を試みた。
docker-compose.yaml
version: '3.9'
services:
db:
image: postgres:16
ports:
- "5432:5432"
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydatabase
volumes:
- ./data:/var/lib/postgresql/data
- ./init:/docker-entrypoint-initdb.d
volumes:
data:
init/init.sql
CREATE TABLE IF NOT EXISTS pets (
pet_id INTEGER,
pet_type INTEGER,
pet_name VARCHAR(10)
);
INSERT INTO pets (pet_id, pet_type, pet_name) VALUES (1, 1, 'Pet1');
INSERT INTO pets (pet_id, pet_type, pet_name) VALUES (2, 2, 'Pet2');
実行内容
docker compose up -d
をした上で、以下コマンドでコンテナに入りDBの中身を確認した。
$ docker-compose exec -it db psql -U user -d mydatabase
mydatabase# \dt;
mydatabase# select * from pets;
過去にコンテナに入ってDB操作を試したデータがそのまま残っており、init.sql
の初期化が実行されていなさそう。
実行ログ
dbコンテナのログには以下のように、Skipping initialization
となっている。
2024-07-26 00:00:00
2024-07-26 00:00:00 PostgreSQL Database directory appears to contain a database; Skipping initialization
2024-07-26 00:00:00
2024-07-26 00:00:00 2024-07-26 02:18:33.974 UTC [1] LOG: starting PostgreSQL 16.3 (Debian 16.3-1.pgdg120+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
2024-07-26 00:00:00 2024-07-26 02:18:33.974 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2024-07-26 11:18:33 2024-07-26 02:18:33.974 UTC [1] LOG: listening on IPv6 address "::", port 5432
2024-07-26 11:18:33 2024-07-26 02:18:33.977 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2024-07-26 11:18:33 2024-07-26 02:18:33.993 UTC [30] LOG: database system was shut down at 2024-07-26 02:18:31 UTC
2024-07-26 11:18:33 2024-07-26 02:18:33.998 UTC [1] LOG: database system is ready to accept connections
解決策
docker volume ls
でも何も表示されないのに何故だろう...と困ったが、docker-compose.yaml
で以下のように指定していることが原因だった。
docker-compose.yaml
volumes:
- ./data:/var/lib/postgresql/data
dockerを起動するたびに過去のデータをそのまま利用したいときにこれを指定すると、ローカルのdata/
内を参照するため、init/init.sql
は実行されない。
もしvolumeを削除して、何もない状態からDBの初期化を試したければ、過去の実行で生成されたdata
ディレクトリを削除してあげれば良い。
data
ディレクトリを削除した状態でdocker-compose up -d
を行えば、真っ新なDBでinit.sql
が実行される。
※今回やりたかったことは以上で実現されたが、volumeの削除との違いについて、今後勉強する必要がありそう。