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)