開発時点であればシンプルサーバーを起動することができます。シングルプロセス、シングルスレッドとなるため商用環境では Apache または Nginx と組み合わせましょう。
必要なモジュールをインストールしてください。
# dnf -y install python3-pip # pip3 install wsgi_static_middleware
アプリケーションフォルダを作成してください。
# mkdir -p /opt/myapp
/opt/myapp/wsgi.py
を下記の様に作成してください。
from wsgiref.simple_server import make_server from wsgi_static_middleware import StaticMiddleware def application(environ, start_response): start_response("200 OK", [("Content-Type", "text/plain")]) return ["OK\n".encode("UTF-8")] if __name__ == "__main__": static_dirs = ["/opt/myapp/static"] app = StaticMiddleware(application, static_root="static", static_dirs=static_dirs) with make_server("0.0.0.0", 80, app) as httpd: try: httpd.serve_forever() except KeyboardInterrupt: pass
下記で実行してください。
# python3 -B /opt/myapp/wsgi.py
curl で動作確認します。
$ curl http://localhost OK
CSS や JS や画像などのスタティックファイルは /var/myapp/static
配下に置くことができます。
mod_wsgi の公式サイトは下記にあります。
必要なパッケージをインストールしてください。
# dnf -y install httpd gcc python3-pip python3-devel httpd-devel # pip3 install mod-wsgi
アプリケーションフォルダを作成してください。
# mkdir -p /opt/myapp
下記の内容で /opt/myapp/wsgi.py を作成してください。
def application(environ, start_response): start_response("200 OK", [("Content-Type", "text/plain")]) return ["OK\n".encode("UTF-8")]
mod_wsgi-*.so
ファイルのパス名を下記で調べてください。
# find / -name "mod_wsgi*.so"
/etc/httpd/conf.d/wsgi.conf ファイルに下記を記述してください。LoadModule
には上記で調べたパスを指定してください。
Alias /favicon.ico /opt/myapp/static/img/favicon.ico <VirtualHost "*:80"> LoadModule wsgi_module /usr/local/lib64/python3.9/site-packages/mod_wsgi/server/mod_wsgi-py39.cpython-39-x86_64-linux-gnu.so DocumentRoot /opt/myapp WSGIScriptAlias / /opt/myapp/wsgi.py Alias /static/ /opt/myapp/static/ <Directory /opt/myapp> Require all granted </Directory> </VirtualHost>
Apache を起動してください。
-- ホストOSの場合 -- # systemctl start httpd -- コンテナの場合 -- # /usr/sbin/httpd -DFORGROUND
curl で動作確認します。
$ curl http://localhost OK
コンフィグファイルに関する詳細は下記を参照してください。
Nginx の場合は uWSGI を使用します。uWSGI の公式サイトは下記にあります。
必要なモジュールをインストールしてください。
dnf -y install python3 python3-devel python3-pip nginx gcc pip3 install uwsgi
uwsgi を起動するユーザを作成してください。
useradd myapp
アプリケーションフォルダ、ログフォルダ、PIDファイル格納フォルダを作成してください。
mkdir -p /opt/myapp mkdir -p /var/log/myapp mkdir -p /var/run/myapp
/opt/myapp/uwsgi.ini
ファイルを作成してください。
[uwsgi] master = true socket = 127.0.0.1:8080 processes = 5 uid = myapp gid = myapp chdir = /opt/myapp wsgi-file = /opt/myapp/wsgi.py module = wsgi:application logto = /var/log/myapp/uwsgi.log pidfile = /var/run/myapp/uwsgi.pid
/opt/myapp/wsgi.py
ファイルを作成してください。
def application(environ, start_response): start_response('200 OK', [('Content-Type','text/html')]) return ["OK\n".encode("UTF-8")]
/etc/nginx/nginx.conf
ファイルに下記を追記してください。
server { ... location = /favicon.ico { root /opt/myapp/static/img; } location /static { root /opt/myapp; } location / { include uwsgi_params; uwsgi_pass 127.0.0.1:8080; } }
Nginx を起動します。
/usr/sbin/nginx
uWSGI を起動します。
uwsgi --ini /opt/myapp/uwsgi.ini &
停止するには下記を実行します。
uwsgi --stop /var/run/myapp/uwsgi.pid
curl で動作確認します。
$ curl http://localhost OK
.ini ファイルに関する詳細は下記を参照してください。
下記などはおすすめの設定です。
# X-Forwarded-For のIPアドレスをロギングする log-x-forwarded-for = true # 日時のフォーマットを指定する logformat-strftime = true logdate = %%Y-%%m-%%d %%H:%%M:%%S # ログフォーマットを指定する logformat = %(ftime) %(status) %(addr) %(uri) # ファイルをtouchするとログをローテートする(uwsgiにローテートさせる場合) touch-logrotate = /var/run/myapp/logrotate # ファイルをtouchするとログを再オープンする(logrotateでローテートする場合) touch-logreopen = /var/run/myapp/logreopen
Webサーバーがリクエストを受信すると application() を呼び出します。第一引数は環境変数、第二引数はレスポンスを返すための関数が渡されます。
def application(environ, start_response): headers = [("Content-Type", "text/plain")] start_response("200 OK", headers) return ["OK\n".encode("UTF-8")]
environ
に渡される環境変数には下記などがあります。
詳細は下記を参照してください。
GET パラメータは下記の様に読み込みます。
import urllib.parse params = {} qs = urllib.parse.parse_qs(environ["QUERY_STRING"]) for key, value in qs.items(): if len(value) == 1: params[key] = value[0] else: params[key] = value
POST パラメータは下記の様に読み込みます。
import urllib.parse params = {} content_length = environ["CONTENT_LENGTH"] wsgi_input = environ["wsgi.input"] if content_length: body = wsgi_input.read(int(content_length)).decode() qs = urllib.parse.parse_qs(body) for key, value in qs.items(): if len(value) == 1: params[key] = value[0] else: params[key] = value
JSONデータは下記の様に読み込みます。
import json params = {} content_length = environ["CONTENT_LENGTH"] wsgi_input = environ["wsgi.input"] if content_length: body = wsgi_input.read(int(content_length)).decode() params = json.loads(body)
HTTPステータスは下記の様に返します。
def application(environ, start_response): headers = [("Content-Type", "text/plain")] start_response("200 OK", headers) return ["OK\n".encode("UTF-8")]
レスポンスヘッダーは下記の様にして返します。
def application(environ, start_response): headers = [ ("Content-Type", "text/html"), ("Content-Encoding", "gzip") ] start_response("200 OK", headers) return ["OK\n".encode("UTF-8")]
HTTPボディーは下記の様に返します。UTF-8 でエンコードするなどバイナリデータとして返却してください。
def application(environ, start_response): headers = [("Content-Type", "text/plain")] start_response("200 OK", headers) return ["OK\n".encode("UTF-8")]