【Python】mod_wsgi + Vue.js の連携

                                                f:id:tm200:20210423222352j:plain

 

mod_wsgiでFlaskとVue.jsを連携させたので、備忘録として残しておきます。

あまり無いかもしれませんが、何かしらの理由でサーバーを1つに纏めたい場合に使えるかも😎

実際はkubernetes環境で実行するなどの事情もあり、分かりやすいように書き換えている為、内容に若干の不整合があるかもしれません。

 

 ⬇️ 在宅勤務のお供です。

 

環境

環境はDocker。

Node.jsはVue.jsのビルドにしか使用しない為、マルチステージビルドを採用。

以下、バージョン情報とフォルダ構成。

CentOS 7
Apache / 2.4.6
Python 3.7
Node 14

// フォルダ構成
project
├── config
│ └── test_server.conf
├── frontend
│ ├── vue.js プロジェクトを配置
│ └── package.json etc...
├── src
│ ├── Flask 各ファイルを配置
│ └── server.py etc...
├── app.wsgi
├── requirements.txt
└── Dockerfile

Dockerfile 

Pythonのインストール等々は省略。

FROM node:14.15.5 as build-stage
WORKDIR /app
COPY frontend/package*.json ./
RUN npm i
COPY
frontend
RUN npm run build

FROM centos:centos7 as production-stage
// 依存関係諸々インストール、必要に応じて変更して下さい
RUN yum install -y \
httpd httpd-dvel ... && \
rm -rf /var/cache/yum/* && \
yum clean all
COPY app.wsgi /var/www/html/app/
COPY config/test_server.conf /etc/httpd/conf.modules.d/
COPY requirements.txt /
RUN pip3 install -r requirements.txt && \
rm -rf `pip3 cache dir` && \
mod_wsgi-express install-module // このコマンドでインストール先を確認できる
COPY --from=build-stage /app/dist /var/www/html
COPY src /var/www/html/app/src
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND", "-f", "/etc/httpd/conf/httpd.conf"]
EXPOSE 80

config/test_server.conf

`/etc/httpd/conf.modules.d` 配下に配置します。

ServerSignature Off
ServerTokens ProductOnly
GracefulShutDown 120
LoadModule wsgi_module {mod_wsgiインストール先のパス}

<VirtualHost
*:80>
DocumentRoot
/var/www/html
.... // 諸々の設定
WSGIDaemonProcess
test-server threads=5 python-path=/var/www/html/app:{site-packagesのパス}
WSGIScriptAlias / /var/www/html/app/app.wsgi

<Directory
"/var/www/html/app">
Options +FollowSymLinks +ExecCGI
Require all granted
</Directory>

<Directory
"/var/www/html/static">
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

requirements.txt

mod-wsgi~=4.7.1
etc...

app.wsgi

FlaskのアプリケーションログをApacheの標準エラーログにリダイレクト。

# -*- coding: utf-8 -*-
import
sys
import os
import logging

logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))

from src.server import create_app

f = create_app()

def application(environ, start_response):
for x in environ:
os.environ[x] = str(environ[x])
return f(environ, start_response)