皆さんこんにちは、小幡です。
今回の記事は、EC2(Amazon Linux 2023)を使用して、Nginx, Gunicorn, Djangoの導入についての備忘録です。
最も単純で明快と思われる方法で、1つずつをインストールしては実行確認するという形式を取っています。
Nginx, Gunicorn, Djangoの連携はベストプラクティス的な扱われ方をしている印象で、それらをまとめてデプロイする方法などをよく見かけるのですが、改めてこれらについて基礎知識を固めようと思いました。
自分自身への備忘録的な記事なので、検証を行っていないところや、間違いもあると思いますのでご注意ください。
EC2 Amazon Linux 2023
まず、もっとも根底となるインスタンスについてですが、今回はAmazon Linuxを選択しています。
これはUbuntuと比較するとアップデートが早いので、本番環境などではなく実験的に使うことが多いようですが、AWSサービスとの相性も良いとのことなので、RDSへの連携も考えているので、一旦はこちらにします。
本番環境へのサービスのデプロイなどもいずれ真剣に考えなければならないことですが、現時点では長期的なサービス運用の可能性はとても低いので、Amazon Linuxを使用します。
万が一サービスを長期運用するような機会が訪れたら、その時は喜んで何とかするしかないですね。
印象的なのが、パッケージ管理が「yum」ではなく、「dnf」を使うところです。ちなみにUbuntuでは「opt」です。
あとssh接続するときのユーザ名がec2-userです。微妙に接続方法が違ったりするので、その都度AWSコンソールの接続方法例を確認するか、AWSの接続サービスを使用すれば詰まることなく接続ができるはずです。
私も最初はssh接続するだけでそれなりに時間がかかってしまいました。
単純にEC2を立ち上げてssh接続すると行っても、キーペアの作成だったり、セキュリティグループの設定だったりと、うまく行かない箇所がいくつかあります。一度やり方を覚えてしまえば、インスタンスを終了(削除)して、後日同じ事をやってみるとすんなり出来るようになっているものです。
やはりこういったインフラ系の作業は事前のテストと、手順書の作成が重要だと改めて感じました。ただ、Iacを用いてインフラ作成をコードに落とし込めていれば、手順書の作成や操作ミスが減るので、Iacの導入も確実に進められるようにしておきたいですね。
以上が改めてEC2インスタンスをAWSマネジメントコンソールで作成してssh接続までの記録です。以降では、ここまでの作業を「作業A」と呼ぶことにします。
続いて、Nginxの導入と確認したことについてみていきます。
Nginxの導入と確認
ここからは、作成したEC2インスタンスにssh接続(作業A)できた状態からのスタートです。
NginxはWebサーバ、リバースプロキシとして、負荷分散や静的ファイルの提供などを行う場所です。
Amazon LInux 2023 で使用するコマンドについては、常に最新のものを参照した方が良いと考えています。
私が確認した時には、以下のようなコマンドでGunicornの導入ができました。
# パッケージリストの更新
sudo dnf update -y
# Nginx のインストール
sudo dnf install -y nginx
# Nginx の起動
sudo systemctl start nginx
# OS再起動時に自動起動するように設定
sudo systemctl enable nginx
Gunicornの状態について確認するために、以下コマンドを実行しました。
sudo systemctl status nginx
# Active: active (running) と表示されていれば成功です。
もっとも単純な導入と動作確認は以上です。
他にも各種設定などがありますが、今回はここまでです。
すべてEC2インスタンスの中で導入と確認が完結していますので、本当にこれで出来たのかな?と不安になる部分もありますが、activeな状態であれば問題ないと考えています。他にもログの確認などいろいろと動作確認する方法はあると思いますが、一旦はここまでとします。
Gunicornの導入と確認
ここからは、作成したEC2インスタンスにssh接続(作業A)できた状態からのスタートです。
Gunicornはアプリケーションサーバとして、リクエストされたDjango本体の処理を行う場所です。
GunicornはPythonで実行されるため、Pythonの仮想環境を作成し、その中で作業をします。
# 必要パッケージのインストール
sudo dnf install -y python3-pip
# プロジェクトディレクトリの作成
mkdir ~/my_app && cd ~/my_app
# 仮想環境の作成と有効化
python3 -m venv venv
source venv/bin/activate
# Gunicorn のインストール
pip install gunicorn
# インストール済みか確認
pip freeze
以上で、作成したvenvと言う名前の仮想環境の作成とアクティベート、Gunicornの導入が完了しました。仮想環境で作業しているので、この環境から抜けるとGunicornが導入されていないように見えますが、再度仮想環境に入ればちゃんとインストールされていることが確認できるはずです。
仮想環境に入っている状態で、app.pyを作成します。このファイルはGunicornの動作確認をするために用意する最も単純なアプリケーションのファイルです。
まず、ファイルを作成します。
vim app.py
ここで以下のコードを記述します。
def app(environ, start_response):
data = b"Hello, Gunicorn on Amazon Linux 2023!\n"
start_response("200 OK", [
("Content-Type", "text/plain"),
("Content-Length", str(len(data)))
])
return [data]
保存した後、以下コマンドでGunicornを起動させます。
# 8000番ポートで起動
gunicorn --bind 0.0.0.0:8000 app:app
最後に動作確認をしますが、EC2インスタンスに設定されているセキュリティグループでHTTPからのリクエストが通るように修正します。
そのごブラウザからパブリックIPへリクエストを実行すると以下のような画面が表示できました。

これでGunicronの導入と動作確認が完了しました。
最後の動作確認では実際のリクエストとレスポンスの処理を実行しているため、セキュリティグループの見直しが必要です。もしも、Webブラウザでエラーが発生している場合は、セキュリティグループの設定でGunicornにたどり着く前にアクセス拒否されている可能性が高いので見直してみましょう。
特にパブリックIPはインスタンスを作成するたびに変化することなど、ミスをしやすい所が多数ありますので、ご注意ください。
Djangoの導入と確認
ここからは、作成したEC2インスタンスにssh接続(作業A)できた状態からのスタートです。
Djangoはデータベースとのやり取りやビジネスロジックを行う場所です。
今回はもっとも単純な構成で、導入と動作確認を行いますので、データベースはデフォルトのSQLiteのまま、マイグレーションは実行しません。
Gunicornの時と同様で、Pythonの仮想環境を作成し、その中で作業をすることにします。
# プロジェクトディレクトリの作成(既存のものがあればそれを使用)
mkdir -p ~/my_project && cd ~/my_project
# 仮想環境の作成と有効化
python3 -m venv venv
source venv/bin/activate
# Django と Gunicorn のインストール
pip install django gunicorn
# インストールできたか確認
pip freeze
Djangoでプロジェクトを作成します。
django-admin startproject myproject .
vimで設定ファイルを開きます。
vim myproject/settings.py
全てのアクセスを許可します。ここはテストなので全てを許可します。ファイルを下にスクロールすると「ALLOWED_HOSTS」という設定項目が見えてきますので以下のように設定を変更します。
ALLOWED_HOSTS = ['*']
保存したら、以下のコマンドで開発用サーバでの起動を実行します。
python manage.py runserver 0.0.0.0:8000
再度セキュリティグループのHTTPについての設定を確認し、Webブラウザでアクセスしてみます。
ロケットが飛んでいれば、動作確認は成功です。
今回は、先ほど記載したGunicornを使用せず、開発サーバを利用した動作確認をしましたので、そこの違いがWebブラウザ上では感じ取れませんが、認識として開発サーバで実行していることを知っておくことが重要だと考えています。
以上で、Djangoの導入と動作確認は完了です。
まとめ
この備忘録では、EC2 Amazon Linux 2023, Nginx, Gunicorn, Djangoの導入と動作確認について記載しました。
これらについては、本来それぞれを連携させて効率的なシステムとするものですが、今回は勉強のためにそれぞれを単独で導入し動作確認をしています。
これを実施したことにより、それぞれがどんな役割をしていて、どんな風に今後連携させていくのかのイメージが明確にできるようになったと感じています。
次回は、これらの導入についてInfrastructure as Code (IaCをとして、CloudFormationを使い自動化を進めていく方法について記載したいと考えています。
以上です。
