プログラミング

ConoHa VPSでFlaskとNginxを使ってWeb アプリをブラウザで確認しよう!

こんにちは、MSKです。
ConoHa VPSでFlaskのアプリをNginxを使ってブラウザから確認できるまでを解説します。
Linuxの扱いにまだ慣れていないため結構苦労したので、備忘録です。

環境など

  • CentOS 7.8
  • メモリ 512MB
  • CPU 1Core
  • SSD 30GB
  • Python 3.6.8

ConoHa VPS はGMOグループによって運営されている、VPSのホスティングサービスです。
使ってみての印象としては

  • VPSを始めるのが簡単
  • 失敗したり、気に食わなかったりするとすぐに削除して作り直せる
  • コントロールパネルが使いやすい

です。

rootでログインして、adduserでuserというユーザーを作っておきます。
以下、sshでuserによりログインしています。
また、userでsudoできるようにしています。

Python・Flaskのインストール

Python3がインストールされていないので、Python3をインストールします。

よく次のコマンドでインストールできるとありましたが、僕はできなかったので違う方法でインストールしました。

yum install -y https://centos7.iuscommunity.org/ius-release.rpm
yum install -y python36u python36u-libs python36u-devel python36u-pip

次のコマンドを打って、検索をかけてPython3があるか確認します。

yum search python

ある場合は、次のコマンドでPython3をインストールすることができます。

sudo yum install python36

インストールができたら念のためバージョンを確認します。

python3 --version

インストールしたバージョンが返ってきたらOKです。

次にFlaskをインストールします。
ディレクトリは /var/www/test_app/としています。

所有権を現在ログインしているuserにしておきます。

sudo chown -R user:user /var/www/test_app/

仮想環境を準備します。

sudo python3 -m venv venv

仮想環境が準備できたら、有効化します。

source /venv/bin/activate

有効化できたら、Flaskをインストールします。

pip install Flask

インストールが完了したらテストコードを書いていきます。
ファイル名はrun.pyとしています。(/var/www/test_app/run.py)

from flask import Flask

app = Flask(__name__)

@app.route("/")
def main():
  return "Main Page!"

@app.route("/hello/")
def hello():
  return "Hello Page!"

if __name__ == "__main__":
  app.run(host="0.0.0.0" ,port=5000)

ソースを書き終わったら、動作確認を行います。

python run.py

次のコマンドで動作しているか確認します。
htmlでMain Pageと返ってくるとOKです。

curl localhost:5000

Nginxのインストール

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

/etc/yum.repos.d/nginx.repoに次のように記述します。

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

保存したら、次のコマンドでインストールを行います。

sudo yum install nginx

test_appを公開するための設定を行います。
/var/www/test_app/にtest_app_nginx.confとしてファイルを作成して、次のように記述します。

server {
  listen      80;
  server_name xxx.xxx.xxx.xxx(サーバーのIP);
  charset     utf-8;
  client_max_body_size 75M;
  
  location / { try_files $uri @test_app; }
  location @test_app {
    include uwsgi_params;
    uwsgi_pass unix:/var/www/test_app/test_app_uwsgi.sock;
  }
}

/etc/nginx/nginx.confの初期の設定では設定ファイルは/etc/nginx/config.d/からconfという拡張子で読み込むことになっていると思いますので、シンボリックリンクでおきます。

sudo ln -s /var/www/test_app/test_app_nginx.conf /etc/nginx/conf.d/

Nginxを起動します。

sudo systemctl start nginx

ブラウザでhttp://(サーバーのipアドレス)/にアクセスすると502 Bat Gatewayと表示されると思います。
(uwsgiがまだ準備できていないため)

uwsgiのインストール

/opt/にpythonの仮想環境を準備して、そこにuwsgiをインストールしていきます。

Webで検索すると次のコマンドでインストールできるとありますが、僕は出来ませんでした。

pip install uwsgi

いろいろと調べてみて、次のコマンドを打つとよいとありましたが、それでもうまくいきません。

yum groupinstall "Development Tools"
yum install kernel-devel kernel-headers

出てきていたエラーを見ると以下のように出ていました。
(エラーの一部です。)

plugins/python/uwsgi_python.h:2:20: fatal error: Python.h: No such file or directory
     #include 
                        ^
    compilation terminated.
    In file included from plugins/python/pyutils.c:1:0:
    plugins/python/uwsgi_python.h:2:20: fatal error: Python.h: No such file or directory
     #include 
                        ^

このエラーで調べていると次のコマンドが有効だという記事がいくつかありました。

sudo yum install python3-devel

これを試してみるも再度エラーがでます。
エラーの内容を見ると、Permission Defined・・・
権限がないのかなと思い、/opt/venv/に対して、次を行いました。

sudo chown -R user:user /opt/venv/

もう一度、pip install uwsgiをやってみると、ようやくインストールが完了しました。

/var/www/test_app/にuwsgiの設定ファイルtest_app_uwsgi.iniを作ります。
ログの出力先を/var/log/uwsgi/としてディレクトリを作成し、所有権を今ログインしているユーザーにしておきます。

[uwsgi]
base = /var/www/test_app
app = run
module = %(app)
virtualenv = /var/www/test_app/venv
pythonpath = %(base)
socket = /var/www/test_app/%n.sock
chmod-socket    = 666
callable = app
logto = /var/log/uwsgi/%n.log

複数アプリを考えがえているので、エンペラーにより起動します。
/etc/uwsgi/vassals/にtest_app_uwsgi.iniを配置します。

sudo ln -s /var/www/test_app/test_app_uwsgi.ini /etc/uwsgi/vassals

最終的にはLinuxサーバーの起動時から実行されたいので、サービス化しておきます。

/etc/systemd/system/にuwsgi.serviceというファイルを作り、次のように記述します。

[Unit]
Description=uWSGI
After=syslog.target

[Service]
ExecStart=/opt/venv/bin/uwsgi --master --emperor /etc/uwsgi/vassals --die-on-term --uid username --gid username --logto /var/log/uwsgi/emperor.log
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

次のように起動します。

sudo systemctl daemon-reload
sudo systemctl start uwsgi

ブラウザでhttp://(サーバーのipアドレス)にアクセスするとMain Page!と表示されればOKです。
※http://(サーバーのipアドレス)/hello/にアクセスするとHello Page!と表示されます。

さいごに

ConoHa VPSを使用してFlaskとNginxでWebアプリを公開できる状態までを書いてきました。
CentOSについても初心者で、実際にサーバー構築をやったこともなかったので、かなり苦戦しました。
(たぶん、数ヶ月かかっています。)
いろんな記事をみて、試行錯誤してようやくここまで準備できたなという感じです。

いまからようやくWebサービスを公開していけますし、ある程度Webサービス公開したら次はGCPやAWSにも手を出したいなと思っています。

サーバー構築の際にかなり参考にさせてもらった記事

次のQittaの記事をかなり参考にさせてもらいました。
ただ、この記事のとおりにはいかなかったので、今回ブログに書いています。

https://qiita.com/yuucu/items/802549beb90fc8e9f228

ABOUT ME
MSK
九州在住の組み込み系エンジニアです。 2児の父親でもあります。 数学やプログラミングが趣味です。 最近Webプログラミングと曲面結び目理論にはまっています。