EC2でのnginx設定メモ

以前、AWS EC2 に gunicorn と whitenoise を使用してWebアプリ(Django, React)を設定したので、今度はNginxを使用してみようと思います。
※個人用のメモレベルです

## 事前設定
・AWS EC2 インスタンスを立ち上げておく
・Webアプリのライブラリを requirements.txt に出力しておく
・WebアプリをGitHubにアップロードしておく

## EC2設定
```sh
# EC2へ接続
ssh -i "[セキュリティキー].pem" ec2-user@[EC2のPUBLIC_IP]
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/''

# 必要なライブラリインストール
sudo yum update -y
sudo yum install python3 -y
sudo yum install python3-pip -y
sudo yum install git -y
sudo yum install nginx

pip install gunicorn

# GitHubからwebアプリクローン作成
git clone https://github.com/[GitHub URL].git

pip install -r requirements.txt
```
セキュリティのポートを開けておく 443, 8000
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/91100c00-27d9-ea57-7207-97593afcc091.png)


## Gunicornテスト
```sh
# Webアプリのsettings.py
sudo nano settings.py

ALLOWED_HOSTS = ["EC2のパブリックIP"]

gunicorn StockKeeper.config.wsgi:application --bind 0.0.0.0:8000
```
`http://パブリックIP:8000` にアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/3818df0d-111d-395d-6bd5-ef3ef62e5678.png)
作成したWebアプリが表示されればOK(静的ファイルは表示できない)

# Nginx の設定
```sh
# 設定用のファイル読み込み
sudo nano /etc/nginx/nginx.config
- include /etc/nginx/conf.d/*.conf;
+ include /etc/nginx/sites-available/[Webアプリ名];

# 設定用ファイル作成
sudo mkdir /etc/nginx/sites-available
sudo mkdir /etc/nginx/sites-enabled

sudo nano /etc/nginx/sites-available/[Webアプリ名]
```
```sh: /etc/nginx/sites-available/[Webアプリ名]
server {
    listen 80;
    server_name [パブリックIPアドレス];
    return 301 https://$host$request_uri;  # HTTPからHTTPSにリダイレクト

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        alias /home/ec2-user/[Webアプリ名]/staticfiles/; # <-静的ファイルフォルダ
    }
}

server {
    listen 443 ssl;  # HTTPSのポート443をリッスン
    server_name [パブリックIPアドレス];

    # 自己署名証明書
    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

    location /static/ {
        alias /home/ec2-user/[Webアプリ名]/staticfiles/; # <-静的ファイルフォルダ
        try_files $uri $uri/ =404;  # ファイルが見つからない場合に404を返す
    }

    location / {
        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $host;
    }
}
```

# 自己署名証明書作成
HTTPS接続するために自己署名証明書の作成
```sh
sudo mkdir /etc/ssl/private

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/ssl/private/nginx-selfsigned.key \
    -out /etc/ssl/certs/nginx-selfsigned.crt
# いくつか質問があるがデフォルトでOK
```

# nginx 設定の反映とテスト
```sh
sudo ln -s /etc/nginx/sites-available/[Webアプリ名] /etc/nginx/sites-enabled
sudo nginx -t  # 設定テスト
sudo systemctl restart nginx

gunicorn config.esgi:application --bind 0.0.0.0:8000
```
gunicorn を起動して `http://パブリックIP` に接続
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/821ac24f-c6e9-d89c-07f9-b69f7bc1df95.png)

自己署名証明書を使用している為、メッセージが表示されるが無視してアクセス。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/37083e6c-78a5-4f86-eb89-4984705e391b.png)

作成したWebアプリ(静的ファイル)が表示されればOK

# 補足
静的ファイルが表示されない場合はファイルの実行権限が不足している可能性あり
```sh
sudo chmod -R 755 /home
```

# 最後に
Gunicorn を使用して Web アプリを公開しようとすると、静的ファイルの配信には追加のツールが必要になります。その選択肢として代表的なものが WhiteNoise と Nginx です。

WhiteNoise
WhiteNoise は Django に簡単に組み込むことができ、静的ファイルの配信を手軽に実現できます。そのため、小規模なプロジェクトや個人用のアプリに非常に適していると感じました。

Nginx
Nginx は細かな設定が可能で、リバースプロキシやセキュリティ対策を含む柔軟な構成が可能です。特に SSL/TLS の設定や静的ファイルのキャッシュなどに優れており、中〜大規模なプロジェクトに向いていると感じました。ただし、その分設定項目が多いため、初心者にはややハードルが高い面もあります。

今回作成した 個人の株式管理アプリ では、手軽さと要件を考慮し、WhiteNoise で十分という結論になりました！

プロジェクトの規模や用途に応じて、適切なツールを選択することが大切だと改めて実感しました(Nginx大変だった...)。