社内SEの話

日々起きたことの記録用

CentOS7でFlaskをmod_wsgiで動かす

↓プログラミングで副業を考えたらこちら↓

f:id:boonv4m312s:20200419165130p:plain

はじめに

社内でAPIを必要とする場面が発生しました。

その際の環境構築のメモの残します。

はじめてちゃんとしたメモを残すので

環境

サーバー側

実際はESXiに乗せていますが、今回はVirtualboxで検証します。

CentOS7

ネットワーク-ブリッジ

クライアント

Windows10

ブラウザ:Chrome

初期設定

復習の意味も兼ねてできるだけ詳しく書いています。

詳しい方は次へ飛ばしてもらって構いません。

インストールした状態から開始します。

rootでログインします。

$ su -

インストールした直後でDCHPだったので固定IP化します。

ネットワークの設定

NICの名前の確認

nmcli d

DEVICE  TYPE      STATE     CONNECTION

enp0s3  ethernet  接続済み  enp0s3

lo      loopback  管理無し  --

今回の環境はenp0s3がNIC名になります。

環境ごとに名前が違うかも知れません。一度確認してから固定IP化します。

# vi /etc/sysconfig/network-scripts/ifcfg-enp0s3

TYPE="Ethernet"

BOOTPROTO="none"    ←DHCPからnone もしくはstatic 

DEFROUTE="yes"

PEERDNS="yes"

PEERROUTES="yes"

IPV4_FAILURE_FATAL="no"

IPV6INIT="no"

IPV6_AUTOCONF="yes"

IPV6_DEFROUTE="yes"

IPV6_PEERDNS="yes"

IPV6_PEERROUTES="yes"

IPV6_FAILURE_FATAL="no"

IPV6_ADDR_GEN_MODE="stable-privacy"

NAME="enp0s3"

UUID="4559be95-2750-42e7-9df4-37b7726e3e8f"

DEVICE="enp0s3"

ONBOOT="yes"

IPADDR=172.31.0.10      ←任意のアドレス

NETMASK=255.255.0.0 ←任意のサブネットマスク

GATEWAY=172.31.0.1  ←任意のゲートウェイ

DNS1="172.31.0.1"       ←任意のDNS

ネットワーク再起動

# systemctl restart network

SELinuxを無効化する

# getenforce

Enforcing

有効状態なので常時無効化しておきます。

# vi /etc/selinux/config

# This file controls the state of SELinux on the system.

# SELINUX= can take one of these three values:

#     enforcing - SELinux security policy is enforced.

#     permissive - SELinux prints warnings instead of enforcing.

#     disabled - No SELinux policy is loaded.

#  ↓enforcingからdisabledへ変更

SELINUX=disabled    

# SELINUXTYPE= can take one of three two values:

#     targeted - Targeted processes are protected,

#     minimum - Modification of targeted policy. Only selected processes are protected.

#     mls - Multi Level Security protection.

SELINUXTYPE=targeted

再起動

reboot
getenforce

Permissive

disableになっていることを確認

更新

# yum -y update

開発者ツール群を一括インストール。

今後の開発中に無用なトラブルを避けるためにもインストールしておきます。

yum -y groupinstall base "Development tools"

Apache

インストール

yum install -y httpd httpd-devel

systemctl start httpd

systemctl enable httpd

httpd-devlはhttpdの開発パッケージでmod_wsgiを使用するときに必要なのでインストールをします。

これがないとmod_wsgiをインストールするときにエラーになりますので必ずインストールします。

ファイアウォールの変更

firewall-cmd --permanent --zone=public --add-service=http

success

firewall-cmd --permanent --zone=public --add-service=https

success

firewall-cmd --reload

今回はhttpでしか使いませんが、今後の展開のためにhttpsも開けておきます。

必要に応じて開放してください。

起動確認

ブラウザで上記で指定した固定IPで見れることを確認します。 f:id:boonv4m312s:20200419165548p:plain

Python

インストール

今回はPython3.6をインストールします。

yum install -y https://centos7.iuscommunity.org/ius-release.rpm

yum install -y python36u python36u-libs python36u-devel python36u-pip

Virtualenvインストール

pip3.6 install virtualenv

pip3.6 install --upgrade pip

Flask環境構築

virtualenvを設置

virtualenvは/opt/内作成します

cd /opt

virtualenv venv

仮想環境に接続します

source /opt/venv/bin/activate

Flaskをインストール

pip install flask

mod_wsgiをインストール

pip install mod_wsgi

インストールの確認

pip list

Package      Version

------------ -------

Click        7.0

Flask        1.1.1

itsdangerous 1.1.0

Jinja2       2.11.1

MarkupSafe   1.1.1

mod-wsgi     4.7.1

pip          20.0.2

setuptools   45.2.0

Werkzeug     1.0.0

wheel        0.34.2

Flaskとmod_wsgiがインストールされていることを確認する

アプリの作成

/var/www/html内にFlaskのアプリを作成していきます。

本当は別のディレクトリの方がセキュリティが高いのですが、ユーザーの権限の問題が複雑化するので上記のパスで作成します。

アプリの作成

cd /var/www/html/

vi app.py

from flask import Flask

app = Flask(__name__)

@app.route('/')

def hello_world():

   return "Hello World!"

if __name__ == '__main__':

   app.run(host='0.0.0.0')

ファイアウォールの変更

作成したアプリをデバックモードで実行するとポート5000番を使用します。

外部から接続ができるようにするために、ポート開けてあげます。

デバッグ時だけ有効にしてあげましょう。

firewall-cmd --add-port=5000/tcp --permanent

success

firewall-cmd --reload

success

デバッグモードで起動確認

python /var/www/html/app.py

* 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://0.0.0.0:5000/ (Press CTRL+C to quit)

mod_wsgiの設定

Flask.wsgiの作成

/var/www/html/flask.wsgi

# coding: utf-8

activate_this ='/opt/venv/bin/activate_this.py'

with open(activate_this) as file_:

   exec(file_.read(), dict(__file__=activate_this))

import sys

sys.path.insert(0, '/var/www/html/')

from app import app as application

mod_wsgiモジュールをコピー

mod_wsgiをインストールするとApacheで使用するモジュールも作成されます。

そのためこのモジュールを使用できるようにする必要があります。

選択肢はいくつかあって権限の問題が発生しないコピーの方法を選択します。

モジュールのある場所

cd /opt/venv/lib64/python3.6/site-packages/mod_wsgi/server/

ls -l

 __init__.py

 __pycache__

apxs_config.py

environ.py

management

mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so

mod_wsgiがあることを確認します

確認したモジュールをApacheのモジュールディレクトリ/etc/httpd/modules/にコピーします。

今回のコピーコマンドになります。環境によって違う可能性があるのでパスを確認しながらコピーしてください。

cp /opt/venv/lib64/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so  /etc/httpd/modules/

Apacheに設定

wsgiの設定情報を作成するには2つパターンがあります。

/etc/httpd/conf/httpd.conf のconfに追記するか

/etc/httpd/conf.d/の中にwsgi.confファイルを作成するかいずれかになります。

今回は作成する方法を採用します。

# vi /etc/httpd/conf/wsgi.conf

LoadModule wsgi_module /etc/httpd/modules/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so

<VirtualHost *:80>

 WSGIDaemonProcess app user=apache group=apache python-home=/opt/venv

 WSGIScriptAlias / /var/www/html/app.wsgi

<Directory /var/www/html>

WSGIProcessGroup app

WSGIApplicationGroup %{GLOBAL}

Order allow,deny

Allow from all
</Directory>
</VirtualHost>

サービスの起動の確認

Apacheを再起動をする

systemctl restart httpd

ブラウザでアクセス

ブラウザでアクセスしてHello Worldが出てくれば成功です。 f:id:boonv4m312s:20200419170644p:plain

最後に

いかがでしたか? お役に立ちましたでしょうか? 今後もブログの方を更新していきますのでよろしくお願いします。 最後になりますが、もしよろしければ読者の皆様からご支援いただけるのであればご支援いただきたく思います。 Amazon欲しい物リストを公開していますので、ご支援よろしくお願いします。

www.amazon.jp