Python
HTTP
Web
初心者
python3

[Python] 開発用ローカルサーバをそのまま運用にしちゃう超簡単サーバ

背景

Pythonには、ワンライナーで開発用ローカルサーバを立ち上げるコマンドがあります。

#ワンライナーで以下を実行。(python3の場合)
python -m http.server 8000
#補足:python2の場合は以下
python -m SimpleHTTPServer 8000
#終了時は、ctrl + c で停止

ブラウザから「 http://localhost:8000 」にアクセスすれば、
起動ディレクトリの中身またはIndex.htmlを返します。

ここまで、またはコレをスクリプト化する程度までは、
多数の諸先輩の記事があるのですが、
今回は、このまま簡単な運用可能サーバにしてしまおう、というテーマです。

本投稿の内容

本投稿は、内部サーバなど軽度なもので良い場合に、
python http.server をそのまま簡単なサーバとして公開するTips & スクリプトです。

  • コンソールを終了するとサーバも終了、にならないようにする。
  • 起動ログ/アクセスログをファイル出力する。(アクセス状況を知りたい)
  • WindowsとLinuxどちらでも動くようにして、Windowsでの味見も可能にする。
  • cronなどからの呼び出しにも対応しやすいようにする。

起動コマンドのTips

運用はlinux上で行うことを想定しています。
コンソールやsshを終了するとサーバも終了、ということにならないように、
以下のような形で起動することが一つのTipsです。
(pythonスクリプトファイル名を「http_server.py」とします。)
以下のようにnohupをつけて起動してください。バックグラウンド実行されます。

起動方法
nohup python http_server.py &
停止方法
#python http_server.py のプロセス番号を見つける
ps -ef | grep http
#見つけたプロセス番号をkillする
kill 99999(上記で見つけたプロセス番号)

アクセスログ付、簡易公開用スクリプト

Python3系のコードです。
運用に乗るように、cron起動、windowsとの共通コード、
アクセスログや起動ログの出力、などの様々な小さな工夫をしています。
詳細はコードのコメントをご参照ください。コメントを除けば短いコードです。
内部利用のためのサーバなど、簡単なサーバはこれで十分でしょう。
アクセス数なども後で解析出来るため、ログの出力は特にオススメです。
POSTに対応することもできますが本投稿の趣旨と外れるため割愛します。

http_server.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
from datetime import datetime
from http.server import HTTPServer, SimpleHTTPRequestHandler

#このpyファイルが存在するディレクトリパスを取得します。
#ファイル出力先を絶対パスにすることで、cronからの実行時などにも対応しやすくなります。
script_dir = os.path.abspath(os.path.dirname(__file__))

#本来はログのローテ等を考えるべきですが、簡易サーバなので、
#起動時の日付をファイル名にして、そのファイルにログを書き続けます。
#適宜リブート運用をすれば、1ファイルが超重くなることは避けられます。
#また、Windows,Linuxどちらの環境でも動くように、ファイルセパレータは「os.path.sep」で扱います。
logfilename = script_dir + os.path.sep + 'log_httpserver_' + datetime.now().strftime("%Y%m%d") +'.log'

#ログ出力を簡単に行うため、標準出力の情報を全てログに追記(a)出力することにします。
buffer = 1
# 通常のprintログなどの出力はstdoutです。
sys.stdout = open(logfilename,"a",buffer)
# 127.0.0.1 - - [23/Feb/2018 12:47:09] "GET / HTTP/1.1" 200 - などのアクセスログはstderr側に出力されます。
sys.stderr = open(logfilename,"a",buffer)

#自分自身で試す場合など他者にアクセスさせない場合は、localhostで起動しましょう。
#空白にすれば、ドメイン名やIPアドレスなどで他のマシンからアクセスできます。
#host = 'localhost'
host = ''
port = 8000
httpd = HTTPServer((host, port), SimpleHTTPRequestHandler)

#サーバ起動時のログを出力
print(' === Server Start!! === ', datetime.now().strftime("%Y/%m/%d %H:%M:%S") )
print('serving at port', port)
print('logfile = ' + logfilename)

#実際にサーバを起動します。
try:
    httpd.serve_forever()
except:
    print(' === Server Stopped === ', datetime.now().strftime("%Y/%m/%d %H:%M:%S") )

以上