4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Python + Flask + MongoDB を利用した Web API の作成と Azure VM + Nginx への配置(ホロライブの動画配信予定を収集 その3)

Last updated at Posted at 2020-12-08

はじめに

前回(https://qiita.com/kerobot/items/41f266dd52988f9bb68e)は、ホロライブの配信予定や動画情報を収集する仕組みを Azure VM の Ubuntu に配置して定期的に実行されるようにしました。

今回は、Azure VM の Ubuntu の MongoDB から、ホロライブの配信予定や動画情報を取得する Web API を作成し、Azure VM (Ubuntu) + Nginx + gunicorn へ配置してみます。

まずは、ローカル環境で Web API を作成して動作を確認したうえで、Azure VM (Ubuntu) + Nginx + gunicorn へ配置します。

  • Nginx : Webサーバー(今回はリバースプロキシとして利用)
  • gunicorn : WSGI アプリケーションを起動させる WSGI サーバー
  • WSGI(ウィスギー) : Web サーバーとWeb アプリケーション(フレームワーク)を接続するためのインターフェース

最終的にやりたいこと

ここ最近、毎日のように閲覧している バーチャル YouTuber プロダクション「ホロライブ」などの、動画配信予定を定期的にデータベースに格納し、それを Web API で参照して閲覧する Android アプリを作りたい。

  1. 動画配信予定を収集するためのプログラムの作成(完了)
  2. 収集した動画配信予定を格納するためのデータベースの作成と収集の自動化(完了)
  3. 格納した動画配信予定を参照するための Web API の作成(今回)
  4. Web API を参照して動画配信予定を閲覧する Android アプリの作成

やったこと

今回は、やりたいこと 3 の「格納した動画配信予定を参照するための Web API の作成」を行いました。

AppService を利用して Web API を配置したかったのですが、いろいろ(後述)あって断念し、結果として Azure VM (Ubuntu) に、Nginx + gunicorn を導入して配置しました。

img04.jpg

  1. ローカル環境の準備

    • pyenv (pyenv-win) が利用できることを確認
    • Poetry が利用できることを確認
    • MongoDB の接続確認
  2. プロジェクトの準備

    • Poetry を利用してプロジェクトの作成とパッケージのインストール
    • pyenv を 利用して Python のバージョンをセット
    • git の初期化
    • .gitignore の作成
    • .env の作成
  3. プログラムの作成

    • .env からの設定情報の取得
    • ホロジュールから取得した情報を保持
    • Flask を利用した Web API モジュールの作成
  4. ローカル環境での実行

    • lounch.json の作成
    • プログラムのデバッグ実行
    • Postman を利用した Web API の動作確認
    • Nginx のコンフィグファイルの作成
    • ファイル構成
  5. Azure AppService の利用

    • 今回は断念
  6. Azure VM 環境の準備

    • pyenv が利用できることを確認
    • Poetry が利用できることを確認
    • MongoDB の接続確認
  7. プログラムの配置

    • プログラムの配置と設定
    • .env の作成
    • プログラムの動作確認
  8. Nginx の導入と Web API の公開

    • Nginx の導入
    • コンフィグファイルを指定してリバースプロキシの実行
    • リバースプロキシ経由の動作確認
    • ローカル環境からの動作確認

ローカル環境の準備

下記構成の環境を用意しました。

  • Windows 10 Pro 1909 x64
  • Python 3.8.5 x64
  • PowerShell 7.1 x64
  • Visual Studio Code 1.51.1 x64
  • Git for Windows 2.27.0 x64
  • MongoDB 4.4.1 x64

pyenv (pyenv-win) が利用できることを確認

参考:Windows 10 で Python のインストールから Poetry と pyenv の利用

> pyenv --version
pyenv 2.64.2

Poetry が利用できることを確認

参考:Windows 10 で Python のインストールから Poetry と pyenv の利用

> poetry --version
Poetry version 1.1.0

MongoDB の接続確認

参考:Windows 10 に MongoDB をインストールして Python から利用する

> mongo --version
MongoDB shell version v4.4.1
Build Info: {
    "version": "4.4.1",
    "gitVersion": "ad91a93a5a31e175f5cbf8c69561e788bbc55ce1",
    "modules": [
        "enterprise"
    ],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "windows",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}

ホロライブの配信予定や動画情報を格納している holoduledb への接続確認

参考:Python3でWebスクレイピングとYouTube Data APIとMongoDB(ホロライブの動画配信予定を収集 その2)

> mongo localhost:27017/holoduledb -u owner -p
MongoDB shell version v4.4.1
> show collections
holodules
> db.holodules.find().sort({"datetime":-1});
{ "_id" : ObjectId("5f85996f7fc0cba6f1309217"), "key" : "HL0204_20201014_193000", "video_id" : "LiItELTkkko", "datetime" : "20201014 193000", "name" : "癒月ちょこ", "title" : "【#カレーメシWEEK】ちょこ先生が味変えアレンジカレーメシ作ってみ たら【ホロライブ/癒月ちょこ】", "url" : "https://www.youtube.com/watch?v=LiItELTkkko", "description" : "サブ垢→https://www.youtube.com/channel/UCp3tgHXw_HI0QMk1K8qh3gQ◎2周年記念グッズ期間限定発売決定!ご購入はコチラ⇊https://hololi" }
...
> exit

プロジェクトの準備

Poetry と pyenv を利用してプロジェクトの作成やパッケージのインストール

poetry を利用してプロジェクトを作成します。

> poetry new holoapi

プロジェクトのディレクトリに移動します。

> cd holoapi

ディレクトリとファイルの構成を下記のようにしておきます。

holoapi
├ config
├ models
├ pyproject.toml
└ README.md

念のため、pyenv をアップデートしておきます。

> pyenv update

インストール可能な Python のバージョンを確認します。

> pyenv install -l

インストールされている Python を確認します。

> pyenv versions

Python 3.8.5 がインストールされていない場合はインストールします。

> pyenv install 3.8.5

ローカル(プロジェクトディレクトリ内)で利用する Python をセットします。

> pyenv local 3.8.5

切り替わったかを確認します。

> python -V
Python 3.8.5

セットした Python に切り替わらない場合は、rehash で shim コマンドを更新します。

> pyenv rehash

これにより、$HOME/.pyenv/shims/ 配下のコマンドが更新され、セットした Python に切り替わります。

poetry を利用してパッケージを pyproject.toml に追加しインストールします。

gunicorn は Windows 環境で動作しませんが、後ほど Azuru VM の Ubuntu に配置した際に利用するため、ここでパッケージを追加しておきました。

> poetry add pylint
> poetry add python-dotenv
> poetry add pymongo
> poetry add Flask
> poetry add gunicorn

パッケージがインストールされるとともに、pyproject.toml が下記のように更新されました。

pyproject.toml にパッケージを記述したうえで poetry install を実行しても良いです。

[tool.poetry.dependencies]
python = "^3.8"
pylint = "^2.6.0"
python-dotenv = "^0.15.0"
pymongo = "^3.11.1"
Flask = "^1.1.2"
gunicorn = "^20.0.4"

poetry を利用して Python のバージョンを確認してみます。

> poetry run python -V
Python 3.8.5

git の初期化

git を初期化しておきます。

> git init

.gitignore の作成

.gitignore ファイルを作成し、除外対象を設定しておきます。

> ni .gitignore
__pycache__/
*.egg-info/
*.egg
.env
.venv
env/
venv/
.python-version

.env の作成

MongoDB の接続情報などを設定しておくためのファイルを作成します。

> ni .env
MONGODB_USER = "<user>"
MONGODB_PASSWORD = "<password>"
MONGODB_HOST = "<localhost:27017>"

プログラムの作成

.env から取得した設定情報を保持するクラス

config/settings.py ファイルを作成します。

今回は Flask の config 関連を利用せず、これまでに利用してきたクラスを使いまわしています。

import os
from dotenv import load_dotenv

class Settings:
    def __init__(self, envpath):
        # .env ファイルを明示的に指定して環境変数として読み込む
        self.__dotenv_path = envpath
        load_dotenv(self.__dotenv_path)
        # 環境変数から設定値を取得
        self.__mongodb_user = os.environ.get("MONGODB_USER")
        self.__mongodb_password = os.environ.get("MONGODB_PASSWORD")
        self.__mongodb_host = os.environ.get("MONGODB_HOST")

    # mongodb の ユーザー
    @property
    def mongodb_user(self):
        return self.__mongodb_user

    # mongodb の パスワード
    @property
    def mongodb_password(self):
        return self.__mongodb_password

    # mongodb の ホスト:ポート
    @property
    def mongodb_host(self):
        return self.__mongodb_host

ホロジュールから取得した情報を保持するクラス

models/holodule.py ファイルを作成します。

こちらも Flask-MongoEngine やモデルの仕組みを利用せず、これまでに利用してきたクラスを使い回し、オブジェクトと辞書を変換するメソッドを追加しています。

import datetime

class Holodule:
    codes = {
        "ときのそら"  : "HL0001",
        "ロボ子さん" : "HL0002",
        "さくらみこ" : "HL0003",
        "星街すいせい" : "HL0004",
        "夜空メル" : "HL0101",
        "アキ・ローゼンタール" : "HL0102",
        "赤井はあと" : "HL0103",
        "白上フブキ" : "HL0104",
        "夏色まつり" : "HL0105",
        "湊あくあ" : "HL0201",
        "紫咲シオン" : "HL0202",
        "百鬼あやめ" : "HL0203",
        "癒月ちょこ" : "HL0204",
        "大空スバル" : "HL0205",
        "大神ミオ" : "HL0G02",
        "猫又おかゆ" : "HL0G03",
        "戌神ころね" : "HL0G04",
        "兎田ぺこら" : "HL0301",
        "潤羽るしあ" : "HL0302",
        "不知火フレア" : "HL0303",
        "白銀ノエル" : "HL0304",
        "宝鐘マリン" : "HL0305",
        "天音かなた" : "HL0401",
        "桐生ココ" : "HL0402",
        "角巻わため" : "HL0403",
        "常闇トワ" : "HL0404",
        "姫森ルーナ" : "HL0405",
        "獅白ぼたん" : "HL0501",
        "雪花ラミィ" : "HL0502",
        "尾丸ポルカ" : "HL0503",
        "桃鈴ねね" : "HL0504",
        "魔乃アロエ" : "HL0505"
    }

    def __init__(self, video_id="", datetime=None, name="", title="", url="", description=""):
        self.__video_id = video_id
        self.__datetime = datetime
        self.__name = name
        self.__title = title
        self.__url = url
        self.__description = description

    # キー
    @property
    def key(self):
        _code = Holodule.codes[self.name] if self.name in Holodule.codes else ""
        _dttm = self.datetime.strftime("%Y%m%d_%H%M%S") if self.datetime is not None else ""
        return _code + "_" + _dttm if ( len(_code) > 0 and len(_dttm) > 0 ) else ""

    # video_id
    @property
    def video_id(self):
        return self.__video_id

    @video_id.setter
    def video_id(self, video_id):
        self.__video_id = video_id

    # 日時
    @property
    def datetime(self):
        return self.__datetime

    @datetime.setter
    def datetime(self, datetime):
        self.__datetime = datetime

    # 名前
    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name

    # タイトル(Youtubeから取得)
    @property
    def title(self):
        return self.__title

    @title.setter
    def title(self, title):
        self.__title = title

    # URL
    @property
    def url(self):
        return self.__url

    @url.setter
    def url(self, url):
        self.__url = url

    # 説明(Youtubeから取得)
    @property
    def description(self):
        return self.__description

    @description.setter
    def description(self, description):
        self.__description = description

    # ドキュメントから変換
    @classmethod
    def from_doc(cls, doc):
        holodule = Holodule(doc['video_id'], 
                            datetime.datetime.strptime(doc['datetime'], '%Y%m%d %H%M%S'), 
                            doc['name'], 
                            doc['title'], 
                            doc['url'], 
                            doc['description'])
        return holodule

    # ドキュメントへ変換
    def to_doc(self):
        doc = { 'key': str(self.key),
                'video_id': str(self.video_id),
                'datetime' : str(self.datetime.strftime("%Y%m%d %H%M%S")),
                'name' : str(self.name),
                'title' : str(self.title),
                'url' : str(self.url),
                'description' : str(self.description) }
        return doc

Flask を利用した Web API モジュールの作成

app.py ファイルを作成します。

今回は、Web API を作成するためのフレームワークとして、軽量なウェブアプリケーションフレームワークである Flask を利用してみました。
Web API として動作させるための最低限の実装としています。

from flask import Flask, jsonify, request, abort, make_response
from pymongo import MongoClient
from os.path import join, dirname
import json
from urllib.parse import quote_plus
from config.settings import Settings
from models.holodule import Holodule

# Settings インスタンス
settings = Settings(join(dirname(__file__), '.env'))

# MongoDB 接続情報
mongodb_user = quote_plus(settings.mongodb_user)
mongodb_password = quote_plus(settings.mongodb_password)
mongodb_host = "mongodb://%s/" % (settings.mongodb_host)

# MongoDB 接続認証
client = MongoClient(mongodb_host)
db = client.holoduledb
db.authenticate(name=mongodb_user,password=mongodb_password)

# Flask
app = Flask(__name__)
# JSONのソートを抑止
app.config['JSON_SORT_KEYS'] = False

# 動作確認用
@app.route('/')
def index():
    return 'holoapi'

# ホロジュール配信予定の取得
@app.route('/Holodules/<string:date>', methods=['GET'])
def get_Holodules(date):
    if len(date) != 8:
        abort(500)

    # MongoDB から年月日を条件にホロジュール配信予定を取得してリストに格納
    holodule_list = []
    for doc in db.holodules.find({"datetime": {'$regex':'^'+date}}).sort("datetime", -1):
        holodule = Holodule.from_doc(doc)
        holodule_list.append(holodule)

    if len(holodule_list) == 0:
        abort(404)

    # オブジェクトをもとに辞書を構築してJSONとして返却
    data = {}
    for holodule in holodule_list:
        doc = holodule.to_doc()
        data[doc['key']] = doc
    result = {
        "result":len(holodule_list),
        "data":data
    }
    # UTF-8コード、Content-Type は application/json
    return make_response(jsonify(result))
    # UTF-8文字、Content-Type は text/html; charset=utf-8
    # return make_response(json.dumps(result, ensure_ascii=False))

# エラーハンドラ:404
@app.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': 'Not found'}), 404)

# エラーハンドラ:500
@app.errorhandler(500)
def internal_server_error(error):
    return make_response(jsonify({'error': 'Internal Server Error'}), 500)

if __name__ == "__main__":
    app.run()

ローカル環境での実行

lounch.json の作成

Visual Studio Code で launch.json を作成しておきます。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        }
    ]
}

プログラムのデバッグ実行

Visual Studio Code でデバッグ実行します。

コマンドラインから実行する場合は、下記のように実行します。

> poetry run python app.py

ローカルサーバーが既定のポート 5000 で起動します。

 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Ctrl + C で終了できます。

Postman を利用した Web API の動作確認

Postman を利用して、作成した Web API にアクセスしてみます。
GET の URL のみ指定し、Query Params は指定なしです。

http://127.0.0.1:5000/Holodules/20201011

JSON レスポンスボディが取得できました。

img01.jpg

jsonify を利用しているため、Content-Type は application/json となっています。

img02.jpg

このような感じです。

{
    "result": 26,
    "data": {
        "HL0501_20201011_230000": {
            "key": "HL0501_20201011_230000",
            "video_id": "NKFFXwZx8hw",
            "datetime": "20201011 230000",
            "name": "獅白ぼたん",
            "title": "【アソビ大全】るしあ先輩と今日はアソビつくす大全!【ホロライブ/#るししし】",
            "url": "https://www.youtube.com/watch?v=NKFFXwZx8hw",
            "description": "るしあ先輩と遊びつくすよ!感想は #るししし でつぶやいてね!この動画およびライブは、任天堂著作物の利用許諾を受けて配信しています。🦋潤羽るしあhttps://twitter.com/uruharus"
        },
        "HL0002_20201011_223800": {
            "key": "HL0002_20201011_223800",
            "video_id": "XFO_4O-aBGM",
            "datetime": "20201011 223800",
            "name": "ロボ子さん",
            "title": "【耐久SP 】35万人記念にみんなで出すぞ35万ダメージ!!APEX参加型#2【ホロライブ/ロボ子さん】",
            "url": "https://www.youtube.com/watch?v=XFO_4O-aBGM",
            "description": "#RBC350K耐久SP  #APEX #ホロライブ34・35万人記念をまとめて耐久すぺしゃる!!カジュアルでみんなとの通算ダメージで35万を目指すよ!クロスプレイとPCのみで時間分けます!#RBC3"
        },
        ...
    }
}

ここまでで、ローカル環境での Web API の作成が完了しました。

Nginx のコンフィグファイルの作成

Azure VM (Ubuntu) + Nginx + gunicorn の環境へ配置するため、事前に Nginx のコンフィグファイルを作成しておきました。
config/nginx.conf ファイルを作成し、ポート 8080 を http://127.0.0.1:8888 へ転送するためのリバースプロキシを設定しているだけです。

worker_processes  1;

events {
    worker_connections 512;
}

http {
    server {
        listen  8080;
        server_name HOLOAPI;
        charset UTF-8;

        proxy_set_header    Host    $host;

        location / {
            proxy_pass http://127.0.0.1:8888;
        }
    }
}

ファイル構成

holoapi
├ .venv
├ .vscode
|  └ launch.json
├ config
|  ├ __init__.py
|  ├ nginx.conf
|  └ settings.py
├ models
|  ├ __init__.py
|  └ holodule.py
├ .env
├ .gitignore
├ .python-version
├ app.py
├ poetry.lock
├ pyproject.toml
└ README.md

Azure AppService の利用

Azure AppService を利用して Flask アプリケーションを配置し、Azure VM (Ubuntu) の MongoDB にアクセスしようとしたのですが、Azure AppService と Azure VM をネットワーク接続するためには VNet統合 を利用する必要があり、VNet統合 は Azure AppService のスタンダードプラン以上でなければいけないため今回は断念しました。

とはいえ、Azure AppService と VNet統合 を利用するために、仮想ネットワークのサブネットを切り替えたり、実際に試してみたりもしたので、あらためて挑戦してみたいと思います。

Azure VM 環境の準備

参考:Azure VM の Ubuntu 20.04(LTS) で Python3 と MongoDB を利用する(ホロライブの動画配信予定を収集 その2の続き)

下記構成の環境を用意しました。

  • Azure VM の Ubuntu 20.04(LTS)
  • Python 3.8.6 x64
  • Git 2.25.1 x64
  • MongoDB 4.4.2 x64

ここからは、Azure VM の Ubuntu に SSH で接続して作業を行っています。

pyenv が利用できることを確認

$ pyenv --version
pyenv 1.2.21

Poetry が利用できることを確認

$ poetry --version
Poetry version 1.1.4

MongoDB の接続確認

$ mongo --version
MongoDB shell version v4.4.2
Build Info: {
    "version": "4.4.2",
    "gitVersion": "15e73dc5738d2278b688f8929aee605fe4279b0e",
    "openSSLVersion": "OpenSSL 1.1.1f  31 Mar 2020",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "ubuntu2004",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}

ホロライブの配信予定や動画情報を格納している holoduledb への接続確認

> mongo localhost:27017/holoduledb -u owner -p
MongoDB server version: 4.4.2
> show collections
holodules
> db.holodules.find().sort({"datetime":-1});
{ "_id" : ObjectId("5fcee53448b99985d55d7346"), "key" : "HL0304_20201208_200000", "video_id" : "sjKsUZ8wM-8", "datetime" : "20201208 200000", "name" : "白銀ノエル", "title" : "【#白銀ノエル謎肉牛丼】新発売『カップヌードル謎肉牛丼』の食レポ 配信します!", "url" : "https://www.youtube.com/watch?v=sjKsUZ8wM-8", "description" : "▼カップヌードル 謎肉牛丼 商品情 報https://www.nissin.com/jp/products/items/10245▼カップヌードル 謎肉牛丼 オンラインストアhttps://store." }
...
> exit

プログラムの配置

github からプログラムを clone して配置と設定を行います。

プログラムの配置と設定

$ cd ~
$ git clone https://github.com/kerobot/holoapi.git holoapi
$ cd holoapi

pyenv を利用して、ローカル環境の Python のバージョンを切り替えます。

$ pyenv local 3.8.6

Poetry を利用して、Python 仮想環境やパッケージをインストールします。

$ poetry install

Python 仮想環境の pip を更新しておきます。

$ /home/mcuser/holoapi/.venv/bin/python -m pip install --upgrade pip
Collecting pip
  Downloading pip-20.2.4-py2.py3-none-any.whl (1.5 MB)
     |████████████████████████████████| 1.5 MB 5.4 MB/s
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 20.2.2
    Uninstalling pip-20.2.2:
      Successfully uninstalled pip-20.2.2
Successfully installed pip-20.2.4

.env の作成

MongoDB の接続情報などを設定しておくためのファイルを作成します。

$ cp .env.sample .env
MONGODB_USER = "<user>"
MONGODB_PASSWORD = "<password>"
MONGODB_HOST = "<localhost:27017>"

プログラムの動作確認

まずは、Flask の開発用サーバーを利用してプログラムを実行してみます。

$ poetry run flask run

開発用サーバーが起動しました。

 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

curl コマンドで GET してみます。

$ curl "http://127.0.0.1:5000/"
holoapi

Web API が応答してくれました。
Ctrl + C で終了しておきます。

この方法はあくまでも開発用なので、WSGI サーバーのひとつである gunicorn を利用してプログラムを実行してみます。

$ poetry run gunicorn -w 1 -b 0.0.0.0:8888 app:app

WSGI サーバーが起動しました。

[2020-12-08 13:53:52 +0900] [35797] [INFO] Starting gunicorn 20.0.4
[2020-12-08 13:53:52 +0900] [35797] [INFO] Listening at: http://0.0.0.0:8888 (35797)
[2020-12-08 13:53:52 +0900] [35797] [INFO] Using worker: sync
[2020-12-08 13:53:52 +0900] [35833] [INFO] Booting worker with pid: 35833

curl コマンドで GET してみます。

$ curl "http://127.0.0.1:8888/"
holoapi

gunicorn でも、Web API が応答してくれました。

Nginx の導入と Web API の公開

Nginx を導入して、リバースプロキシを設定してみました。

Nginx の導入

Nginx をインストールします。

$ sudo apt install nginx

Nginx のバージョンを確認します。

$ nginx -v
nginx version: nginx/1.18.0 (Ubuntu)

サーバーが起動していることを確認します。

$curl 'http://localhost'
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
...

プロセスはこのような状態で、daemon として起動しています。

$ ps ax | grep nginx
  10278 ?        Ss     0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
  11918 ?        S      0:00 nginx: worker process
  11919 ?        S      0:00 nginx: worker process

daemon の停止などはこのように行います。

$ sudo nginx –s stop    すぐに停止
$ sudo nginx -s quit    リクエスト処理が完了した後に停止
$ sudo nginx -s reopen  ログファイルの再オープン
$ sudo nginx -s reload  設定の再読み込み

コンフィグファイルを指定してリバースプロキシの実行

既定の daemon はこのままにしておき、Web API のためのリバースプロキシを実行します。

まずは、Web API の config ディレクトリにある設定ファイルを確認します。

$ sudo nginx -t -c ~/holoapi/config/nginx.conf
nginx: the configuration file /home/mcuser/holoapi/config/nginx.conf syntax is ok
nginx: configuration file /home/mcuser/holoapi/config/nginx.conf test is successful

設定ファイルは問題なさそうです。

Nginx をリバースプロキシとして実行します。

$ sudo nginx -c ~/holoapi/config/nginx.conf

プロセスはこのような状態になりました。

$ ps ax | grep nginx
  10278 ?        Ss     0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
  11918 ?        S      0:00 nginx: worker process
  11919 ?        S      0:00 nginx: worker process
  14863 ?        Ss     0:00 nginx: master process nginx -c /home/mcuser/holoapi/config/nginx.conf
  14864 ?        S      0:00 nginx: worker process

参考までに pid を指定した停止方法

$ cat /var/run/nginx.pid
14863
$ sudo kill -QUIT $( cat /var/run/nginx.pid )

リバースプロキシ経由の動作確認

gunicorn で Web API が実行され、Nginx のリバースプロキシが起動している状態で、動作を確認します。

$ curl 'http://10.1.1.4:8080/'
holoapi

リバースプロキシ経由で Web API が応答してくれました。

ローカル環境からの動作確認

Azure のネットワークセキュリティゲートウェイに、受信セキュリティ規則を追加しています。

ローカル環境の Postman を利用して、Azure VM の Web API にアクセスしてみます。
GET の URL のみ指定し、Query Params は指定なしです。

http://test.example.co.jp:8080/Holodules/20201208

Azure VM の Web API から JSON レスポンスボディが取得できました!

img03.jpg

おわりに

Azure AppServcie を利用する予定が、Nginx + gunicorn になるなど変更はありましたが、なんとか Web API を公開することができました。
課題もたくさんあるので、継続して取り組んでいきます。

  • Flask アプリケーションとしてあるべき作り込みが甘いので作り直したい。
  • Flask-JWT などを利用して、Web API のトークン認証を行いたい。
  • SSL無しは早めにどうにかしたい。
  • Azure AppService (Azure Functions とかも) をあらためてチャレンジしたい。
4
3
0

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
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?