postgresql.conf をマウントするとGithubActions 上でエラーになる

`postgresql.conf` を Docker イメージで読み込まれていた場所にマウントした所、ローカルでは問題なく起動するが、 `Github Actions` 上でビルドが失敗するようになってしまった。


追加したボリュームの設定。

```diff:compose.yaml
   db:
     image: postgis/postgis:12-3.1-alpine
     .....
     volumes:
       - db:/var/lib/postgresql/data:cached
+      - ./config/postgresql.conf:/var/lib/postgresql/data/postgresql.conf
```

CIの設定は次の通りで、`docker compose up -d` で `db` コンテナが起動出来ずにビルド失敗している。
```yaml:ci.yml
      - name: Docker Image prune
        run: |
          docker compose up -d
          docker image prune -f
          docker compose down -v
```

```:エラー内容
 Container appserver-db-1  Error
 Container appserver-db-1  Error
 Container appserver-redis-1  Healthy
 Container appserver-redis-1  Healthy
dependency failed to start: container appserver-db-1 exited (1)
Error: Process completed with exit code 1.
```
ログがこれだけなのでなぜ落ちているのかよくわからない…。
試した事を順番に記載していく。

## 1.  追加したボリュームを削除して正常終了するか確認

 元々動いてた状態に戻すことなので必ず正常終了するはず。
正常終了するということは、追加したボリュームの記述に何かしら問題があるということ。
```diff
     volumes:
       - db:/var/lib/postgresql/data:cached
-      - ./config/postgresql.conf:/var/lib/postgresql/data/postgresql.conf
```
当然、問題なくビルドは成功した。

## 2. postgresのdata を:cached オプションにしていたので外す

ボリュームの記述は元に戻し、 `:cached` が影響するのかを確認した。
```diff
     volumes:
-      - db:/var/lib/postgresql/data:cached
+      - db:/var/lib/postgresql/data
+      - ./config/postgresql.conf:/var/lib/postgresql/data/postgresql.conf
```
エラーになった。

## 3. volumes の順番を変更してみる

ダメ元で定義順番で影響があるかもしれない。

```diff
     volumes:
-      - db:/var/lib/postgresql/data
       - ./config/postgresql.conf:/var/lib/postgresql/data/postgresql.conf
+      - db:/var/lib/postgresql/data:cached
```
エラーになった。

## 4. 2に戻し、ログを出力するステップを追加してみる

Webを検索していてログを出力するようなものがあったので試してみた。
```diff:compose.yaml
     volumes:
+      - db:/var/lib/postgresql/data
       - ./config/postgresql.conf:/var/lib/postgresql/data/postgresql.conf
-      - db:/var/lib/postgresql/data:cached
```

```diff:ci.yml
           docker compose up -d
           docker image prune -f
           docker compose down -v
-
+      - name: Postgres logs
+        if: always()
+        run: docker logs "${{ job.services.db.id }}"
```

参考にしてたページでは、 `ci.yml` 上で `service` を定義しており、今回の `docker compose` で動かしてるのとは状況が違う。実行するとコンテナが見つからず当然ログも出力されない。検討違いすぎた。

## 5. dbコンテナだけ先に起動してログ出力の変化をみる

```diff:ci.yml
       - name: Docker Image prune
         run: |
+          docker compose up db -d
           docker compose up -d
           docker image prune -f
           docker compose down -v
-      - name: Postgres logs
-        if: always()
-        run: docker logs "${{ job.services.db.id }}"
       - name: Check format with Rubocop
```
追加した行で失敗するだけで、変わらずエラーになる。
## 6. docker compose `-d` を外し、失敗時と成功時のログを比較する
```diff:ci.yml
       - name: Docker Image prune
         run: |
-          docker compose up db -d
-          docker compose up -d
+          docker compose up --exit-code-from web
+          docker compose logs
```

`--exit-code-from web` を設定したのはwebコンテナの終了コードを使うようにしたら問題なく起動するのかも？と考えたから。`docker compose logs` はもしかして上のコードで正常したらログがみれるのかもしれないと追加してみた。

（そもそも、`web` コンテナは `db` コンテナが起動するまで待つ依存関係があるので、 `--exit-code-from` で指定するのは間違ってる。）

失敗しているときは、 `db` コンテナの出力はここで止まる
```
db-1        | The files belonging to this database system will be owned by user "postgres".
db-1        | This user must also own the server process.
db-1        |
db-1        | The database cluster will be initialized with locale "en_US.utf8".
db-1        | The default database encoding has accordingly been set to "UTF8".
db-1        | initdb: error: directory "/var/lib/postgresql/data" exists but is not empty
db-1        | If you want to create a new database system, either remove or empty
db-1        | the directory "/var/lib/postgresql/data" or run initdb
db-1        | with an argument other than "/var/lib/postgresql/data".
db-1        | The default text search configuration will be set to "english".
db-1        |
db-1        | Data page checksums are disabled.
db-1        |
```

成功しているときは次のような出力になる。
```
db-1        | The files belonging to this database system will be owned by user "postgres".
db-1        | This user must also own the server process.
db-1        | 
db-1        | The database cluster will be initialized with locale "en_US.utf8".
db-1        | The default database encoding has accordingly been set to "UTF8".
db-1        | The default text search configuration will be set to "english".
db-1        | 
db-1        | Data page checksums are disabled.
db-1        | 
db-1        | fixing permissions on existing directory /var/lib/postgresql/data ... ok
db-1        | creating subdirectories ... ok
db-1        | selecting dynamic shared memory implementation ... posix
db-1        | selecting default max_connections ... 100
```

失敗時のログをみると、
```
db-1        | initdb: error: directory "/var/lib/postgresql/data" exists but is not empty
db-1        | If you want to create a new database system, either remove or empty
db-1        | the directory "/var/lib/postgresql/data" or run initdb
db-1        | with an argument other than "/var/lib/postgresql/data".
```
とあり、 `initdb` を実行する際にディレクトリが空でないためエラーになっている。

## 7. postgresql.confのマウント先を変更する

```diff:ci.yml
       - name: Docker Image prune
         run: |
-          docker compose up --exit-code-from web
-          docker compose logs
+          docker compose up -d
           docker image prune -f
```

```diff:compose.yaml
     volumes:
-      - db:/var/lib/postgresql/data
+      - db:/var/lib/postgresql/data:cached
+      - ./config/postgresql.conf:/etc/postgresql/postgresql.conf
     ports:
       - "${DC_DB_PORT:-5432}:5432"
     healthcheck:
@@ -36,6 +37,7 @@ services:
       interval: 1s
       retries: 5
       timeout: 60s
+    command: ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]
```

無事にGithub Actions上で成功するようになった。

## まとめ

思いつく順番で色々試したが、まずはログを出力(手順6)して、内容を確認するべきだった。
`postgresql.conf` を既存の場所から別の場所にマウントして、起動時にそちらを指定することで対応できた。
なぜローカルで成功してGithubActions上で失敗するのかは不明。
ボリュームのマウントタイミングが違うのだろうか。