ほげほげ見聞録

技術メモ、備忘録、使い方はそのうち覚える

さくらのレンタルサーバー(ライトプラン)でbottleを動かすときのメモ

最初にやったのが1年位前で、今回再びbottleを動かそうとして詰まったのでサクッとまとめ。
bottleを動かす環境準備とテンプレートファイルの「Hello World!」を表示するところまで。
pythonやbottleそれ自体に関しては他にもっと良い文献があると思われるので、そちらを当たると吉。

さくらのレンタルサーバーとbottleを選んだ理由

さくらのレンタルサーバー(ライトプラン)

大層な機能はいらない。値段的な理由で。

bottle

DBを使うほどではないが、ページの管理を楽にしたいのでフレームワークを使いたい。
今まで使ったの事のない言語で簡単にできそうなのがPythonだったので。




サーバーの環境

さくらのサイトで確認したところ、以下のものが使えるとのこと(2017/11/28)。

サーバー Python
Apache 2.x系 2.7.x

Python2.7はbottleの最新版でも対応しているので問題なし。
ただし、Pyhonを実行する場合はCGIでやる必要がある。

何はともあれHello World.

実際にPython動かすにはどうするのさ、という話。
上の表からPythonのパスを調べて1行目に設定し、以下のsetup.cgiを作成。
サーバーのドキュメントルートにファイルをアップロード。

#!/usr/local/bin/python
# -*- coding: utf-8 -*-

print "Content-Type: text/plain;charset=utf-8\n\n"
print "Hello World."


※以降の実行ファイル(CGIPythonファイル)の設定

ブラウザからアクセスし、「Hello World.」が表示されていたら成功。




余談

※ファイルはUTF-8で作成したはずが、アップロード後のサーバー上ではSJISになっている…なんてことがある。

FTPソフトで確認するとSJISに、さくらのファイルマネージャーだとEUCになってたりする。
詳しい事は分からないが、自動で変換されてしまうらしい。後々問題になるが、今は無視しておく。


※ライトプランだとSSH使えないので、設定の確認やパッケージの導入ではsetup.cgiに必要なコマンドを書いて行う

他に良い方法があるのかも知れないが、手っ取り早く済ませたいので。




使用可能なPythonのモジュール

bottleではテンプレートエンジンに「SimpleTemplate Engine」と「jinja2 http://jinja.pocoo.org/docs/2.10/」が使用可能。
jinja2の方が機能が充実してるようなので、今回はそちらを選ぶことに。

そんなわけで、jinja2が使用可能か確認する必要あり。
Pythonのモジュールの存在を確認するには以下を実行すると一覧表示される。

help('modules')

osやsysなど基本的なモジュールはあるものの、jinja2は見当たらない(はず)。
というわけで、自分のホームディレクトリにjinja2をインストールする必要あり。
先ほどのモジュール一覧の中に「easy_install」があるので、このコマンドを使ってjinja2を導入する。

※以降「foo」は自分のホームディレクトリ名に置き換える




モジュールの位置

導入するといっても何処にすればいいのか、という話。

以下を実行すると「/home/foo/.local/lib/python2.7/site-packages」のようなパスが出力されるはず。
このパスにモジュールがあるとPython実行時に自動で検索対象に追加される。

import site
print site.USER_SITE






モジュールのインストール

先ほどの場所にjinja2を入れるには以下のコマンドを実行。

os.putenv()という関数で環境変数を設定し、easy_installでjinja2をインストール。
インストールするディレクトリ「.local」のパーミッションは変えておいた方がいいかもしれない。

import os
os.putenv('PYTHONPATH','foo/.local/lib/python2.7')
os.putenv('PYTHONPATH','foo/.local/lib/python2.7/site-packages')

import subprocess
subprocess.check_output("easy_install --prefix=foo/.local/lib/python Jinja2")

再び以下を実行すると、「jinja2」が追加されているはず。

help('modules')





bottleの導入

環境が整ったので、ドキュメントルートにbottle.py、index.cgi、index.tplを設置。

index.cgi

#!/usr/local/bin/python
# -*- coding: utf-8 -*-


"""文字コードの設定
文字コードの設定はサーバー側で設定して、プログラム側ではいじらないのが基本。
なのだが、前述のようにさくらのレンタルサーバーだとサーバー上ではSJISになっている。
しょうがないのでプログラムの以下を実行する必要がある。
(.htaccessで変更する方法もあるらしいが未検証)
"""
import os
import sys
reload(sys)
sys.setdefaultencoding('utf-8')


# モジュールの読み込み
from bottle import route, run, url, jinja2_template, TEMPLATE_PATH


# bottleがテンプレートファイルを読みに行く場所を追加
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
TEMPLATE_PATH.append(BASE_DIR)

# index.tplの表示
@route('/')
def index():
    return jinja2_template('index',
                               url=url
                               )

if __name__ == '__main__':
    run(server='cgi')

index.tpl

<h1>Hello World!!!</h1>

ブラウザでindex.cgiにアクセスして、h1の「Hello World!!!」が表示されていたら成功。




よくあるエラー

  • End of script output before headers: index.cgi
    • CGIはすべてUTF8、LFに統一
  • AH01215: suexec policy violation
  • UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128): /home/foo/www/setup.cgi
    • 文字コードUTF-8に変更(アップロード後に自動でUTF-8意外になってしまう場合はプログラム内で変更)