(VPSでつくる) 総括・変更履歴

長らくお疲れ様でした。
最後までご覧いただき誠にありがとうございました。

今回は、VPSの良い点、悪い点、引っかかりやすいポイントなどなど。
総括を行いたいと思います。

この記事は、VPSで作るPythonでのWebアプリ運用環境の総括記事です。
その他については上記ページをお読みください。

総括

Flaskを使ってみて、データベースを作ってみて、Webアプリをデプロイしてみて・・・と色々とやってきました。
今回の構成のメリット・デメリットを記載します。

メリット

VPSは安い

AWS、GCP、Azureと違いさすがに安い。
お試しで月600円程度なら、誰でも使えると思います。

VPSは設定できればすべてに対応できる。

VPSは知識があればすべての設定が可能です。
レンタルサーバーのように基礎設定が決まっていて、例えば「アップロード可能容量が少なくて使いづらい」のような事なありません。
※AWSやGCPも別途知識が必要ではありますが…

デメリット

管理コストが高くなりがち

レンタルサーバーは全てお任せですが、VPSはすべて自分でやるからこそのこのお値段です。
バグがあれば、セキュリティのミスがあれば対応し…
テストで立ち上げるだけなら、これは問題にはなりません。

セキュリティリスクが心配

SQLインジェクション、クロスサイトスクリプティングなど基礎的なセキュリティ対策は知識がなければできません。
Flaskをはじめとしたフレームワークである程度対応可能なものの、完全とは言えません。

CentOS7からの移行が必要

CentOS7がサポート終了になり、後継も存在しません。
そのため、移行が簡単でなければならないのですが・・・移行先はUbuntuが良いようです。

まとめると、小さなサービスをサクッと作るのには便利。
ユーザー数が多く、大きなサービスになってくると別の構成が必要そうという所ですね。

作者コメント

みなさま、完走お疲れ様でした!
私も完走できるとは思っていませんでした。

FlaskはPythonベースのフレームワークです。
そのため、データ分析のBIを作ったり、機械学習を埋め込んだりが非常に簡単にできます。
今後もこう言った記事を書いていきます。

変更履歴

2021.05.24 初版

2022.01.29 第2版

・様々な部位の手直し
・総括・変更履歴の記載(忘れていた)

(VPSでつくる) Let’s EncryptでVPS上のWebサイトをSSL(HTTPS)接続にしよう

連載第十五回目です。
いや~この連載、長かったですね。まとめに1か月近くかかりました。

今回は、これまで作ってきたVPS環境のWebサイトをHTTPS接続に切り替えます。
HTTPS接続に切り替えるために使う機能は、非常に簡単なのでLet’s Encryptにします。
HTTPS接続には独自ドメインが必要になりますので、そちらも併せて説明します。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
その他については上記ページをお読みください。

作業予定

下記の通り、作業を行います。

  1. 独自ドメイン取得
  2. 独自ドメイン反映
  3. SSH接続設定
  4. Let’s EncryptでWebサイトの設定を行う

独自ドメイン取得

簡単な手順で、最後の手順であるドメイン反映が行えるため、さくらのドメインで取得しました。別のサイトで取得していただいてもかまいませんが、ドメイン転入(さくらのドメイン)への申請が必要です。

転入がホントに面倒だった…orz

取得の具体的な方法については、さくらのドメインをご覧ください。

独自ドメイン反映

独自ドメインの変更の反映には少し時間が掛かるため、先に設定を行っておきます。

独自ドメインの設定(さくらのVPS設定マニュアル)の3.VPS側のネームサーバー設定を実施してください。

SSH接続設定

ファイアウォールを起動

さくらVPSのデフォルトでは、ファイアウォールがONになっていません。
VPSにログインし、まずはONにしておきます。

systemctl start firewalld.service
systemctl enable firewalld.service

自動起動設定もしておきましょう。

firewall-cmd --state

そうすると、httpアクセスも遮断されるため、以前の記事でデプロイしたアプリにアクセスできなくなります。
この間にVPSへのログインを切断するとログインできなくなるので注意してください。

パケットフィルタの停止

まず初めに、さくらのVPSコントロールパネルで、パケットフィルタを停止させておきます。

※こちらは必須ではありませんが、SSHのポート番号が22で固定されることが困る場合は実行必須です。

ファイアウォールの利用可能機能設定

とりあえず、HTTP接続とFTP接続、SSH接続は接続可能にしておきます。

sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=ftp --permanent
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload

TeraTermで公開鍵を作って反映する

Tera Termで公開鍵と秘密鍵を作成して、安全にSSH接続を行う方法(エンジニア足立のコーディング日記さんより)を参照ください。

作成したid_rsa.pubをアップロードしてます。

       
cd ~            
mkdir .ssh
chmod 700 .ssh
mv id_rsa.pub .ssh/authorized_keys
chmod 600 .ssh/authorized_keys

※さくらVPSのOSインストール時の機能として、id_rsa.pubを登録することもできます。

いったんログアウトして、今度は公開鍵認証でログインします。
パスフレーズはVPSサーバーのユーザーではなく、公開鍵を作った時のパスワードを入力してください。

セキュリティのための設定

rootユーザーは強すぎる権限を持つため、VPSへのログインを別ユーザーで行います。
そのため、新規ユーザーを先に作成します。
加えて、平文パスワードでのログイン認証も不可能にしましょう。

ユーザーの作成とsudo設定

rootユーザーの代わりのユーザー(例:sakura)を作成します。

useradd sakura

ユーザー(sakura)のパスワードを設定します。

passwd sakura

ユーザー(sakura)にsudo権限を与えます。

usermod -G wheel sakura
設定ファイルの変更

SSH設定ファイル(/etc/ssh/sshd_config)を変更します。

PasswordAuthentication no

※今回はポート番号は変えません。変えたい場合は、こちらの記事を参照ください。

変更後、下記コマンドを実行します。

sudo systemctl restart sshd
sudo firewall-cmd --reload

最後に、firewallで有効にされている機能を確認します。
http、ssh、ftpがあることを確認してください。

firewall-cmd --list-services --zone=public --permanent

確認のため、ユーザーを切り替える場合は下記コマンドを入力します。

su sakura

rootでログインしなおし、今回作成したユーザーに切り替えてください。

Let’s EncryptでWebサイトの設定を行う

Let’s Encryptのクライアントcertbotをインストールし、反映する

今回はwork-it.bizという独自ドメインを使います。環境に合わせて変更してください。

まずはepelと、epelを利用したcertbotのインストールをします。

sudo yum install -y epel-release
sudo yum install -y certbot

続いて、証明書の発行を行います。
メールアドレスの入力と確認を求められます。

sudo systemctl stop nginx
sudo certbot certonly --standalone -d work-it.biz
sudo systemctl start nginx

※certbotは80番ポートを使うので、nginxを止めておく必要があります。もちろんファイアウォールも止めておかないとエラーが出ます(出ました)。

最後に設定ファイル(/etc/nginx/conf.d/work-it.biz.conf)を下記の例に沿って変更します。

server {
       listen 80;
       listen [::]:80;
       server_name work-it.biz;
       return 301 https://$host$request_uri;
}

server {
       listen  443 ssl;
       server_name     work-it.biz;
       #ssl on;
       ssl_certificate         /etc/letsencrypt/live/work-it.biz/fullchain.pem;
       ssl_certificate_key     /etc/letsencrypt/live/work-it.biz/privkey.pem;
}

Nginxを再起動します。

sudo systemctl restart nginx

HTTPSの起動

ファイアウォールにHTTPSを登録し、リロードします。

sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload

最後に、cron設定ファイルを作っておき、自動更新設定を掛けておきます。

sudo crontab -e

下記を正しく設定してください。

0 12 5 * * certbot renew --pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx"

※この設定では、毎月5日12時に更新がかかる設定となります。

最終確認

http://work-it.bizと、https://work-it.bizどちらもにアクセスできることを確認してください。

httpsへアクセスした場合、下記のようにCentOS7の初期表示が見えます。

赤枠の部分に鍵マークがついていることが確認できると思います。

おつかれさまでした~。

おわりに

今回は、WebサイトにHTTPS接続ができるように設定しました。
意外と単純に設定ができるので驚きました(@@

通常の運用だと、この後HTTPの接続をできなくするなどの設定を行います。
HTTPを開いておく必要は全くないので。
これである程度のセキュリティ設定は完了しました!

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
次回以降は上記記事からご覧ください。

(VPSでつくる) Socket通信を使ったモダンなチャットアプリをFlaskで作ろう

連載第十三回目です。

今回は、チャットアプリを作っていきたいと思います。
チャットの想定としては、会員制、socket通信で滑らかにチャットできる、データベースにログを残すにしましょう。

ただのチャットとは言え、使いやすさも考えて構築を行います。
そのため、HTML、JavaScript(jQuery含む)、CSSなどでの記載も行います。
ただし、理解が簡単になるよう、コメントを多めに書いています。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
その他については上記ページをお読みください。

作業予定

まず、テストアプリプログラムファイルのダウンロードが必要です。
Github(https://github.com/R2002/flask_chat)
テストアプリフォルダ(app/flask_chat)は、VPS上の/usr/share/nginx/app/flask_chatにアップロードします。

作業予定としては以下を想定しています。
・Gunicorn+eventletの設定
・CentOS7日本語対応
・チャットアプリのsystemd上でのサービス化
・Nginxの設定
・公開(デプロイ)

socket通信には、Gunicornやeventletなどのサービスが必要になります。Webサーバー兼リバースプロキシのNginxだけでは対応できません。
そのため、いろいろと設定が必要になります。

続いて、どのような思考でそれぞれのプログラムが書かれているのか確認します。

構成


このアプリは、チャットアプリです。
滑らかなチャットを行うためにsocket通信を使います。

socket通信の担い手はWSGIサーバーであるGunicorn、その一機能のeventletです。
前回のアプリまで使っていたNginx Unitは、eventletに関する資料がなかったので使いませんでした。

ファイル構成


ファイルごとに関係を示します。

前回と比べconfig.pyなどが増えましたが、設計思考は同じです。
viewsとmodelsをディレクトリ化したのは、機能の増加を何度か行い記載量が増えた際に、コーディングの状況が一人開発ですら分かり辛くなるからです。例えば、app.pyにviewsの記載をべた書きしていると、複数人での開発は困難になります。

ディレクトリを分けることによって、機能の一時停止判断や、バージョンアップ・ダウンの切り替え作業が非常に簡単になります。

なお、Flaskアプリの起動にはrun.pyを利用しています。
すべてのファイルは、run.pyから見た絶対的または相対的な記述が必要です。
例えば、importやfromで指定するディレクトリはどこか、パスはどう記載しなければ動かないか等です。

Gunicorn+eventletの設定

flask-socketioの公式を参考にします。

まずは、仮想環境(/usr/share/nginx/venv/flask_chat)を作り、その環境上でgunicornなどをインストールします。
gunicorn以外は、テストアプリに含まれるrequirements.txtをご利用ください。

pip install gunicorn==20.1.0

※バージョンは変更して問題ありません。

最後に、アプリフォルダ(/usr/share/nginx/app/flask_chat)に移動して、gunicornでflask_chatを起動します。

gunicorn -k eventlet -w 1 run:application

ちなみに、Windows上ではgunicornは動きませんのでご注意ください。

CentOS7、Windowsどちらでも動く下記コマンドは優秀ですね!

python run.py

何度かテスト立ち上げをしていると、ポートはもう使われているというエラーが出ます。
その場合はポートを開けるために、プロセスを停止させる必要があります。

プロセスの検索は下記コマンドを利用します。

ps ax

pythonのプロセスを探して、PIDを指定します。

kill -9 [該当のPID]

CentOS7日本語対応

CentOS7はそのままの設定だと言語が英語になっています。
チャットでは日本語を使うのですが、チャット内容に日本語を含む場合エラーが発生します。
エラーが起こらないよう、言語設定を変更していきます。

まずは、環境変数(LANG)を確認します。
LANG=C(英語)となっていると思います。

env

設定ファイルも確認しておきましょう。

less  /etc/locale.conf

次に、使える言語を確認します。
ja_JP.utf8があるか確認してください。

locale -a

最後に、下記コマンドで設定を書き換えます。

localectl set-locale LANG=ja_JP.utf8

これで日本語入力ができるようになりました。

失敗例

下記ファイル群を書き換えても意味がありません。
~/.bash_profile
~/.bashrc
~/.profile

下記コマンドもシェル上だけで有効で、systemd上のサービスにすると日本語にエラーが出ます。

export LANG=ja_JP.utf8

チャットアプリのsystemd上でのサービス化

それでは、デプロイのために色々と設定を行っていきましょう。

Gunicorn

gunicorn.conf.pyを下記の通りに作成します。

workers = 1
worker_class = 'eventlet'
bind = 'unix:/run/flask_chat.socket'

上記のファイルは、以下のようにコマンド上で利用します。

gunicorn run:application --config gunicorn.conf.py

worker_classは、eventletかgeventを指定します。
bindは、どこのポートまたはソケットで立ち上げるかを設定します。今回はソケットを使います。
workerについては、CPU1個あたりworkerを2~4個用意するのがいいようです。1個だとたまにチャットのメッセージが消えます。

CPU数を出力するには下記コードをpythonインタプリンタ上で使用してください。

import multiprocessing
print(multiprocessing.cpu_count())

serviceおよびsocketの準備

flask_chat.serviceとflask_chat.socketを用意します。
※settings_envフォルダに入っているのでアップロードしていただいてもかまいません。

flask_chat.serviceの内容は下記の通りです。

[Unit]
Description=flask_chat daemon
Requires=flask_chat.socket
After=network.target

[Service]
User=root
Group=root
RuntimeDirectory=gunicorn
WorkingDirectory=/usr/share/nginx/app/flask_chat/
ExecStart=/usr/share/nginx/venv/flask_chat/bin/gunicorn --config /usr/share/nginx/app/flask_chat/gunicorn.conf.py run:application
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
KillMode=mixed
PrivateTmp=true
Restart=always

[Install]
WantedBy=multi-user.target

注意すべき点は、ExecStartを仮想環境上のgunicornに指定することです。
venvを直接指定しなくても、勝手に良い感じに読み込みをしてくれます。

flask_chat.socketの内容は下記の通りです。

[Unit]
Description=flask_chat socket

[Socket]
ListenStream=/run/flask_chat.socket

[Install]
WantedBy=sockets.target

2つのファイルをアップロードして、下記コマンドで指定位置にコピーします。

cp flask_chat.service /etc/systemd/system/flask_chat.service
cp flask_chat.socket /etc/systemd/system/flask_chat.socket

サービス起動

下記コマンドでサービスを自動開始設定・開始します。

systemctl enable flask_chat.socket
systemctl start flask_chat.socket

※socketを起動すると、自動的にflask_chat.serviceが起動するのでコマンドは不要です。

最後に、動作確認を行います。

curl --unix-socket /run/flask_chat.socket localhost

エラーが出ずに、HTMLが返ってくれば設定は完了です。

Nginxの設定

Nginx Unit設定ファイル(/usr/share/nginx/conf.json)を下記の通りに変更します。
使わないので空にしましょう。

{
    "listeners": {
    },

    "applications": {
    }
}

設定を反映します。

sudo curl -X PUT --data-binary @/usr/share/nginx/conf.json --unix-socket /var/run/unit/control.sock http://localhost/config
systemctl restart unit

Nginx設定ファイル(/etc/nginx/conf.d/default.conf)のlocationを変更します。

location / {
    proxy_set_header Host $host;
    proxy_pass http://unix:/run/flask_chat.socket;
}

再起動させましょう。

systemctl restart nginx

公開(デプロイ)

上記の手続きが問題なければアプリが起動すると思います。
おつかれさまでした。

あとは、前回と同様にデータベース(flask_chat)を用意しておく必要がありますが、今回は説明を割愛します。

問題がなければ、下記のように別ブラウザおよび別IPからで滑らかなチャットを行えます。

socket通信で問題となる、ブラウザ上では通信確立が上手くできたかわからないについても、通信が確立されるまではチャットを表示しないようにしています。

おわりに

今回は、socket通信を使った滑らかなチャットが可能なアプリをデプロイまで持っていきました。

次回以降は、これまで全く考えられていなかったセキュリティ設定等を行っていきます。
アプリをデプロイしても、頻繁に落ちたり、個人情報が取られたり・・・可能性は十分あり得ます。
そのため、HTTPS(SSL)接続などの設定も行います。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
次回以降は上記記事からご覧ください。

(VPSでつくる) Python(Flask)でMariaDB(MySQL)へ接続できるアプリをもっと読みやすく改良してみよう

連載第十二回目です。

前回の記事で、Python3.6.8+FlaskでMariaDBに接続・データベースを編集するアプリを動作させる設定を行い、動作確認しました。

今回は、機能は前回と全く同じアプリを、もっと簡潔に読みやすく記述する方法を説明します。
コーディングの解説のみで、アプリの動作確認等は行いません。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
その他については上記ページをお読みください。

作業予定

まず、テストアプリプログラムファイルのダウンロードが必要です。
Github(https://github.com/R2002/flask_db_blueprint)

続いて、どのような思考でそれぞれのプログラムが書かれているのか確認します。

構成

このアプリは、データベース(MariaDB)を変更するアプリです。

HTTP接続でWebサーバ(Nginx)にアクセスし、APサーバ(Nginx Unit)を介してPythonアプリをvenvで起動しています。
Nginx UnitでのPythonのバージョンは導入が簡単なので3.6.8を選択しました。
phpMyAdminはWebサーバ(Nginx)上のPHP-FPMで動かしています。

このように図解することで、どんなアクセスに対し、それぞれの機能が対応しているかを分かりやすくしています。

ファイル構成

ファイルごとに関係を示します。
viewsとmodelsをディレクトリ化したのは、機能の増加を何度か行い記載量が増えた際に、コーディングの状況が一人開発ですら分かり辛くなるからです。例えば、app.pyにviewsの記載をべた書きしていると、複数人での開発は困難になります。

ディレクトリを分けることによって、機能の一時停止判断や、バージョンアップ・ダウンの切り替え作業が非常に簡単になります。

なお、Flaskアプリの起動にはrun.pyを利用しています。
すべてのファイルは、run.pyから見た絶対的または相対的な記述が必要です。
例えば、importやfromで指定するディレクトリはどこか、パスはどう記載しなければ動かないか等です。

ディレクトリ構成

前回に比べて、ディレクトリは増えましたが機能は変わっていないので、理解はそこまで難しくないと思います。

/usr/share/nginx 
 ┗ app アプリ用ディレクトリ
 | ┗ flask_db_blueprint テストアプリ用ディレクトリ
 |   ┗ models データベースモデル設定用ファイル(旧:models.py)
 |   ┗ templates HTML設定用テンプレートファイル
 |   ┗ views ビュー用ファイル(旧:app.py内に記載)
 |   ┗ app.py アプリ本体
 |   ┗ config.py 設定ファイル
 |   ┗ database.py データベース用関数ファイル
 |   ┗ run.py 起動ファイル
 ┗ venv 仮想環境用ディレクトリ
   ┗ flask_db テストアプリ用環境(前回アプリとインストール内容は同じ)

コード解説

それではflask_db_blueprintのディレクトリ内にあるファイルを一つずつ、コードを解説していきます。

run.py

オンラインではNginx UnitからWebアプリを起動するため、ローカルではflaskでローカルサーバーを起動するためのファイルです。

from app import app as application

if __name__ == '__main__':
    application.run()

Nginx Unitのデフォルトでは、application.run()が必要です。
そのため、app.pyを呼び出して、appをapplicationにエイリアスを変更してからrun()を行っています。
※conf.jsonの個別のapplicationのcallback属性でエイリアス(application)の変更が可能です。

app.py

run.pyから呼び出されるファイルです。
アプリ設定(Flask、設定、DB)の基本的な流れが書かれています。

from flask import Flask
import config, views
from database import init_database

# create_app
def create_app():
    # Flask定義
    app = Flask(__name__)
    # 設定反映
    app.config.update(config.cf)
    # DB設定
    init_database(app)
    return app

# app
app = create_app()

# Blueprint
# データベース参照(view): views/index.py
app.register_blueprint(views.index.app)

# 一行追加(insert), 一行変更(update), 一行削除(delete): views/database.py
app.register_blueprint(views.database.app)

create_appでアプリ設定をした後に別で表示用にBlueprintを定義することで、
・アプリとして起動したい場合は、ファイル全体を呼び出す。
・アプリのDB初期設定を行いたい場合は、app.pyのcreate_appのみを呼び出す。
という使い方が可能になります。

config.py

アプリの設定を全て統括するファイルです。
今回は追加していないですが、画像・JavaScript・CSSなどの静的ファイルのディレクトリ設定(絶対パス・相対パス問わない)などを設定すると良いかと思います。

import os

#--------------------------------------#
# 設定ファイル
#--------------------------------------#
cf = {} # 削除しないでください

# Flaskのデバッグ表示を有りにする
cf['DEBUG'] = 1

# DB設定
cf['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://{user}:{password}@{host}/{db_name}?charset=utf8'.format(**{
    'user': os.getenv('DB_USER', 'root'),
    'password': os.getenv('DB_PASSWORD', ''),
    'host': os.getenv('DB_HOST', 'localhost'),
    'db_name': 'flask_db_blueprint',
})

# TRACK_MODIFICATIONSを無効にしておく
cf['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

database.py

DBの読み込み設定を行っています。
今回はflask_SQLAlchemy(DB接続方法)とflask_migrate(DB更新方法)を規定しています。
その他には、init_database()などの関数を定義しておくことで、DBロジックの変更に対して、このファイルの書き換え行うだけで対応が可能になります。

from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

# DB規定
db = SQLAlchemy()

# db初期設定
def init_database(app):
    db.init_app(app)
    Migrate(app, db)

# 追加または更新
def db_insert(data):
    db.session.add(data)
    db.session.commit()

# 削除
def db_delete(data):
    db.session.delete(data)
    db.session.commit()

おわりに

今回はflaskアプリの中身について解説しました。
どう動いているのか、なぜこのような記載方法になっているのかを知ることで、このアプリではない他アプリをどう作るべきか考えるのに役立てれば幸いです。

その他にも下記のようなページが参考になります。
・【Flask】ディレクトリ構成を考える

次回は、このアプリを元に、Socket通信を用いた軽量チャットアプリを作成します。
Webアプリ(Flask)+Socket通信はまとまった解説がなく、かなり理解に時間が取られてしまったので、後の方はもっと楽してほしいなーと思っています。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
次は、13. Socket通信を使ったモダンなチャットアプリをFlaskで作ろうです。

(VPSでつくる) PythonでMariaDB(MySQL)へ接続できるアプリを触ってみよう

連載第十一回目です。

Python3.6.8+FlaskでMariaDBに接続・データベースを編集するアプリを動作させる設定を行い、動作確認します。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
その他については上記ページをお読みください。

作業予定

作業予定としては、下記のアプリを作っていきます。
まず動かしてみて、その後でFlaskの各関数が何をしているか解説していきます。

ディレクトリ構成

/usr/share/nginx 
 ┗ app アプリ用ディレクトリ
 | ┗ flask_db テストアプリ用ディレクトリ
 |   ┗ app.py アプリ本体
 |   ┗ config.py 設定ファイル
 |   ┗ database.py データベース用関数ファイル
 |   ┗ models.py データベースモデル設定ファイル
 |   ┗ run.py 起動ファイル
 ┗ venv 仮想環境用ディレクトリ
   ┗ flask_db テストアプリ用環境

機能

・データベース参照(/)
・1行追加(/insert)
・1行変更(/update)
・1行削除(/delete)

作業内容

まず、テストアプリプログラムファイルのダウンロードが必要です。
Github(https://github.com/R2002/flask_database_test)
アップロードして使用しますので、適宜内容を見てご利用ください。

まずは、ディレクトリを移動します。

cd /usr/share/nginx

次に、アプリ用ディレクトリを作ります。

mkdir app/flask_db

仮想環境を作り、その仮想環境に入ります。

python3 -m venv venv/flask_db
source venv/flask_db/bin/activate

pipをアップグレードしておきます。

pip install --upgrade pip

ダウンロードしたファイルの中にあるrequirements.txtアップロードし、テストアプリに必要なPythonモジュールを下記コマンドでインストールします。仮想環境上でインストールするようにしてください。

pip install -r requirements.txt

ファイルをアップロードできない場合は、パーミッション変更を下記の通り行ってみてください。

chmod 0777 /usr/share/nginx

requirements.txtファイルの内容は以下の通りです。

flask==1.1.2
flask-sqlalchemy==2.5.0
SQLalchemy==1.3.23
pymysql==1.0.2
Flask-Migrate==2.7.0

簡易アプリ(main.py)作成し、複数アプリを同時並行でNginx Unitでデプロイできることを確認します。
まずは、アプリ用ディレクトリに移動します。

cd app/flask_db
[python]

続いて、<strong>main.py</strong>を作成します。
[python]
from flask import Flask

application = Flask(__name__)

@application.route('/')
def index():
    print('test')
    return "Hello Flask"

if __name__ == '__main__':
    application.run()

/usr/share/nginx/conf.jsonを編集し、flask_testに加え新たなアプリ(flask_db)を起動できるようにします。

{
    "listeners": {
        "*:8081": {
            "application": "flask_test"
        },
        "*:8082": {
            "application": "flask_db"
        },
    },

    "applications": {
        "flask_test": {
            "type": "python 3.6.8",
            "path": "/usr/share/nginx/app/flask_test/",
            "home": "/usr/share/nginx/venv/flask_test/",
            "module": "main"
        },
        "flask_db": {
            "type": "python 3.6.8",
            "path": "/usr/share/nginx/app/flask_db/",
            "home": "/usr/share/nginx/venv/flask_db/",
            "module": "main"
        },
    }
}

Nginx Unitの設定を更新します。

sudo curl -X PUT --data-binary @/usr/share/nginx/conf.json --unix-socket /var/run/unit/control.sock http://localhost/config

Nginxの設定ファイル(/etc/nginx/conf.d/default.conf)に下記を追記します。

    location /flask_db/ {
        proxy_pass http://127.0.0.1:8082/;
    }

再起動をしてみましょう。

systemctl restart nginx
systemctl restart unit

下記のURLでアクセスできるようになります。
http://XXX.XXX.XXX.XXX/sample/
→ 前回のテストアプリ
http://XXX.XXX.XXX.XXX/flask_db/
→ 同じようなテスト用アプリ

今後は、flask_dbを改良していきます。

それでは、ファイルアップロードのためのパーミッション変更を行います。

cd /usr/share/nginx
chmod 0777 app/flask_db

flask_db内にファイルをアップロードします。

conf.jsonを編集し、applicationsのflask_db、moduleをmainからrunにしてください。

{
    "listeners": {
       # 略
    },

    "applications": {
        "flask_test": {
           # 略
        },
        "flask_db": {
            # run
            "module": "run" # ここだけ変更
        },
    }
}

Nginx Unitの設定を更新します。

sudo curl -X PUT --data-binary @/usr/share/nginx/conf.json --unix-socket /var/run/unit/control.sock http://localhost/config

phpMyAdminで、新しいデータベースflask_dbを作っておきます。照会順序はutf8_general_ciで問題ありません。
http://XXX.XXX.XXX.XXX/phpMyAdmin/

最後に、アプリ設定ファイル(app/flask_db/config.py)を編集し、phpMyAdminで設定したユーザーのパスワードを記載します。

再起動をしておきましょう。

systemctl restart nginx
systemctl restart unit

ここまでで設定は終わりです!
おつかれさまでした。

あとは実際にアプリを触っていきます。

まず、データベースをcreateします。
そのためにflask_db仮想環境に入っておき、ディレクトリを/usr/share/nginx/app/flask_dbに移動します。

続いて、pythonコマンドでPythonインタプリンタを起動し、下記コマンドを入力します。

from app import create_app
from database import db
db.create_all(app=create_app())

データベースの内容(testテーブル)ができたことを確認してください!

続いて、データベースのMigrate(差分保存)初期設定を行っておきます。
Pythonインタプリンタから出て、下記コマンドを実行します。

set FLASK_APP=run.py
flask db init

※Migrateについての詳細は、Flask-migrateをご覧ください。

それではWebサイトにアクセスします。
まずはトップページ(/flask_db/)を確認します。

まだデータが入っていないため、テーブルは空です。
※このトップページはphpMyAdmin(flask_dbのtestテーブル内)と同じ表示になります。

では、データを入れていきましょう。
データ追加は、/insert/<入れたい値>にアクセスしてください。
テストでは100, 200, 300, 400, 5000の5つの数値をそれぞれ入力しました。

トップページ(/flask_db/)を確認すると、下記のようにデータベースに行が追加されました。

続いて、特定のidの値(data)を更新していきます。
更新は、/update/<id>/<変更したい値>にアクセスしてください。
テストでは/update/3/0, /update/4/100にアクセスしました。

トップページ(/flask_db/)を確認すると、下記のようにデータベースのid3および4の値が変更されました。

最後に、特定のidを削除します。
削除は、/delete/<id>にアクセスしてください。
テストでは/delete/3にアクセスしました。

トップページ(/flask_db/)を確認すると、下記のようにデータベースのid3が削除されました。

これにてテストアプリのテスト起動は終了しました。

締めに、アプリの解説を行います。
アプリの構造は以下の通りです。
HTTP接続からNginx、NginxからNginx Unit、Nginx Unit上でvenvを使ってアプリを起動し、MariaDBにアクセスする方法を取っています。

ファイルの内容については以下の通りです。
app.pyがアプリ本体です。conf.jsonに指定したrun.pyは起動用のアプリであって本体ではありません。

このような構成にすることで、ファイルごとに役割分担を明確にしています。かつ、Nginx Unit以外のAPサーバー(例:uWSGI)などでも動かせるような構成となっています。

おわりに

PythonでMariaDB(MySQL)へ接続できるアプリを触ってみようということで、今回いろいろと設定を行いました。
このアプリをWebサーバー上で起動できれば、その他の応用アプリも起動が可能になります。

ただ、当アプリはapp.pyにルーティングや表示のコードが記載されているため、このまま記載を続けるとapp.pyのコード量が肥大化します。
次回はファイルごとに役割分担を明確にしたFlaskアプリを作成するために、Flaskの機能であるBlueprintをこのアプリに導入していきます。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
次は、12. Python(Flask)でMariaDB(MySQL)へ接続できるアプリをもっと読みやすく改良してみようです。

(VPSでつくる) WinSCPでFTP接続

連載第十回目です。

これまではVPSサーバーに対し、viエディタで色々なファイルを編集してきました。
ただ、今後はFlaskアプリなど、かなり作り込んだサービスの導入テストを行いますので、一ファイルずつviエディタで書き込んでると日が暮れます。

そのため、FTP通信を使って、VPSサーバーにファイルを転送してしまいましょう。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
その他については上記ページをお読みください。

1. ユーザーの作成

FTPユーザー(ftp-user)を作ります。他の名前でも構いません。
パスワードも設定しておきましょう。

useradd ftp-user
passwd ftp-user

あとは、ユーザーが操作できる最上位のディレクトリのパーミッションを0777に設定しておきます。

chmod 777 /usr/share/nginx

2. FTPのインストール

FTPパッケージのインストールを行います。

yum -y install vsftpd

3. FTPの設定

FTPの設定ファイル(/etc/vsftpd/vsftpd.conf)を2通り変更します。
(1)内容の追記

# userlist_fileで指定指定したユーザを接続可能にする
userlist_enable=YES

# アクセスファイル(/etc/hosts.allow, /etc/hosts.deny)をアクセス制御に利用しない
tcp_wrappers=NO

# ドットから始まるファイルを含めた一覧を返す
force_dot_files=YES

# ファイル(またはディレクトリ)のタイムスタンプの表示をローカルタイムで表示する
use_localtime=YES

# ユーザー毎の設定ファイルの場所を指定する。
user_config_dir=/etc/vsftpd/user_conf

# chroot設定で許可する
allow_writeable_chroot=YES

# chroot設定で許可するを設定すると、下記エラーが防止できます。
OOPS: vsftpd: refusing to run with writable root inside chroot()

(2)コメントアウトから有効にする

# ルート設定有効ユーザー
chroot_local_user=NO
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list

意外と追記内容(赤枠)が多いですが、問題ありません。

ルート設定ユーザーリストファイル(/etc/vsftpd/chroot_list)を下記の通りにしてください。

ftp-user

※改行で新規ユーザーを追加可能です。

ユーザー設定用ディレクトリとファイルを作ります。

mkdir /etc/vsftpd/user_conf
vi /etc/vsftpd/user_conf/ftp-user

ユーザー設定用ファイル(/etc/vsftpd/user_conf/ftp-user)を下記の通りにしてください。

local_root=/usr/share/nginx

※コピペすると先頭数文字が切れる場合があるので注意ください。

いつもの通りサービスのスタートと再起動可能設定を行います。

systemctl enable vsftpd
systemctl start vsftpd

4. FTPのテスト

仕様ソフトはWinSCPを例にしていますが、他ソフトでも構いません。

下記の通り設定します。
IPアドレスは環境に応じて変更してください。

パッシブモードOFFだと20番接続、パッシブモードONだと21番接続にします。

※もし接続できて、ディレクトリが表示されない場合はONにしてください。

接続すると下記のような表示となります。
上位のディレクトリに移動する(赤枠)をクリックしても、設定したディレクトリより上には行けないことを確認できます。

上位のディレクトリに行けない設定にするのには、セキュリティの観点から言って正解です。
FTPユーザーはファイルを送受信するだけの役割であり、サーバーの中身は見る必要はありません。

おつかれさまでした。

おわりに

今回でFTPでのファイル送受信が可能となり、前回行ったデータベースと合わせて、本格的なアプリを構築する準備ができました。
次回は、Pythonの軽量なフレームワークFlaskで本格的なアプリを構築していきます!

ちなみに、FTPは平文でファイルをやり取りするためセキュリティ面に脆弱性があります。
よりセキュリティを高めるなら、SFTPなどを利用することをお勧めします。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
次は、11. PythonでMariaDB(MySQL)へ接続できるアプリを触ってみようです。

(VPSでつくる) phpMyAdminインストール

連載第九回目です。

GUI上でMariaDB(MySQL)を触れるようにするために、phpMyAdminをインストールしましょう。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
その他については上記ページをお読みください。

1. phpMyAdminインストール

前回の記事で指定したremiレポジトリを使っていきます。

yum -y --enablerepo=remi-php71 install phpMyAdmin

※もしPHPのバージョンを変更された場合は、php71を編集してください。

環境設定保存用のデータベースを作成しておきます。

vi /usr/share/phpMyAdmin/sql/create_tables.sql

コードを下記から、

-- (activate this statement if necessary)
-- GRANT SELECT, INSERT, DELETE, UPDATE, ALTER ON `phpmyadmin`.* TO
--    'pma'@localhost;

下記の通り変更します。

-- (activate this statement if necessary)
GRANT SELECT, INSERT, DELETE, UPDATE, ALTER ON `phpmyadmin`.* TO
  'root'@localhost;

※今回はrootユーザーをすでに作成しているので、このようにしています。

MariaDBにログインして、クエリを実行します。

mysql -u root -p
source /usr/share/phpMyAdmin/sql/create_tables.sql

権限関係のメモリリフレッシュを行います。

FLUSH PRIVILEGES;

Control+ZコマンドでMariaDBから抜けることができます。

2. Nginxの環境設定

PHP-FPMとNginxを接続するために、TCPとUnix Socketの2通りの方法があります。(参考ページ)
今回はUnix Socketを利用します。

まずは、PHP-FPMファイルの設定(/etc/php-fpm.d/www.conf)を変更します。

listen = /var/run/php-fpm/php-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0666

変更イメージは以下の通りです。

PHPの設定ファイル(/etc/php.ini)を変更します。

session.save_path = "/var/lib/php/session"

このセッションにNginxがアクセスできるようにしておきます。

sudo chown -R root.nginx /var/lib/php/session

最後に、Nginxの設定を変更します。
環境設定ファイル(/etc/nginx/conf.d/default.conf)を2点編集します。
(1)server{}内のlocation ~ \.php$内を変更します。

    location ~ \.php$ {
                fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
    }

(2)server{}内にlocation /phpMyAdminを追記します。

    location /phpMyAdmin {
        alias /usr/share/phpMyAdmin/;
        try_files $uri $uri/ /index.php;

        location ~ ^/phpMyAdmin/(.+\.php)$ {
            alias /usr/share/phpMyAdmin;
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
            fastcgi_param SCRIPT_FILENAME /usr/share/phpMyAdmin/$1;
            include fastcgi_params;
            fastcgi_intercept_errors on;
        }
    }

location ~ ^/phpMyAdmin/(.+\.php)$内にallow XXX.XXX.XXX.XXX(IP); deny all;をこの中に追記すると、指定IP以外のアクセスを拒否することができます。

変更イメージとしては以下の通りです。

sudo systemctl restart php-fpm
sudo systemctl reload nginx

3. 動作確認

下記のように表示されればOKです。

rootユーザーでのログインが可能かどうか確認ください。

設定を変更した場合は、php-fpm.sockを削除して、php-fpmなどを再起動します。

rm -f /var/run/php-fpm/php-fpm.sock

おわりに

phpMyAdminがインストールできました。
これにてデータベースの導入は完了です!

次は、FTPでファイルを送受信できるようにします。
これまではviエディタで色々と記載していましたが、この方法だと限界があるので変更します。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
次は、10. WinSCPでFTP接続です。

(VPSでつくる) MariaDB(MySQL)インストール

連載第八回目です。

今回はMariaDBをインストールします。
MariaDBはMySQLの完全互換で、高速性を持っているので採用します。
SQLクエリも全く同じものが使えます。
詳しくはMariaDB vs MySQL: 徹底比較をご覧ください。

MariaDBとphpMyAdminにより、Flaskアプリのデータベースを設定し、GUI上で触れるようになります。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
その他については上記ページをお読みください。

1. MariaDBインストール

PHPと同じように、MariaDBもyumのリポジトリではバージョンが古いので、MariaDBの公式サイトからインストールします。

vi /etc/yum.repos.d/MariaDB.repo

ファイルの内容は下記の通りにします。

[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.5/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

インストールします。

yum -y install MariaDB-server MariaDB-client

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

mysql -V

下記のように表示されればOKです。

いつものごとく起動と自動起動設定を行っておきます。

systemctl start mariadb
systemctl enable mariadb

2. MariaDB(MySQL)初期設定

下記コマンドで始めます。

mysql_secure_installation

質問が色々と出てきますので、1つずつ丁寧に答えていってください。
1. パスワードを入力してね。(初回はそのままエンターを入力してください)
2. 認証にunix_socketを使うか? >> n
Yにすると別途設定が必要です。
3. MySQLのrootパスワードを変更するか? >> Y
パスワードの入力が必要です。
4. anynomous(無名)ユーザーを除外するか? >> Y
5. リモート接続を不許可にするか? >> Y
6. testデータベースは不要か? >> Y
7. 特権テーブルをリロードするか? >> Y

最後に、環境設定を行います。

vi /etc/my.cnf.d/server.cnf

[mysqld]に下記を追記してください。

character-set-server = utf8

再起動を行います。

systemctl restart mariadb

おわりに

今回はMariaDBをインストールしました。
これでphpMyAdminを導入する準備はできました!

次回はphpMyAdminをインストールします。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
次は、9. phpMyAdminインストールです。

(VPSでつくる) Nginx+PHPでHello World

連載第七回目です。

今回はGUIでデータベースを操作できるphpMyAdminのインストール準備のために、PHPという言語をインストールします。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
その他については上記ページをお読みください。

1. PHPのインストール

PHPはyumにPHP5系しか入っていないようなので、EpelとRemiレポジトリをインストールします。

yum -y install epel-release
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

最低限のPHP関連のモジュールをインストールします。

yum -y install --enablerepo=remi-php71 php php-cli php-common php-devel php-fpm php-mbstring php-mysqlnd

※今回はPHP7.1にしました。5系より7系の方が処理が早いらしいので、そちらに切り替えました。

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

php -v

7.1と表示されると完了です。

2. PHP関係の環境設定

PHP.iniの環境設定を行っておきます。

vi /etc/php.ini

下記の設定を変更しておきます。
「/」コマンドで検索すると早く終わります。

date.timezone = "Asia/Tokyo"
expose_php = Off ; サーバーがPHPを導入しているか公表するかどうか
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8 ; サーバー内での文字の扱い
mbstring.http_input = auto ; input_encodingが代わりに使われるべきなのでautoと明示しておく。

PHP-FPMの設定を行います。
NginxでPHPを使う場合はこのPHP-FPMが必須です。

vi /etc/php-fpm.d/www.conf

ただし、設定がApache用なのでそれを切り替えます。

user = nginx
group = nginx

設定を反映して起動、および自動起動設定をしておきます。

php-fpm -t
systemctl start php-fpm
systemctl enable php-fpm

3. PHPのテスト

PHPのテストコードを公開ディレクトリ(ルート)に作成します。

vi /usr/share/nginx/html/info.php

簡単なものにしておきます。

<?php
phpinfo();
?>

Nginxの設定を変更します。

sudo vi /etc/nginx/conf.d/default.conf

今の状態がコレです。

location / の中身を外に出して(緑枠)、新規追加(赤枠)を行います。

※最後の「;」を忘れるとエラーが出ます。

コピペ内容は以下の通りです。

    root        /usr/share/nginx/html;
    index       index.html index.htm index.php;

    location ~ \.php$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
    }

Nginxを再起動します。

systemctl restart nginx

最後に、info.phpにアクセスして動作を確認してください。
http://XXX.XXX.XXX.XXX/info.php

下記のように表示されればOKです!

不要であればファイルを削除しておきましょう。

rm -f /usr/share/nginx/html/info.php

おわりに

今回はPHPを導入しました。
これで基本的なPHPプログラムは実行できるようになりました!

次回はデータベースであるMariaDB(MySQL)をインストールします。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
次は、8. MariaDB(MySQL)インストールです。

(VPSでつくる) Nginx Unit+venv+FlaskでHello World

連載第六回目です。

色々と設定を行ってきましたが、今の状態ではNginx(Webサーバー)上で動的なサイトを表示することはできません。
そのため、今回はNginx Unit(APサーバー)を用いて、簡単なPythonアプリを作成してWebサイトで公開してみましょう!

そもそもAPサーバーって何ぞ?という方はミドルウェア(Web、AP、DB)について知ろうをご覧ください。

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
その他については上記ページをお読みください。

1. Nginx Unitのインストール

では、まずNginx Unitのインストールを行います。
Nginxと同じようにレポジトリ情報を作成します。

vi /etc/yum.repos.d/unit.repo

ファイルの中身は下記の通りです。
記入したら:wqコマンドで保存+終了してください。

[unit]
name=unit repo
baseurl=https://packages.nginx.org/unit/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

※先頭の何文字かが欠ける不具合があります。

それではインストールを行います。

yum install unit

最後に、必要な機能をインストールしておきます。

yum install unit-devel unit-jsc8 unit-jsc11 unit-php unit-python27 unit-python36

※公式サイトを参考にしていますが、今回不要なものはインストールしていないので、あなたの環境に必要なパッケージはインストールされない可能性があります。

環境設定は後で行います。

2. Python3.6.8のインストール

(仕様かどうかわかりませんが、)pyenvをそのままNginx Unitに反映することは難しいようです。
そのため、pyenvでインストールしたバージョンと同じPython3.6.8をVPSにインストールしておきます。

今回は、Python3.6.8のインストールは上記でunit-python36をインストールしたため、すでにインストール済みで不要です。別バージョンが必要であればこのページの下部にある補足. Python別バージョンのインストール方法をご覧ください。
もし別バージョンをインストールしたい(Python3.6.8か2.7.5以外の)場合はNginx Unitは非推奨です。Nginx Unitを使うには、Dockerコンテナ等別途準備が必要です。(参考ページ)

3. Flaskアプリの作成、仮想環境作成

続いて、Flaskアプリをインストールします。

まずは作業ディレクトリを移動して、Nginx公開用のディレクトリにします。

cd /usr/share/nginx/

test_flask仮想環境を作っておきます。

python3 -m venv venv/flask_test

仮想環境をアクティブ化して、flaskをインストールします。

source venv/flask_test/bin/activate
pip install flask

pythonインタプリタを起動して、flaskのバージョンを確認しておきましょう。

python
import flask
flask.__version__

下記のように表示が出ればOKです。

このとき、仮想環境以外にはflaskをインストールできていません。
つまり、もし実行するとエラーが出るはずです。確認しておきましょう。

pythonインタプリンタはControl+Zコマンドで出て、仮想環境を下記コマンドで非アクティブ化します。

deactivate

pythonインタプリタを起動して、flask_test仮想環境以外でflaskがインポートできないことを確認してください。

python
import flask

下記のようなエラーが出ますが、問題ありません。

最後に、Flaskアプリを作成しておきます。
まずは、アプリ用ディレクトリを作成します。

mkdir app/flask_test

続いて、viエディタで下記ファイルを作成します。

vi app/flask_test/main.py

ファイルの内容は下記の通りです。
下記の2通りの関数どちらもをアプリの1機能として表示させられるようにします。

from flask import Flask

application = Flask(__name__)

@application.route('/')
def index():
    return "Hello Flask1"

@application.route('/test2')
def test2():
    return "Hello Flask2"

※application = ~としているのは、Nginxで動作させるときのデフォルト値なので守ってください。
※変更したい場合は、conf.jsonのapplicationsのcallable設定を変更ください。

想定では、Flaskアプリを下記URLで表示できるようにします。
http://XXX.XXX.XXX.XXX/sample/

http://XXX.XXX.XXX.XXX/sample/
“Hello Flask1”

http://XXX.XXX.XXX.XXX/sample/test2
“Hello Flask2”

動作確認として、flask_test仮想環境をアクティブ化した状態で下記コマンドを使用してください。

python app/flask_test/main.py

エラーが出なければ完了です!

4. NginxおよびNginx Unitの設定

Nginx Unitを起動します。自動起動設定もしておきましょう。

systemctl start unit
systemctl enable unit

続いて、Unitの設定ファイル(conf.json)を作成します。

vi conf.json

ファイルの内容は下記の通りです。コピペでOKです。

{
  "listeners": {
    "*:8081": {
      "application": "flask_test"
    }
  },

  "applications": {
    "flask_test": {
      "type": "python 3.6.8",
      "path": "/usr/share/nginx/app/flask_test/",
      "home": "/usr/share/nginx/venv/flask_test/",
      "module": "main",
    }
  }
}

Nginx Unitの構造として、
指定ポートへのアクセス
↓
Listener
↓
venv(test_flask)
↓
Application(test_flask)

となりますので、上記のように設定します。

各設定の解説としては以下の通りです。

{
  "listeners": {
    "*:8081": { // ポート番号設定
      "application": "flask_test" // アプリケーション名
    }
  },

  "applications": {
    "flask_test": { // アプリケーションごとに設定を記述できる
      "type": "python 3.6.8", // python3.6.8以外も可能だが、別途設定が必要
      "path": "/usr/share/nginx/app/flask_test/", // アプリディレクトリ
      "home": "/usr/share/nginx/venv/flask_test/", // 仮想環境
      "module": "main" // 作成したファイル名(.pyなしが正)
    }
  }
}

その他の設定について、詳しくは公式サイトをご覧ください。

設定ファイルの通りにNginx Unitの設定を変更します。

sudo curl -X PUT --data-binary @/usr/share/nginx/conf.json --unix-socket /var/run/unit/control.sock http://localhost/config

エラーが出る場合は下記コマンドでエラーログを確認します。

vi /var/log/unit/unit.log

Successと出れば問題ありません!

あとは、Nginxの2つの設定を行えば対応完了です。
nginx.confの設定を行います。

sudo vi /etc/nginx/nginx.conf

http{}内に下記を記載します。

    upstream unit_backend {
        server 127.0.0.1:8300;
    }

※ポート番号は他のモノと一致しないようにしてください。

記載例は以下の通り。

default.confの設定を行います。

sudo vi /etc/nginx/conf.d/default.conf

※バージョンによっては、nginx.conf内に記載する場合があります。どのファイルに記載があるかご注意ください。

server{}内に下記を記載します。

    location /sample/ {
        proxy_pass http://127.0.0.1:8081/;
    }

※ポート番号はUnitの設定と一致するようにしてください。

記載例は下記の通り。

最後に、NginxとNginx Unitを再起動しておきます。

sudo systemctl restart nginx
sudo systemctl restart unit

これにて設定は終了です!

5. Webサイトの動作確認

想定通りに表示できるか確認します。
http://XXX.XXX.XXX.XXX/sample/
“Hello Flask1”

http://XXX.XXX.XXX.XXX/sample/test2
“Hello Flask2”

問題ありませんでした。
おつかれさまでした!

参考サイト

【Python】CentOS7サーバ上にFlask+Nginx+Nginx UnitでWebアプリを構築する

補足. Python別バージョンのインストール方法

Python3.X(今回は3.7.0)をVPSにインストールしておきます。

まずは、pyenvを一旦非アクティブ化させるため、下記のbashファイルを編集します。

vi ~/.bashrc

~/.bashrcの内容の次の文字列を削除します。

export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

((VPSでつくる) Pythonのバージョンを3.Xにするの次の文字列(*1)に該当)

最後にリブートします。一旦CUIが閉じるで再ログインしてください。

sudo reboot

次に、yumにインストールしたいPythonのバージョンがあるか確認します。

yum search python3

Python3.6.8が最新のようですね…。

目的の3.7.0がないので、適当なディレクトリを作って、その中で作業をします。

mkdir /usr/share/nginx/temp
cd /usr/share/nginx/temp

続いて、ファイルをダウンロードします。

curl -O https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz

※必要であれば、https://www.python.org/ftp/python/から検索できます。

ファイルを解凍して、ディレクトリに移動します。

tar xf Python-3.7.0.tgz
cd Python-3.7.0

インストールを行います。
このままインストールすると、Pythonは/usr/local/ディレクトリにインストールされます。

./configure
make
sudo make altinstall

もし、その他にインストールしたい場合は、./configure –prefixオプションを利用ください。

パスが通っていないのでパスを通しておきます。

sudo visudo

下記のように変更します。
かなり下の方にあるので、/コマンドでsecureを検索すると楽です。

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
↓
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

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

python3 -V

python3へのパスが3.6.8に通っていることが多いので、これも変更しておきます。

sudo ln -sf /usr/local/bin/python3.7 /usr/bin/python3

※python3ではなく、pythonにパスを通すのはおすすめしません。yumなど他の環境を壊してしまう可能性があるため、非推奨です。

もし指定したいバージョンのpythonへのパスが分からない場合は、下記で検索を行います。

whereis python

バージョンを再度確認します。

python3 -V

下記のように表示されればOKです。

最後に、ディレクトリの削除などの整理を行っておきます。

cd ../../
rm -rf temp

削除したこの内容を再度記述します。
→ ~/.bashrcの内容の次の文字列を削除します。

export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

シェルを再起動させます。

exec $SHELL

注意点としては、venvを作成した時のバージョンと、動作環境のpythonのバージョンは一定でなければなりません。
pyenvでバージョンを切り替えながら仮想環境を作ると、たまにミスするので取り扱いに注意してください。

おわりに

どうにかNginx Unitとvenv、Flaskを使ったアプリケーションができました。
ただ、Webアプリに重要な機能がまだ構築できていません。
データベースとFTPです。

データベースはこれまで使う必要がありませんでしたが、MariaDB(MySQLの完全互換)使えるように設定します。
データベースをGUI上で簡単に使えるように、phpMyAdminを導入します。
FTPは、viエディタでチマチマ記載していたものを転送で簡単に送ったり、アプリをデプロイするときに使います。
それぞれ、少し手間はかかりますが、今回ほどではないので一緒に頑張りましょう!

この記事は、VPSで作るPythonでのWebアプリ運用環境の連載記事です。
次は、7. Nginx+PHPでHello Worldです。