【入門】Docker + PostgreSQL Web操作＋ER図閲覧 環境構築

# 目標
- ローカルPC上でDockerを用いたpostgresqlのコンテナを作成する
- 作成したpostgresqlにCLIでログインする
- 構築したdockerdbで他の場所で運用中の既存dbを複製する
- adminerで作成したDBを操作する
- ER図を生成する

## 環境
- Windows10 wsl2 Ubuntu
- Docker version 20.10.17, build 100c701

## 前提
本記事はDockerの環境構築の手順は割愛します。

# 作業
### ローカルPC上でDockerを用いたpostgresqlのコンテナを作成する
1. YMLファイルを作成
 
   ``` docker-compose.yml
    version: '3.1'
    
    services:
    
      db:
        image: postgres:14
        restart: always
        environment:
          POSTGRES_PASSWORD: test
        volumes:
          - ./postgres14:/var/lib/postgresql/data
        ports:
          - 5432:5432
    
      adminer:
        image: adminer
        restart: always
        ports:
          - 8080:8080
   ```
    参考： 
    - https://hub.docker.com/_/postgres/
    - https://hevodata.com/learn/docker-postgresql/#step2
    - https://zenn.dev/re24_1986/articles/b76c3fd8f76aec
2. イメージ構築
    1で作成したdocker-compose.ymlのあるディレクトリで実行
    ```
    docker-compose build
    ```
3. コンテナ構築
    ```
    docker-compose up -d
    ```

### 作成したpostgresqlにCLIでログインする
1. 実行中のpostgresのコンテナIDを確認
    ```
    docker ps
    ```
1. コンテナに入る
    ```
    docker exec -it [コンテナID] bash
    ```
1. postgresへログイン
    ```
    psql -U postgres
    ```
### 構築したdockerdbで他の場所で運用中の既存dbを複製する
1. 下記サイトを参考に複製に必要なファイルを用意 （dump）
    ※dump作業は時にサーバーに過剰な負荷をかけるので、事前に容量を確認した方が良い。
    　確認方法は、本記下部の「利用するかもしれないpostgresテクニック」に記載。
[PostgreSQLのbackup, restore方法まとめ](https://qiita.com/rice_american/items/ceae28dad13c3977e3a8)
    ```
    pg_dump -Ft database名 > backup_file名
    ```
1. 用意した(dump)ファイルをローカルからdockerコンテナ内に移動
[dockerコンテナにファイルを転送する](https://qiita.com/buntafujikawa/items/04c3bdd93ac3520c53eb)

    ```
    docker cp [dumpしたファイルパス] [コンテナid or コンテナ名]: [コンテナ内のファイル名を含めたフルパス]
    ```

1. dockerコンテナ内で下記コマンドを実行して、複製（リストア）する。複製先のDBが存在していない場合は、作成してから実行してください。
    ```
    psql -d [複製先DB名] -f [dumpで作成したバックアップファイル] -U postgres
    ```


### adminerで作成したDBを操作する
1. ブラウザで下記URLにアクセス
http://localhost:8080/
1. 下記の内容で作製したDBへログイン

    - データベース種類: postgres
    - サーバ : db
    - ユーザ名: postgres
    - パスワード: test
    - データベース: postgres
1. adminerより適当なテーブルを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031888/e656dfdb-72fc-accb-30a9-9cc328ee0d83.png)
1. postgresへログインし、作製できている確認
    1. postgres上で下記コマンドを実行
        ```
        postgres=# \dt
                List of relations
         Schema | Name | Type  |  Owner
        --------+------+-------+----------
         public | user | table | postgres
        (1 row)
        ```
### ER図を生成する（後日追記）
- 手法
[Shemaspy](https://schemaspy.readthedocs.io/en/latest/index.html)を[Docker](https://hub.docker.com/r/schemaspy/schemaspy/)で構築して生成する
- 手順
1. schemaspy.propertiesをホームディレクトリ直下に作成
    ```
    # type of dtabase. Run with -dbhelp for details
    schemaspy.t=pgsql
    # optional path to alternative jdbc drivers.
    schemaspy.dp=path/to/drivers
    # database properties: host, port number, name user, password
    schemaspy.host=host.docker.internal
    schemaspy.port=5432
    schemaspy.db=db_name
    schemaspy.u=postgres
    schemaspy.p=test
    # output dir to save generated files
    schemaspy.o=output
    ```
1. 下記作成コマンドを実行
    ```
    docker run -v "$PWD/output:/output" -v "$PWD/schemaspy.properties:/schemaspy.properties" schemaspy/schemaspy:latest -debug
    ```
- エラー事例
    - schemaspy.hostを最初`schemaspy.host=localhost`でやったが失敗したので注意。
        https://qiita.com/skobaken/items/03a8b9d0e443745862ac
    - 下記のように指定したフォルダが作成できなかった
        ```
        ERROR - IOException
        java.io.IOException: Unable to create directory /output/tables
        ```
       上記のときは下記を実行
        1. rootに変更
            `sudo su`
        2. 対象のフォルダの権限を変更
            `chmod 777`
        3. 再度作成コマンドを実行
# 利用するかもしれないpostgresテクニック
### DB容量の確認の仕方
下記SQLをDBで実施することで、DBごとの使用容量を確認できる。
```
~=#SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database;
```
### コンテナ内でDBを複製する場合、下記をサーバーで実行
```
root@[コンテナid]:/tmp# pg_dump -Ft [複製元db名] -U postgres | pg_restore -d [複製先db名] -U postgres
```
※rootではpg_dumpが実行できないので、必ずpostgresアカウントを利用
# その他
### [Dockerで構築したpostgresDBにlaravelでmigrationする方法]()