Mac上のRacher Desktopでpostgisコンテナが起動しない場合の解決策

## はじめに

これまで[Docker Desktop](https://www.docker.com/ja-jp/products/docker-desktop/)を利用してきましたが、今回[Rancher Desktop](https://rancherdesktop.io/)への移行を検討していました。
移行の検証にあたり、Docker Desktop環境では動作していたが、Rancher Desktop環境ではうまくコンテナが起動しない現象に遭遇したので、その調査メモを公開します。
同じ現象で困っている人の参考になれば幸いです。
今回うまく動作しなかったのは[postgis/postgis:15-3.5⁠](https://hub.docker.com/r/postgis/postgis)のコンテナになります。

なお、結論だけ知りたい場合は、解決策まで読み飛ばしてください。

## 前提事項

まず、前提となる条件を記載します。

PC A

| 名前 | バージョン |
| ---- | ---- |
| Mac OS | 15.41 (Sequoia) |
| CPU | Apple M3 |
| Rancher Desktop | 1.18.2 |
| postgis/postgis | 15-3.5 |

Rancher Desktopのインストール等は省略しますが、コンテナエンジンはDockerを利用しています。
PC AにはもともとDocker Desktopがインストールされており、正常にpostgis/postgis:15-3.5のコンテナが起動していました。

## 検証内容詳細

### コンテナが正常に起動しない事象の再現方法

まず、以下のDockerfileを利用して検証します。

```Dockerfile:Dockerfile
FROM postgis/postgis:15-3.5
```

次に以下のコマンドを実行します。

```bash
$ docker build -t my-postgres:15 .
```

ここで以下のエラーがでます。

```
ERROR: failed to solve: postgis/postgis:15-3.5: failed to resolve source metadata for docker.io/postgis/postgis:15-3.5: no match for platform in manifest: not found
```

postgisのイメージはlinux/amd64対象しか提供していないためです。
なので、Dockerfileを以下に修正し再度ビルドします。

```Dockerfile:Dockerfile
FROM --platform=linux/amd64 postgis/postgis:15-3.5
```

ビルドが成功したらコンテナの起動コマンドを実行します。

```bash
$ docker run -d \
  --name some-postgres \
  -e POSTGRES_USER=myuser \
  -e POSTGRES_PASSWORD=mypassword \
  -e POSTGRES_DB=mydb \
  -p 5432:5432 \
  my-postgres:15
```

以下のようなエラーログが出ていることを確認できました。

```
(一部省略)...
initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    pg_ctl -D /var/lib/postgresql/data -l logfile start

waiting for server to start....2025-05-06 14:03:25.713 UTC [123] LOG:  starting PostgreSQL 15.12 (Debian 15.12-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
2025-05-06 14:03:25.718 UTC [123] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2025-05-06 14:03:25.732 UTC [131] LOG:  database system was shut down at 2025-05-06 14:03:25 UTC
 stopped waiting
pg_ctl: could not start server
Examine the log output.
```

次にDocker Desktopを利用した場合の、正常に起動するログを記載します。

```
(一部省略)...
initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    pg_ctl -D /var/lib/postgresql/data -l logfile start

waiting for server to start....2025-05-06 14:11:07.792 UTC [49] LOG:  starting PostgreSQL 15.12 (Debian 15.12-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
2025-05-06 14:11:07.793 UTC [49] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2025-05-06 14:11:07.799 UTC [52] LOG:  database system was shut down at 2025-05-06 14:11:07 UTC
2025-05-06 14:11:07.809 UTC [49] LOG:  database system is ready to accept connections
 done
server started
CREATE DATABASE

(一部省略)...
2025-05-06 14:11:10.355 UTC [1] LOG:  starting PostgreSQL 15.12 (Debian 15.12-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
2025-05-06 14:11:10.357 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-05-06 14:11:10.357 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2025-05-06 14:11:10.358 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2025-05-06 14:11:10.364 UTC [73] LOG:  database system was shut down at 2025-05-06 14:11:10 UTC
2025-05-06 14:11:10.374 UTC [1] LOG:  database system is ready to accept connections
```

前述のログの通り、Rancher Desktopの場合は、「pg_ctl: could not start server」というログの後にコンテナが終了していることがわかります。
各種ログなどを調査しましたが、直接的な原因は不明でした。
ただ、Docker DesktopとRancher Desktopでは、CPUエミュレーションの方法が異なっているため、この辺りで差異が発生しているのではないか、と考えています。

### 別のバージョンを指定した場合

PostgreSQL 16系のpostgis/postgis:16-3.5でも試してみましょう。

```Dockerfile:Dockerfile
FROM --platform=linux/amd64 postgis/postgis:16-3.5
```

```bash
$ docker build -t my-postgres:16 .

$ docker run -d \
  --name some-postgres \
  -e POSTGRES_USER=myuser \
  -e POSTGRES_PASSWORD=mypassword \
  -e POSTGRES_DB=mydb \
  -p 5432:5432 \
  my-postgres:16
```

起動後のログは以下になります。

```
(一部省略)...
initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    pg_ctl -D /var/lib/postgresql/data -l logfile start

waiting for server to start....2025-05-06 14:22:03.782 UTC [123] LOG:  starting PostgreSQL 16.8 (Debian 16.8-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
2025-05-06 14:22:03.787 UTC [123] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2025-05-06 14:22:03.804 UTC [131] LOG:  database system was shut down at 2025-05-06 14:22:03 UTC
2025-05-06 14:22:03.821 UTC [123] LOG:  database system is ready to accept connections
 done
server started
CREATE DATABASE

(一部省略)...
2025-05-06 14:22:11.726 UTC [1] LOG:  starting PostgreSQL 16.8 (Debian 16.8-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
2025-05-06 14:22:11.730 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-05-06 14:22:11.730 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2025-05-06 14:22:11.733 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2025-05-06 14:22:11.743 UTC [186] LOG:  database system was shut down at 2025-05-06 14:22:11 UTC
2025-05-06 14:22:11.756 UTC [1] LOG:  database system is ready to accept connections
```

結論から言うと正常にコンテナの起動ができています。
PostgreSQL 15系だと正常に起動せず、16系だと正常に起動しています。

## 解決策

前述の調査でpostgis/postgis:15-3.5をCPUエミュレートした場合にコンテナが正常に起動しないことが分かりました。
つまり、自分のPCでビルドすれば問題が解決するということになります。

以下から必要なファイルをダウンロードします。
https://github.com/postgis/docker-postgis/tree/master/15-3.5

必要なファイル一式

* Dockerfile
* initdb-postgis.sh
* update-postgis.sh

次に、以下のコマンドでビルド、コンテナの起動を実施します。

```bash
$ docker build -t custom-postgres:15 .

$ docker run -d \
  --name some-postgres \
  -e POSTGRES_USER=myuser \
  -e POSTGRES_PASSWORD=mypassword \
  -e POSTGRES_DB=mydb \
  -p 5432:5432 \
  custom-postgres:15
```

上記コマンド実行後に正常にコンテナが起動していることが分かります。
また、以下のコマンドでデータベースに接続することが可能です。
※下記コマンド実行には別途psqlコマンドのインストールが必要です。

```bash
$ psql -h localhost -p 5432 -U myuser -d mydb
```

## 最後に

Appleシリコン製Macの環境差異問題はかなり解決されつつありますが、今回のような事象も起きることがあります。
その場合に、コンテナを独自でビルドする、という視点を持っていれば今回の事象に対しても対応できるので一つの引き出しとして持っていると役に立つ場面があるのではないかなと思います。