Lightsail + Nginx + Gunicorn で Django アプリのデプロイ

## はじめに
本記事は [AWS Advent Calendar 2022](https://qiita.com/advent-calendar/2022/aws) の22日目の記事です。

Djangoで[ブログアプリ](https://hotaru-tech.com/)を作ったので、AWS Lightsailを使ってデプロイしてみました。
初歩的な内容だとは思いますが、技術記事を書くのもWebアプリをデプロイしたのも初めてなので、備忘録も兼ねて紹介させてください。

Lightsailにはいくつかのテンプレートがあり、Djangoもそのテンプレートを使って簡単にデプロイできるのですが、
今回はテンプレートを使わずにデプロイしてみました。

## 参考文献

https://www.amazon.co.jp/%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E5%AD%A6%E3%81%B6-Python-Django%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-NEXT/dp/479817419X

基本的にこちらの本の通りに実装することでWebアプリを公開することができました。
一つ一つ丁寧に説明されているので、初心者でも比較的簡単に実装からデプロイまでできると思います。
こちらの本ではEC2を使ったデプロイ方法を紹介しています。
私の場合はこれをLightsailに置き換えました。
違いはインスタンスを生成するところくらいで、sshでインスタンスに接続した後はほぼ同じように設定することができました。

https://www.udemy.com/course/amazon-lightsail-laravel/

こちらの動画ではLaravelのデプロイ方法を紹介していますが、Lightsailのインスタンスを立ち上げるところまでは同じ操作ができるので参考にしました。
こちらも丁寧に分かりやすく説明されており、AWSの操作に慣れていない私でもインスタンスを立ち上げることができました。


## Lightsail + Nginx + Gunicorn のデプロイ方法

### インスタンスの作成

#### Lightsail のインスタンスを立ち上げる
Lightsail にアクセスしたら、"Create instance"のボタンを押します。
![create_instance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68178/cf192ddb-8fd9-58ff-b5c6-fff2ebabf39c.png)
設定画面に移動しました。
まずOSを選択していきます。

今回はLinux/Unixを選択します。
また、テンプレートは使わないのでOS onlyを選択します。
OSの種類はAmazon Linux 2を選択します。
![select_instance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68178/f0454ee8-2696-bd6c-957b-183f67863f04.png)

次に料金プランを選択します。
\\$3.5のスペックではちょっと心許なかったので、私は\\$5を選びました。
![instance_plan.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68178/f91e902b-bbba-56d3-0fa8-27b96a0ba3ba.png)

最後にインスタンスに名前を付けて"Create instance"のボタンを押します。
![create_instance2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68178/8b0c1ad5-56db-a6a5-be5c-f9fb3b10f4c5.png)

下図のように、Runningの状態になったらインスタンスの作成は完了です。
![running.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68178/ec9e33f2-0bde-e23b-4783-abac74189825.png)

#### Static IP アドレスを設定する
次に静的IPアドレスを作成し、インスタンスにアタッチします。
Networkingのタブに移動し、"Create static IP"を選択してください。
![create_static.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68178/f2373a39-c0d8-5c0a-4db7-cee2aa2ae6c5.png)

アタッチするインスタンスを選び、名前を付けたら"Create"ボタンを押してください。
![create_static2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68178/f275a692-c314-1073-54db-6a128c782ea1.png)

このように、インスタンスにStatic IPアドレスをアタッチすることができました。
![complete_static.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68178/19c3de60-e21c-73c2-3266-d7a793e9b444.png)

#### ファイアウォールの設定
デフォルトではHTTPとSSHの接続が可能な設定になっています。
HTTPSでのアクセスは必要な方は下記の手順でファイアウォールにHTTPS接続を追加してください。

余談ですが、この部分は参考にした本とUdemyには説明がなく、設定が漏れていたので、HTTPSの接続がうまくいかずハマりました。。
(本ではEC2のセキュリティグループの設定については記載があります。Lightsailでも同じことが必要だという認識が私になかっただけです。。)
また、テンプレートを使うとBitnamiで簡単に設定できるようで、UdemyではBitnamiを使った設定方法が紹介されていました。

では、今回実施したセキュリティグループの設定方法についてお伝えします。

もう一度Networkingのタブに移動し、IPv4 Firewallのところまで進んでください。
"+ Add rule"のところを押したら、ApplicationのドロップダウンリストからHTTPSを選び、"Create"を押します。
これでHTTPSでの接続が可能となりました。
![add_https.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68178/0b5e62f1-ee32-9694-45e7-7b5a9976bc72.png)



### SSHでインスタンスに接続する
インスタンスの準備が整ったので、SSH接続をして各種設定をしていきます。
本ではWindows/Macそれぞれの接続方法が説明されており、Windowsについては[Puttyを使った方法](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/putty.html)の説明がありました。
私はWindowsなのですが。標準でコマンドプロンプトで使えるsshコマンドで、Macの接続方法と同じように接続できました。
接続するためのコマンドは下記になります。

```
ssh <ユーザー名>@<ホスト名> -i <秘密鍵のパス> -p <ポート番号>
```

### Pythonのインストール

今回は本に倣ってPytyhon3.8をインストールしました。

```
sudo amazon-linux-extras install python3.8
```

プロジェクトはローカルで開発していて、gitにプッシュされている状態を前提とします。
gitからpullしてきてコードを配置したら、ローカル環境と同じようにPythonの環境を整えてください。

### Nginxのインストール

```
sudo amazon-linux-extras install nginx
```

nginx.confを修正していきます。
```
sudo vi /etc/nginx/nginx.conf
```

nginx.confの前半部分を下記のように書き換えてください。
```
server {
    listen 80;
    servser_name <Stataic IP>;
    root /usr/share/nginx/html;

    include /etc/nginx/default.d/*.conf;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass http://127.0.0.1:8000;
    }

    # これ以降はそのままにする
    error_page 404 ... 
}
```

Nginxの自動起動を設定するために、下記のコマンドを実行します。
```
sudo systemctl enable nginx.service
```

Nginxを起動するには下記のコマンドを実行してください。
```
sudo systemctl start nginx.service
```

### Gunicornのインストール

manage.py があるディレクトリに移動します。
Pythonの仮想環境を作っている場合は、仮想環境に入った状態にしてください。

Gunicornを起動するには下記のコマンドを実行します。

```
gunicorn --bind 127.0.0.1:8000 <Django Project>.wsgi -D
```

これでHTTPでのアクセスが可能になりました。
http://[Static IP] にアクセスしてみてください。

## 感想
筆者は普段組み込み系の専門なので、Webアプリをデプロイして公開するのは初めてでした。
同じような初心者の方の参考になれば幸いです。
作ったブログの方はまだまだ(主にデザインの)作りこみが必要ですが、年内に公開すること、Qiitaのアドベントカレンダーに投稿することを目標としていたので、なんとか間に合ってよかったです。
ブラッシュアップしていけるよう、これからも頑張っていきたいと思います。
また、今回は本に書いてあるコマンドやコードをほぼそのまま使っただけなので、それらがなぜ必要なのか、今後も整理して発信していきたいなと思います。