かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その24 )( Docker で PostreSQL+pgAdmin4+ Flyway の環境を構築する )

概要

記事一覧はこちらです。

Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( 番外編 )( docker volume メモ書き ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • PostgreSQL の環境を Windows バイナリ(postgresql-10.5-1-windows-x64.exe)をインストールして構築した環境から Docker の PostgreSQL 環境へ変更します。
    • pgAdmin4 も Docker 版を入れます。
    • Docker の Flyway 環境も構築し、docker-compose up -d コマンドでコンテナを作成した時にテーブルの作成、データの投入を自動で実行されるようにします。尚、Flyway の PostgreSQL のページ を見ると、まだ PostgreSQL の 11 はサポートされていませんでした。

参照したサイト・書籍

  1. dockerhub - postgres
    https://hub.docker.com/_/postgres/

  2. docker-library/postgres
    https://github.com/docker-library/postgres

  3. dpage/pgadmin4
    https://hub.docker.com/r/dpage/pgadmin4

  4. pgadmin4/pkg/docker/Dockerfile
    https://github.com/postgres/pgadmin4/blob/master/pkg/docker/Dockerfile

  5. Dockerfile reference
    https://docs.docker.com/engine/reference/builder/

    • VOLUME の説明を参照しました。
  6. Best practices for writing Dockerfiles
    https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

    • 今回の記事とは直接関係ありませんが、調べている時に見つけたのでメモっておきます。
  7. boxfuse/flyway
    https://hub.docker.com/r/boxfuse/flyway

  8. flyway/flyway-docker
    https://github.com/flyway/flyway-docker

目次

  1. IntelliJ IDEA で YAML ファイルをリフォーマットした時に配列が1つ右にインデントされるようになった
  2. 単体の PostgreSQL+pgAdmin4サーバの環境を構築する
  3. create database 文等の SQL を実行した後、動作確認する
  4. Docker で Flyway の環境を構築する
  5. 次回は。。。

手順

IntelliJ IDEA で YAML ファイルをリフォーマットした時に配列が1つ右にインデントされるようになった

おそらく 2018.3 にバージョンアップしたからだと思いますが、以前はリフォーマットしても配列の要素は1つ上の要素と左揃えになっていたのが(ports, environment の部分)、

  rabbitmq_exporter:
    image: kbudde/rabbitmq-exporter:latest
    container_name: rabbitmq_exporter
    ports:
    - "9419:9419"
    environment:
    - RABBIT_URL=http://haproxy:15672
    - RABBIT_USER=${RABBITMQ_DEFAULT_USER}
    - RABBIT_PASSWORD=${RABBITMQ_DEFAULT_PASS}
    - RABBIT_CAPABILITIES=bert,no_sort
    - PUBLISH_PORT=9419

Ctrl+Alt+L を押してリフォーマットすると1つ右にインデントするようになりました。個人的には嬉しい変更です。

  rabbitmq_exporter:
    image: kbudde/rabbitmq-exporter:latest
    container_name: rabbitmq_exporter
    ports:
      - "9419:9419"
    environment:
      - RABBIT_URL=http://haproxy:15672
      - RABBIT_USER=${RABBITMQ_DEFAULT_USER}
      - RABBIT_PASSWORD=${RABBITMQ_DEFAULT_PASS}
      - RABBIT_CAPABILITIES=bert,no_sort
      - PUBLISH_PORT=9419

単体の PostgreSQL+pgAdmin4サーバの環境を構築する

.env に PostgreSQL、pgAdmin4 のバージョン番号を記述します。

..........
RABBITMQ_DEFAULT_VHOST=/

POSTGRESQL_VERSION=11.1
PGADMIN4_VERSION=3.6
  • 以下の2行を追加します。
    • POSTGRESQL_VERSION=11.1
    • PGADMIN4_VERSION=3.6

pgadmin4 のデータを保存するディレクトリとして docker/pgadmin4/data を作成します。

docker-compose.yml に postgresql、pgadmin4 の設定を追加します。

  # 起動したコンテナに /bin/sh でアクセスする場合には以下のコマンドを実行する
  # docker exec -it postgresql /bin/sh
  #
  # psql を使用したい場合には以下のコマンドを実行する
  # docker exec -it postgresql psql -U postgres
  postgresql:
    image: postgres:${POSTGRESQL_VERSION}-alpine
    container_name: postgresql
    ports:
      - "5432:5432"
    volumes:
      - ./sql:/sql
    environment:
      - LANG=ja_JP.UTF-8
      - POSTGRES_PASSWORD=xxxxxxxx

  # URL
  # http://localhost:12000/
  pgadmin4:
    image: dpage/pgadmin4:${PGADMIN4_VERSION}
    container_name: pgadmin4
    ports:
      - "12000:80"
    volumes:
      - ./docker/pgadmin4/data:/var/lib/pgadmin
    environment:
      # PGADMIN_DEFAULT_EMAIL には接続する PostgreSQL の ユーザ名を設定する(サーバを追加する時楽なため)
      - PGADMIN_DEFAULT_EMAIL=postgres
      - PGADMIN_DEFAULT_PASSWORD=yyyyyyyy
  • PostgreSQL の Docker Image は -alpine 版を使用します。
  • 構築後に SQL ファイルを実行したいので volumes に ./sql:/sql を記述しています(Flyway の環境を導入したら削除します)。
  • PostgreSQL の Docker Image はデフォルトでは ENV LANG en_US.utf8 と設定されているので、LANG=ja_JP.UTF-8 を設定して日本語環境にします。また PostgreSQL を Docker で構築する記事を見ると RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8 が記載されていることが多いのですが、postgres/Dockerfile-alpine.template の中にコメントで alpine doesn't require explicit locale-file generation と記載されており、-alpine 版では不要です。
  • pgAdmin4 の Docker Image は dpage/pgadmin4 を使用します。
  • pgAdmin4 のポート番号はホストの適当に空いているところに関連付けます(今回は 12000番ポートにしました)。
  • pgAdmin4 の設定情報をホストのディレクトリに保存したいので volumes に ./docker/pgadmin4/data:/var/lib/pgadmin を記述します。外部からマウントするディレクトリをどうやって探すのかよく分かっていなかったのですが、Dockerfile の中に VOLUME ... で記述されているディレクトリを見つければよいだけでした。
  • pgAdmin4 起動後に参照するサーバを追加するのですが、PGADMIN_DEFAULT_EMAIL にサーバに接続する時のユーザ名を設定しておくとサーバ追加時の設定が少し楽になるので postgres を記述しておきます(別に EMAIL である必要はないようです)。GADMIN_DEFAULT_EMAIL、PGADMIN_DEFAULT_PASSWORD は pgAdmin4 にログインする時のユーザID、パスワードになります。

docker-compose up -d コマンドを実行します。

f:id:ksby:20181224174918p:plain f:id:ksby:20181224175012p:plain

docker exec -it postgresql psql -U postgres コマンドを実行し psql で接続した後、日本語環境で PostgreSQL が構築されていることを確認します。

f:id:ksby:20181224175216p:plain

pgAdmin4 で接続してみます。http://localhost:12000/ にアクセスしてログイン画面が表示されたら ID、パスワード(docker-compose.yml に設定した PGADMIN_DEFAULT_EMAIL、PGADMIN_DEFAULT_PASSWORD の文字列)を入力し、「language」を "Japanese" に変更した後、「Login」ボタンをクリックします。

f:id:ksby:20181224175609p:plain

ログインして pgAdmin4 のメイン画面が表示されたらサーバを追加します。画面左側の「Servers」を選択してコンテンキストメニューを表示した後、「作成」-「サーバ...」を選択します。

f:id:ksby:20181224180106p:plain

「作成 - サーバ」ダイアログが表示されるので、「名称」に PostgreSQL のコンテナ名と同じ "postgresql" を入力します。

f:id:ksby:20181224180244p:plain

「接続」タブをクリックした後、「ホスト名/アドレス」に PostgreSQL のコンテナ名である "postgresql" を(docker-compose コマンドで起動しているのでコンテナ名で接続できます)、「パスワード」に PostgreSQL の postgres ユーザのパスワード(docker-compose.yml の postgresql コンテナに設定した POSTGRES_PASSWORD の文字列)を入力します。入力したら「保存」ボタンをクリックします。

※「ユーザ名」には PGADMIN_DEFAULT_EMAIL に設定した文字列がデフォルトでセットされます。今回は PostgreSQL に接続可能な "postgres" という文字列を PGADMIN_DEFAULT_EMAIL に設定していたので、改めて入力はしていません。

f:id:ksby:20181224180459p:plain

メイン画面上に追加した postgresql サーバが表示されます。

f:id:ksby:20181224180820p:plain

create database 文等の SQL を実行した後、動作確認する

プロジェクトの sql フォルダの下にある SQL ファイルを実行して database, table を作成した後、gradle の build タスクを実行してテストが正常に終了するか確認してみます。

まずは以下のコマンドを実行して SQL ファイルを実行します。

$ docker exec -it postgresql /bin/sh

# cd /sql
# psql -U postgres
postgres=# \i create_database.sql
postgres=# \q

# psql -U ksbylending_user ksbylending
ksbylending=> \i create_table.sql
ksbylending=> \i insert_data.sql
ksbylending=> \q

f:id:ksby:20181224181943p:plain f:id:ksby:20181224182031p:plain

gradle の build タスクを実行すると "BUILD SUCCESSFUL" のメッセージが出力されます。

f:id:ksby:20181224184630p:plain

IntelliJ IDEA から Tomcat を起動して Spring Actuator の health check を見ると db が PostgreSQL で認識されています。

f:id:ksby:20181224185844p:plain

以下の手順で画面から動作を確認してみましたが、こちらも問題ありませんでした。

  • ブラウザを起動して http://localhost:8080/ にアクセスしてログイン画面を表示します。tanaka.taro@sample.com / taro でログインします。
  • 検索対象図書館登録画面が表示されます。"東京都" で検索した後、一覧表示されている図書館から「国立国会図書館東京本館」を選択します。
  • ログアウトします。
  • ログイン画面に戻るので suzuki.hanako@test.co.jp / hanako でログインします。
  • 貸出希望書籍 CSV ファイルアップロード画面が表示されます。以下の内容が記述された CSV ファイルをアップロードします。

    "ISBN","書名"
    "978-4-7741-6366-6","GitHub実践入門"
    "978-4-7741-5377-3","JUnit実践入門"
    "978-4-7973-8014-9","Java最強リファレンス"
    "978-4-7973-4778-4","アジャイルソフトウェア開発の奥義"
    "978-4-87311-704-1","Javaによる関数型プログラミング"

  • 「貸出状況を確認しました」のメールが送信されるので、メールに記述されている URL にアクセスします。
  • 貸出申請画面が表示されます。3冊程「申請する」を選択して申請します。
  • ログアウトします。
  • 「貸出申請がありました」のメールが送信されるので、メールに記述されている URL にアクセスします。ログイン画面が表示されるので、tanaka.taro@sample.com / taro でログインします。
  • 貸出承認画面が表示されます。「承認」あるいは「却下」を選択して確定させます。
  • ログアウトします。
  • 「貸出申請が承認・却下されました」のメールが送信されるので、メールに記述されている URL にアクセスします。ログイン画面が表示されるので、suzuki.hanako@test.co.jp / hanako でログインします。
  • 貸出申請結果確認画面が表示されるので内容を確認します。

Docker で Flyway の環境を構築する

Docker で Flyway の環境を構築してみます。

src/main/resources の下に db/init、db/migration ディレクトリを作成します。

src/main/resources/db/init の下に sql/create_database.sql を移動します。

src/main/resources/db/migration の下に create_table.sql、insert_data.sql を移動し、以下のようにファイル名を変更します。

  • create_table.sql → V1__create_table.sql
  • insert_data.sql → V1.1__insert_data.sql

sql ディレクトリを削除します。ここまでの操作で以下のディレクトリ構成になります。

f:id:ksby:20181224230413p:plain

.env に Flyway のバージョン番号と設定を記述します。

..........
POSTGRESQL_VERSION=11.1
PGADMIN4_VERSION=3.6

FLYWAY_VERSION=5.2.4
FLYWAY_URL=jdbc:postgresql://postgresql/ksbylending
FLYWAY_USER=ksbylending_user
FLYWAY_PASSWORD=xxxxxxxx
  • 以下の4行を追加します。
    • FLYWAY_VERSION=5.2.4
    • FLYWAY_URL=jdbc:postgresql://postgresql/ksbylending
    • FLYWAY_USER=ksbylending_user
    • FLYWAY_PASSWORD=xxxxxxxx

docker-compose.yml を以下のように変更します。

  postgresql:
    image: postgres:${POSTGRESQL_VERSION}-alpine
    container_name: postgresql
    ports:
      - "5432:5432"
    volumes:
      - ./src/main/resources/db/init/create_database.sql:/docker-entrypoint-initdb.d/create_database.sql
    environment:
      - LANG=ja_JP.UTF-8
      - POSTGRES_PASSWORD=xxxxxxxx

  ..........

  flyway:
    image: boxfuse/flyway:${FLYWAY_VERSION}-alpine
    container_name: flyway
    volumes:
      - ./src/main/resources/db/migration:/flyway/sql
    command: -url=${FLYWAY_URL} -user=${FLYWAY_USER} -password=${FLYWAY_PASSWORD} -connectRetries=60 migrate
    depends_on:
      - postgresql
    # 下の3行は debug 用
    # うまく動かない時はコメントアウトを解除した後、
    # docker exec -it postgresql /bin/sh
    # で接続してから
    # flyway <command に記述した文字列>
    # を実行してみる
    #
    # entrypoint: /bin/sh
    # stdin_open: true
    # tty: true
  • postgresql コンテナの volumes の設定を以下のように変更します。
    • - ./sql:/sql を削除します。
    • - ./src/main/resources/db/init/create_database.sql:/docker-entrypoint-initdb.d/create_database.sql を追加します。create database 文は Flyway の実行前に実行しておく必要があるので postgresql コンテナの /docker-entrypoint-initdb.d ディレクトリの下に SQL ファイルを置いてコンテナ起動時に SQL ファイルを自動で実行させます(postgres/docker-entrypoint.sh 参照)。
  • flyway コンテナの設定を追加します。

docker-compose up -d コマンドを実行します。

f:id:ksby:20181224232024p:plain

pgAdmin4 でログインして ksbylending データベース及びテーブルが作成されていることを確認します。

f:id:ksby:20181224232230p:plain

build タスクを実行して "BUILD SUCCESSFUL" のメッセージが出力することも確認できました。

f:id:ksby:20181224233248p:plain

次回は。。。

Spring Boot アプリケーションにも Flyway を導入し、PostgreSQL のメトリックスを Prometheus+Grafana で見られるようにする予定です。

履歴

2018/12/24
初版発行。