開発作業を行う際、Dockerのsql系イメージとDBUnitを使ってテストを作っていたので、練習がてらこちらの記事にも書いていきます。
- バージョン関連
- ディレクトリ構成
- docker-compose.ymlの中身
- environment
- restart
- Dockerfileの中身
- ddl、dmlフォルダの中身
- docker compose でpostgresqlを立ち上げる
- DBeaverからPostgresqlコンテナにつなげてみる
- まとめ
バージョン関連
macOS Pro Monterey Apple M1 Docker 20.10.11, build dea9396 docker compose v2.2.1 DBeaver 23.0.5
ディレクトリ構成
のちのちの記事でSpring Bootを使うので、それに見越したフォルダ構成にします。
おそらくみなさんの環境には何もないと思いますが、何はともあれ下記のようなフォルダ構成やファイルを今回の目標として進めていきます。
# DBUnitApplication/ └── docker ├── docker-compose.yml └── postgresql ├── Dockerfile ├── ddl │ └── book_ddl.sql └── dml └── book_dml.sql
docker-compose.ymlの中身
dockerディレクトリ配下にdocker-compose.ymlファイルを作成します。
中身は下記です。
version: '3' services: postgresql: container_name: postgresql_container build: ./postgresql ports: - 5432:5432 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: passw0rd TZ: "Asia/Tokyo" restart: always
version
docker-composeで使用するバージョンを定義しています。詳細は公式ページとかをみてください(雑)。
services
アプリケーションを動かすための各要素。docker composeでは下記の例のように複数のコンテナを立てることができ、service以下に複数のコンテナを立てることができます。
ただ、今回はpostgresqlだけしかない状態です。
services db: 〜〜 web: 〜〜 app:
postgresql
正確にはservices内で作成するコンテナのことで、ここの名前はなんでもいいです。
今回はpostgresqlのイメージを使うので、postgresqlと書いただけでした。
container_name
コンテナを立ち上げた際のコンテナの名前です。postgresqlのコンテナなので、postgresql_containerとしています。
build
Dockerfileが置いてあるパスを指定します。今回はdocker-compose.ymlから見て、postgresqlディレクトリ配下のところに置いてあるDockerfileを参考にしています。
ports
ポートを指定します。指定の仕方はホスト:コンテナ
となります
Dockerはコンテナを立てた後、そのコンテナと通信を行うためには外部から通信できるポートを指定しなければコンテナにアクセスすることができません。
今回、コンテナ内部でpostgresqlサーバを立てており、それはpostgresqlのデフォルトのポート番号5432で動いています。そのため、ホスト:コンテナ
のコンテナ部分はホスト:5432
となります。
一方、ホスト部分は外部からあるポートで来たときに内部のpostgresqlサーバで5432に繋ぐようになっています。この時のホスト部分から繋ぐ番号はわかりやすく5432としておきましょう。
つまり、ホスト:5432
のホスト部分が5432:5432
となり、これで外部からポート番号5432で来た場合に、コンテナ内部のPostgresqlサーバにポート番号5432で繋ぐことができます。
(この辺りのポート番号の指定の仕方をしっかり理解しておきたい場合は、ホスト側の番号を変えると理解しやすくなるかと思います。)
environment
postgresqlのイメージを使う際には必須の設定になります。ここら辺の設定は他の記事を参考にしてください。
restart
コンテナを再起動するかどうかのオプションです。alwaysを設定した場合、コンテナが落ちた際は再起動するようになっています。
で、これが役に立つのは大体OSを再起動した時でしょうか。OSを再起動する場合はほとんどのアプリケーションを止めることになるので、OS再起動後にDocker側で自動でコンテナを再起動するようにするには、必要な設定になっています。
Dockerfileの中身
dockerディレクトリ > postgresqlディレクトリ配下にDockerfileを作成します。
中身は下記です。
FROM postgres:latest COPY ./ddl/* /docker-entrypoint-initdb.d COPY ./dml/* /docker-entrypoint-initdb.d
FROM イメージ名
FROM句でイメージ名を指定します。今回はpostgresqlの最新(latest)のイメージを利用します。
COPY 第一引数 第二引数
COPY句はDockerfileがあるパスから見て、第一引数にあるものをコンテナ内部の第二引数の部分にコピーする方法です。
ここでsql系のイメージを使う場合、コンテナが起動したと同時に、sql系のサーバに初期データなどを投入しておきたいなどがあるかと思います。
その場合、Dockerのsql系のイメージは大体docker-entrypoint-initdb.d
というディレクトリがあります。
ここに必要なファイル(sqlファイル系)を配置するようにすると、コンテナ起動と同時に、必要な設定や初期データを自動で入れてくれます。
ddl、dmlフォルダの中身
ddlとは、データ定義言語(DDL: Data Definition Language)のことで、SQLのCREATE TABLEステートメントなどを指します。
一方、dmlはデータ操作言語(DML: Data Manipulation Language)のことで、SELECT、UPDATE、DELETEステートメントなどを指します。
まぁ、一番最初のDBの枠を作るのがDDLで、具体的にデータの操作を行うのがDMLと覚えておけばいいでしょう。
ddlの中身
中身はシンプルで、ddlフォルダの中にbook_ddl.sqlファイルを置いてあるだけです。book_ddl.sqlの中身は下記になります。
-- DBの作成 create database db_books; -- DBの選択 \connect db_books; -- スキーマの作成 create schema books; -- スキーマの選択 SET search_path = books; -- テーブルの作成 create table book ( id serial PRIMARY KEY NOT NULL, title varchar(100) NOT NULL, author varchar(10) NOT NULL, created timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, updated timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL );
最初のcreate schema
でbooksというスキーマを作成し、そのbooksというスキーマの中にbookというテーブルを作成しています。
具体的なsqlの型などはここでは割愛します。
dmlの中身
こちらも中身はシンプルで、dmlフォルダの中にbook_dml.sqlファイルを置いてあるだけです。book_dml.sqlの中身は下記になります。
-- DBの選択 \connect db_books; -- スキーマの選択 SET search_path = books; -- データの挿入 insert into book (title, author) values ('営繕かるかや怪異譚', '小野不由美'); insert into book (title, author) values ('営繕かるかや怪異譚 その弐', '小野不由美'); insert into book (title, author) values ('営繕かるかや怪異譚 その参', '小野不由美');
search_pathでbooksというスキーマを指定し、そのスキーマの中のbookテーブルにデータを入れています。
docker compose でpostgresqlを立ち上げる
さて、ここまでくればDockerを使って、postgresqlを立ち上げることができます。
ターミナルからdocker-compose.ymlファイルがあるディレクトリ(dockerディレクトリ)に移動し、下記でコンテナを立ち上げます。
# docker compose up -d --build Sending build context to Docker daemon 1.05kB Step 1/3 : FROM postgres:latest ---> bc5d09b9811d Step 2/3 : COPY ./ddl/* /docker-entrypoint-initdb.d ---> Using cache ---> 884adf10e417 Step 3/3 : COPY ./dml/* /docker-entrypoint-initdb.d ---> Using cache ---> 10a346435f9b Successfully built 10a346435f9b Successfully tagged docker_postgresql:latest Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them [+] Running 2/2 ⠿ Network docker_default Created 0.0s ⠿ Container postgresql_container Started 0.0s
docker ps(もしくはdocker container ls) として、コンテナがちゃんと起動しているか確認します。
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6df61fb84222 docker_postgresql "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:5432->5432/tcp postgresql_container
上記のように出てくれば、一旦は大丈夫です。
DBeaverからPostgresqlコンテナにつなげてみる
DBeaverを利用して、先ほど立ち上げたPostgresqlコンテナにつなげてみましょう。 (DBeaverと言っていますが、正直、繋がるのであればどんなクライアントツールでもいいと考えています。WindowsだとA5SQLが有名でしょうか??)
DBeaverは下記の公式ページからダウンロードしてください。
さて、DBeaverを開いたら、接続設定を行います。
① 左上の接続ボタンを押下
② PostgreSQLを選択し、次へを押下
③ 下記項目を設定していきます。
Connect by:Host
Host:0.0.0.0
Port:5432
Database:postgres
ユーザー名:postgres
パスワード:passw0rd
いくつか注意点があります。
Port:DBeaverのPortでは、docker-compose.ymlのportsで設定した部分のポート番号を記載します。ここで注意しないといけないのは、ホスト:コンテナ
のホストのポート番号を記載することです。
仮に5500:5432
などと設定していた場合は、DBeaverのPortは5500を設定してください。
Database:特にdocker-compose.ymlやDockerfileで、DBの設定をしていなければ、デフォルトのpostgresで問題ありません。設定を変えていた場合、それに合わせて、変更が必要です。
ユーザー名:docker-compose.ymlで記載したユーザ名を記載します。今回はPOSTGRES_USERにpostgresを指定しているので、postgresになります。
パスワード:docker-compose.ymlで記載したパスワードを記載します。今回はPOSTGRES_PASSWORDにpassw0rdを指定しているので、postgresになります。
④ 設定し終わったら左下のテスト接続を押下します。
接続済み(下記画面)と出てきたら「OK」を押下し、(③の画像の)右下の「終了」を押下します。
さて、実際にDBeaverにデータが入っているか見てみましょう。
dmlで設定した3データがちゃんと入っていることが確認できましたね。
今回はここまでです。
まとめ
何はともあれ、Dockerの練習も兼ねてPostgreSQLをDockerで立てることができましたね。次回からはSpring Bootを導入して、実際にデータにアクセスしてみたいと思います。
また、これまでのものを整理すると下記のようになっています。
ディレクトリ構成
# DBUnitApplication/ └── docker ├── docker-compose.yml └── postgresql ├── Dockerfile ├── ddl │ └── book_ddl.sql └── dml └── book_dml.sql
docker-compose.ymlの中身
version: '3' services: postgresql: container_name: postgresql_container build: ./postgresql ports: - 5432:5432 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: passw0rd TZ: "Asia/Tokyo" restart: always
Dockerfileの中身
FROM postgres:latest COPY ./ddl/* /docker-entrypoint-initdb.d COPY ./dml/* /docker-entrypoint-initdb.d
book_ddl.sqlの中身
-- DBの作成 create database db_books; -- DBの選択 \connect db_books; -- スキーマの作成 create schema books; -- スキーマの選択 SET search_path = books; -- テーブルの作成 create table book ( id serial PRIMARY KEY NOT NULL, title varchar(100) NOT NULL, author varchar(10) NOT NULL, created timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, updated timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL );
dmlの中身
-- DBの選択 \connect db_books; -- スキーマの選択 SET search_path = books; -- データの挿入 insert into book (title, author) values ('営繕かるかや怪異譚', '小野不由美'); insert into book (title, author) values ('営繕かるかや怪異譚 その弐', '小野不由美'); insert into book (title, author) values ('営繕かるかや怪異譚 その参', '小野不由美');