Flask + Nginxでお手軽Webアプリ公開

# はじめに
備忘録も兼ねてます。
とりあえず自宅サーバを運用して、自分が楽しむことを目標としてます。

# 本題
## Flaskアプリを用意しよう
なんでも良いです。
動作確認とかしやすいように、html, css, jsを使うアプリとし、flask側と通信するようにしておくと良いでしょう。

ただし、以下のようにprefixを参照できるようにしておこう。
今回の内容であれば`x_prefix`だけで十分だが、セキュリティを考えるとこのままでOK。
```python
from werkzeug.middleware.proxy_fix import ProxyFix

app = Flask(__name__)
app.wsgi_app = ProxyFix(
    app.wsgi_app,
    x_for=1, x_proto=1, x_host=1, x_prefix=1
)
```

そして、gunicornで起動しておきましょう。
```
gunicorn -w 2 -b 127.0.0.1:8000 main:app
```
みたいな感じで。

## Nginxの設定を書く
Flaskの設定に合わせて記述する。
以下のように、locationと`X-Forwarded-Prefix`を組み合わせることで、複数のflaskアプリを使えるようになる。
```conf:nginx.conf
events{
  worker_connections 1024;
}

http{
  server{
    listen 80;
      server_name localhost;

      location /myapp {
        add_header Cache-Control "no-store, no-cache, must-revalidate";
        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $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-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Prefix /make10;
      }
}
```

あとは、この設定ファイルを適用するだけ。
```
sudo cp nginx.conf /etc/nginx/nginx.conf && sudo nginx -s reload
```

## ngrokで公開してアクセス
```
ngrok http 80 
```

上記コマンドを実行し、表示されたドメインにアクセスして、作成したアプリが表示されれば完了。
```text:アクセスするURL例
https://example.com/myapp
```

## 複数アプリを使えるようにする
nginxの設定をコピペで増やせばOK。
起動するアプリのポート番号は被らないように注意する。
以下の例では、8000, 8001, 8002としている。
```conf:例
events{
  worker_connections 1024;
}

http{
  server{
    listen 80;
      server_name localhost;

      location /myapp {
        add_header Cache-Control "no-store, no-cache, must-revalidate";
        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $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-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Prefix /make10;
      }

      location /secondapp {
        add_header Cache-Control "no-store, no-cache, must-revalidate";
        proxy_pass http://127.0.0.1:8001/;
        proxy_set_header Host $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-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Prefix /make10;
      }

      location /thirdapp {
        add_header Cache-Control "no-store, no-cache, must-revalidate";
        proxy_pass http://127.0.0.1:8002/;
        proxy_set_header Host $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-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Prefix /make10;
      }
}
```

# 免責事項
ngrokは開発用のツールなので、本運用で使うのはやめましょう。
セキュリティとか色々ガバガバなので危険です。
なお、この記事を参考にして問題が発生しても私は責任を負いません。
あくまで自己責任でお願いします。

# 参考記事
[flask公式のnginxでの使い方記事](https://flask.palletsprojects.com/en/stable/deploying/nginx/)
[flask公式のProxyに関する記事](https://flask.palletsprojects.com/en/stable/deploying/proxy_fix/)

**special thanks**
Claude Opus 4