DockerでPostgreSQLとSchemaSpyを使ってDBドキュメントを作成する（Apple M1チップ編）

# はじめに
EclipseとERMasterを用意したところで、そもそもドキュメント用意しているほどスケジュールに余裕が無いことに気づき、
ならばSchemaSpyで自動生成してしまえ！
・・・と言うことで、今更ながら初めてDockerで開発環境を構築しました。

その際、見事にApple　M1チップの洗礼を受けてハマってしまったので、備忘録としてここに記します。

# 環境
```terminal:OS
macOS Monterey 12.3
チップ Apple M1
```

```terminal:ディレクトリ構成
project directory/
 ├ docker-compose.yml
 ├ postgresql/
 │ └ Dockerfile
 └ schemaspy/
   └ Dockerfile
   └ config/
     └ schemaspy.properties
   └ output/
```

# Docker Desctop for Macのインストール
「Mac with Apple chip」を選択し、Docker　Desctopをインストールします。

https://hub.docker.com/editions/community/docker-ce-desktop-mac

```terminal:docker --version
Docker version 20.10.12, build e91ed57
```

# 日本語環境用PostgreSQL Dockerコンテナの準備

何も考えずにDockerHubからPostgreSQLの公式Dockerイメージをコピーしてきたところ、日本語言語（jp_JP.UTF-8）が設定できずに困りました。

どうやら、配布されているDockerイメージでは日本語環境が有効になってないようです。
下記のサイトを参考に、公式のDockerイメージをベースに日本語環境を有効化したイメージを作成しました。

https://terurou.hateblo.jp/entry/2016/11/27/193139

プロジェクトのディレクトリ内に「postgresql」ディレクトリを作成し、下記のようなDockerファイルを用意します。
PostgreSQLのバージョンは最新を指定しています。

```Dockerfile
FROM postgres:latest
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.utf8
```

名前とタグをつけてビルド。

```terminal
docker build -t postgres:latest .
```

# PostgresqlとPgAdminのDockerコンテナ作成

次にPostgresqlとPgAdminのDockerコンテナを作成します。
プロジェクトのディレクトリに戻り、下記のようなdocker-compose.ymlを作成してDockerコンテナを作成します。

```yml:docker-compose.yml
version: "3"

services:
  postgresql:
    image: postgres:latest
    container_name: "postgresql"
    restart: always
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      PGPASSWORD: password
      POSTGRES_DB: maindb
      DATABASE_HOST: localhost
    ports:
      - "5432:5432"
    volumes:
      - postgres:/var/lib/postgresql/data
  
  pgadmin:
    image: dpage/pgadmin4
    container_name: "pgadmin"
    restart: always
    ports:
      - 81:80
    environment:
      PGADMIN_DEFAULT_EMAIL: sample@example.com
      PGADMIN_DEFAULT_PASSWORD: password
    volumes:
      - pgadmin:/var/lib/pgadmin
    depends_on:
      - postgres

volumes:
  postgres:
  pgadmin:
```

コンテナを作成。

```terminal
docker-compose up -d
```

ブラウザからPgAdminへアクセスし、DBを構築していきます。
ちなみに構築したDBのDumpファイルは、下記のコマンドで出力可能です。（INSERT文込みのパターン）

```terminal
docker exec [container_name] pg_dump --column-inserts -U [user_name] [db_name] > maindb.dump.sql
```

今回の環境だと、[container_name]がpostgresql、[user_name]がpostgres、[db_name]がmaindbなので、下記のようになります。


```terminal
docker exec postgresql pg_dump --column-inserts -U postgres maindb > maindb.dump.sql
```

# SchemaSpyのDockerコンテナ作成

DBの準備もできたのでSchemaSpyの導入だ！

```terminal
docker run -v "$PWD/schema:/output" --net="host" schemaspy/schemaspy:6.1.0 -t pgsql \\
-host localhost:5432 -db maindb -u postgres -p password -connprops useSSL\\\\=false -all
```

またしても何も考えずにDockerHubからSchemaSpyの公式Dockerイメージをコピーしてきたところ、全く動かずに困り果てました。

どうやら、配布されているDockerイメージではM1チップのMacに対応していないようです。
下記のサイトを参考に、公式のDockerイメージをベースにM1チップに対応したイメージを作成しました。

https://qiita.com/pnpk/items/d308d96ef933312f8d9a

プロジェクトのディレクトリ内に「schemaspy」ディレクトリを作成し、下記のようなDockerファイルを用意します。

```Dockerfile
FROM openjdk:8u212-jdk-alpine

ENV DRIVER_URL https://repo1.maven.org/maven2/org/postgresql/postgresql/42.2.22/postgresql-42.2.22.jar
ENV APP_URL https://github.com/schemaspy/schemaspy/releases/download/v6.1.0/schemaspy-6.1.0.jar

WORKDIR /app

RUN apk --update add graphviz ttf-dejavu && \
    apk --update add --virtual .builddep tzdata wget libressl && \
    cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    wget -O postgresql-connector-java.jar ${DRIVER_URL} && \
    wget -O schemaspy.jar ${APP_URL} && \
    apk del .builddep && \
    rm -rf /var/cache/apk/*
```

Postgresqlの設定に合わせて、SchemaSpyのDB接続情報をまとめます。
「schemaspy」ディレクトリ内に「config」ディレクトリを作成し、下記のようなschemaspy.propertiesファイルを用意します。

```config:schemaspy.properties
# type of database. Run with -dbhelp for details
schemaspy.t=pgsql
# optional path to alternative jdbc drivers.
schemaspy.dp=/app/postgresql-connector-java.jar
# database properties: host, port number, name user, password
schemaspy.host=postgresql
schemaspy.port=5432
schemaspy.db=maindb
schemaspy.u=postgres
schemaspy.p=password
# output dir to save generated files
schemaspy.o=/output
# db scheme for which generate diagrams
schemaspy.schemas=share,public
```

SchemaSpyのオプションは下記を参照。
今回のDBには2つのscheme（shareとpublic）があるので、schemaspy.schemasオプションで指定しています。

https://schemaspy.readthedocs.io/en/v6.0.0/configuration.html

次にSchemaSpyと、SchemaSpyの出力結果をブラウザで確認できるようにNginxのDockerコンテナについて、先ほどのdocker-compose.ymlに追記します。
SchemaSpyの出力先は「output」ディレクトリを指定しています。

```yml:docker-compose.yml
version: "3"

services:
  postgresql:
    image: postgres:latest
    container_name: "postgresql"
    restart: always
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      PGPASSWORD: password
      POSTGRES_DB: maindb
      DATABASE_HOST: localhost
    ports:
      - "5432:5432"
    volumes:
      - postgres:/var/lib/postgresql/data
  
  pgadmin:
    image: dpage/pgadmin4
    container_name: "pgadmin"
    restart: always
    ports:
      - 81:80
    environment:
      PGADMIN_DEFAULT_EMAIL: sample@example.com
      PGADMIN_DEFAULT_PASSWORD: password
    volumes:
      - pgadmin:/var/lib/pgadmin
    depends_on:
      - postgres

  schemaspy:
    build: ./schemaspy
    image: schemaspy/schemaspy:6.1.0
    container_name: "schemaspy"
    volumes:
      - ./schemaspy/output:/output
      - ./schemaspy/config/schemaspy.properties:/app/schemaspy.properties:ro
    command: "java -jar schemaspy.jar"

  nginx_schemaspy:
    image: nginx
    container_name: "nginx_schemaspy"
    depends_on:
      - schemaspy
    ports:
      - "8080:80"
    volumes:
      - ./schemaspy/output:/usr/share/nginx/html:ro

volumes:
  postgres:
  pgadmin:
```

再びプロジェクトのディレクトリに戻ってコンテナを作成。

```terminal
docker-compose up -d
```

これでようやくSchemaSpyが動くようになりました。
Docker DesctopでSchemaSpyのDockerイメージを動かすと、「output」ディレクトリにファイルが出力されます。

# おわりに
Windows環境で構築すればよかったな、なんて後で思いましたが、なんとか環境が準備できたのでよかったです。