LoginSignup
4
5

More than 1 year has passed since last update.

uvicornとnginxでwebアプリケーションの環境構築をしました。

Last updated at Posted at 2021-04-20

はじめに

はじめまして。
komegoroです。

自然言語処理分野の機械学習エンジニアをフリーランスとしてやっています。
普段は学習モデルの構築や検証をやっており、なかなかインフラやUI周りをやる機会がないので、
簡単なWEBアプリケーションを作ってAWSでリリースしようと思いました。

その第一歩として、WEBアプリケーションが見れるようにまでの環境を構築したので、
知識整理も兼ねて投稿します。
初めての環境構築のため、推奨されない or 非効率な やり方があるかと思いますが、
ご指摘いただけると嬉しいです。

紹介する範囲

この記事で紹介する範囲は、AWSのEC2インスタンス生成後から、WEBアプリケーションが表示されるまでです。
AWSの登録方法やEC2インスタンスの生成方法は紹介していません。
また、WEBアプリケーションの作成については触れません。

環境

主要なもののみ記載します。
starletteなどはfastapiインストール時に一緒にインストールするため省略します。

インスタンス
・AWSのEC2 Amazon Linux 2

linux上でインストールするもの
・Python (僕の環境では3.7.9)
・nginx

Python上でインストールするもの
・fastapi (僕の環境では0.63.0)
・uvicorn (僕の環境では0.13.4)

作業手順

アプリケーションサーバー側の設定

  1. Python3のインストール
  2. Pythonのライブラリのインストール
  3. WEBアプリケーションファイルの配備
  4. systemdによるWEBアプリケーションの起動

WEBサーバー側の設定

  1. nginxのインストール
  2. nginxの設定

実施

※EC2はAmazon Linux 2です。
※ec2-userでログインしています。

WEBアプリケーションサーバー側の設定

1.Python3のインストール

sudo yum install python3
でPython3をインストールします。

2.Pythonのライブラリのインストール

sudo pip3 install fastapi uvicorn
でインストールします。

3.WEBアプリケーションファイルの配備

今回用いるファイルは、

example1.py
import uvicorn
import example2
import example3


if __name__ == "__main__":
    uvicorn.run(app=example2.app)
example2.py
from fastapi import FastAPI
from starlette.requests import Request


app = FastAPI(
    title="タイトル",
    description="ここに詳細を書きます",
    version="0.1"
)


def index(request: Request):
    return {"hello": "world"}
example3.py
import example2

example2.app.add_api_route("/", example2.index, methods=["GET"])

以上の3ファイルです。

この3ファイルを/home/ec2-user/test_appに配備します。

python3 /home/ec2-user/test_app/example1.py

このコマンドを実行することで、
127.0.0.1:8000{"hello":"world"}と記載されたページが表示されるようになります。
ただ、このコマンドではコマンドラインを閉じたら、コマンドも終了してしまうので、
裏で動き続けるようにsystemdを利用します。

4.systemdによるWEBアプリケーションの起動

/etc/systemd/system/test_app.serviceを作成します。
中身は以下です。
※変数の意味については他記事を参照ください。

test_app.service
[Unit]
Description=release test_app
After=network.target

[Service]
User=ec2-user
Group=nginx
WorkingDirectory=/home/ec2-user/test_app
ExecStart=/usr/bin/python3 example.py

[Install]
WantedBy=multi-user.target

作成後、
sudo systemctl start test_app
sudo systemctl status test_app
を実行すると、

[ec2-user@ip-172-31-1-197 test_app]$ sudo systemctl status test_app
● test_app.service - release test_app
   Loaded: loaded (/etc/systemd/system/test_app.service; static; vendor preset: disabled)
   Active: active (running) since Tue 2021-04-20 10:05:32 UTC; 5s ago
 Main PID: 2858 (python3)
   CGroup: /system.slice/test_app.service
           └─2858 /usr/bin/python3 example1.py

Apr 20 10:05:32 ip-172-31-1-197.ap-northeast-1.compute.internal systemd[1]: Started release test_app.
Apr 20 10:05:32 ip-172-31-1-197.ap-northeast-1.compute.internal systemd[1]: Starting release test_app...
Apr 20 10:05:32 ip-172-31-1-197.ap-northeast-1.compute.internal python3[2858]: INFO:     Started server process [2858]
Apr 20 10:05:32 ip-172-31-1-197.ap-northeast-1.compute.internal python3[2858]: INFO:     Waiting for application startup.
Apr 20 10:05:32 ip-172-31-1-197.ap-northeast-1.compute.internal python3[2858]: INFO:     Application startup complete.
Apr 20 10:05:32 ip-172-31-1-197.ap-northeast-1.compute.internal python3[2858]: INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

となり、裏で上手く起動できました。
これでWEBアプリケーション側の設定が終わったので、WEBサーバー側の設定をしていきます。

WEBサーバー側の設定

1.nginxのインストール

nginxのインストールコマンドは
sudo amazon-linux-extras install nginx1
です。

2.nginxの設定

/etc/nginx/conf.d/test_app.confを作成します。
中身は以下です。

server {
  listen 80;               # ポート番号80番にアクセスされたら
  server_name <"パブリック IPv4 アドレス" or "パブリック IPv4 DNS">;
#  http://<"パブリック IPv4 アドレス"> or http://<"パブリック IPv4 DNS"> にアクセスされたら

  location / {
    proxy_pass http://127.0.0.1:8000; # test_appの起動場所に移動
    proxy_redirect                          off;
    proxy_set_header Host                   $host;
    proxy_set_header X-Real-IP              $remote_addr;
    proxy_set_header X-Forwarded-Host       $host;
    proxy_set_header X-Forwarded-Server     $host;
    proxy_set_header X-Forwarded-Proto      $scheme;
    proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
  }
}

作成後、sudo service nginx startを実行すると、
http://<"パブリック IPv4 アドレス"> or http://<"パブリック IPv4 DNS">
にアクセスすることで{"hello":"world"}と記載されたページが見られるようになります。

おわりに

今回はAWSのEC2インスタンス生成後から、WEBアプリケーションが表示されるまで、
WEBサーバーとアプリケーションサーバーの構築を行いました。
私自身、なぜこの作業が必要なのか、をまだ理解できておらず、ただの作業手順書になってしまいましたが、
今後追記か別記事で投稿していきたいと思います。
読んでいただきありがとうございました。

4
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5