MinIO サーバー用の NGINX プロキシ構成

# サーバ構成

今回構築した環境は専用DNSを使用しブラウザからのアクセスにはMnIOのコンソール画面を表示。APIへのリクエストには通常通りの処理を行ってもらう。こういった制御を行いうようにしました。Dockerを用いてそれぞれ構築してます。
大まかな流れとしては
ブラウザ →　Nginx → MinIO(ブラウザからのアクセスか判断) → リダイレクト → コンソール
といった流れです。

## Nginxサーバ

初めに今回設定したconfを紹介いたします。
尚、コメントしてるのは公式が提案してる設定を日本語翻訳を行ってます。

```conf
server {
    listen       80;
    listen       [::]:80;
    server_name  minio.example.com;
    charset      utf-8;

    # ヘッダーに特殊文字を許可する
    ignore_invalid_headers off;
    # 任意のサイズのファイルをアップロードできるようにします。
    # ファイルサイズを特定の値に制限するには、1000mなどの値を設定します。
    client_max_body_size 0;
    # バッファリングを無効にする
    proxy_buffering off;
    proxy_request_buffering off;

    # どうやら以下の行は、DNSルックアップのキャッシュを防ぐかもしれない。
    # Docker DNSを経由して、リクエストごとにnginxに名前解決をさせる。
    # Docker DNSを経由して名前解決させる。
    set $upstream "minio";

    location / {
        proxy_pass http://{minioサーバip}:9000;
        proxy_set_header Host               $http_host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;

        proxy_connect_timeout 300;
        # デフォルトはHTTP/1、キープアライブはHTTP/1.1でのみ有効
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        chunked_transfer_encoding off;
    }

    # Minio Console (UI)
    location /console/ {
        rewrite ^/console/(.*)$ /$1 break;
        proxy_pass http://{minioサーバip}:9090;

        proxy_set_header    Host                $http_host;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto   $scheme;
        proxy_set_header    X-NginX-Proxy       true;

        proxy_connect_timeout 300;

        # これは、ハッシュされる正しいIPを渡すために必要である。
        real_ip_header X-Real-IP;


        # 2023年1月以降にリリースされたMinIOのバージョンでウェブソケットをサポートするため
        # デフォルトは HTTP/1, キープアライブは HTTP/1.1 でのみ有効
        proxy_http_version 1.1;
        proxy_set_header    Upgrade     $http_upgrade;
        proxy_set_header    Connection  "upgrade";
        # 環境によってはCORSエラーが発生する可能性があります (Kubernetes + Nginx Ingress)
        # 以下の行のコメントを解除して、Originリクエストに空の文字列を設定します。
        # proxy_set_header Origin ''；
        chunked_transfer_encoding off;
    }
}
```
この設定はMnIOが提示してるNGINX プロキシをもとに少し変更を加えたものとなります。
実際に公式の設定をそのまま使用したところURLを叩いたところ画面は表示されるのですが、画像やコンソール画面のスタイル等が一切表示されませんでした。
error.logを確認したところ以下のエラーが出力されていました。
```log
"GET /ws/objectManager HTTP/1.1" 400 295 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" "-" GET /ws/objectManager HTTP/1.1 6e2e7399a501 0.001 20 1280 1180
```
なので少し公式が提示してる設定から変更する必要がありました。
以下公式の情報と解決するに至った質問を共有いたします。

公式設定

https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html

解決に至った質問、回答

https://stackoverflow.com/questions/72020904/minio-console-not-accessible-behind-nginx-reverse-proxy

## MinIO (Dockerでの設定)

```yml
minio:
    container_name: minio
    image: minio/minio:RELEASE.2023-10-07T15-07-38Z
    command: ["server", "/data", "--address", ":9000", "--console-address", ":9090"]
    ports:
        - "9000:9000"
        - "9090:9090"
    environment:
        - MINIO_ROOT_USER=minio_root
        - MINIO_ROOT_PASSWORD=minio_password
        - MINIO_BROWSER_REDIRECT_URL=http://minio.example.com/console/
        - MINIO_SERVER_URL=http://minio.example.com/
```

**environment**

MINIO_BROWSER_REDIRECT_URL
上記設定ではブラウザからのアクセスに対してリダイレクト先の設定です。
`/console/`と指定してるのでNginxが9090ポートへアクセスしてます。

MINIO_SERVER_URL
 MinIO サーバーのホスト名を指定してます。

# 最後に
S3としても使用できるMinIOはかなりありがたくlocal環境でも結構使用する場面が多いです。今回はNginxをALBに見立てて構築する流れの一環でコンソール画面も制御しました。なかなか面白かったので是非MnIO使う際はやってみてください。