python webアプリのトラブルシューティング

Webアプリケーションを本番環境でデプロイメントさせたときに出現する、わけのわからないエラーに対するトラブルシューティングです。


pyファイルを更新したのに反映されない。

HTML生成のためのpyファイルを更新したのに、ときどき昔のpyファイルが参照されてしまう問題が起こる。

・「__pycash__」の中に入っているpycファイルを除去
・systemctl restart httpd でリスタート

とりあえずこれを行うと問題が解消された。理由はよくわからないが、そういう癖をつけておくとよかろう。


画像ファイル生成時のパーミッションエラー:

ドキュメントルートにあるpyファイルのなかに、fileやoutputなどの画像保存用のディレクトリがあるとする。ここに、pyファイルのplt.savefigなどで画像ファイルを作ろうとすると、Error: 500 Internal Server Error / Permission deniedというエラーがブラウザから出る。

・画像ファイルを生成するディレクトリ(file, outputなど)の所有者を apache にすること
・apacheに対して、そのディレクトリの権限を、「w: 書き込み(2)」と「x: 実行(1)」を与えること。つまり、3か7を指定する。これは、画像ファイルの生成などに、ファイルの書き込みが必要となるためです。

ls -lコマンドを打ち、


drwxr-xr-x 2 apache xxx 24 May 8 17:40 yyy

というように、所有者名がapacheになっているか、所有者の権限にwxがあるか確認しましょう。ない場合は、

chown apache:xxx yyy
chmod 755 yyy

のように、apacheを所有者にし、権限に7か3を与えてください。大事なのは、所有者に権限を与える1つ目の数字です。xxxは一般ユーザ名(ssh接続でログインしているアカウント)、yyyは画像ファイルなどを生成する先であるディレクトリ名です。chmodコマンドをかけるときは、

chmod 755 /var/ ... /アダプタ

のように、フルパスで行う必要があります。

なお、pyファイルの中に、画像の保存先ディレクトリyyyは、


@route('/yyy/') # (2) この画像ファイルを検索
def static(filename):
    return static_file(filename, root = os.getcwd() + "/yyy")

というように、必ず記載しておくこと。os.getcwdはpyファイルがあるディレクトリです。それに”/yyy”を足しているので、フルパスで画像ファイルをロードするディレクトリを書いているわけです。


昔の画像が表示される(html側のキャッシュ問題)。

キャッシュ問題です。対策には、以下のように、imgタグで指定する画像ファイルの後ろに、?をつけて、適当な文字列を入れます。下の例では、現在時刻を突っ込んでいます。キャッシュ対策で検索すると、似たような記述が出てくるはずです。


import time
cashtime = time.time()
css = css + ''


10%くらいの確率でロードに失敗する。

ほとんどうまく動くのに、10%くらいの稀によくありそうな確率で、画像が?マークでロードできていなかったり、テンプレートのhtmlファイルがないだとか、そんなエラーが出る。

ファイルロードや画像保存の命令から、htmlに反映させるという流れの中で、前の処理が終わっていないのにhtmlに反映させようとしていることが原因である。

そんなときは、画像ファイルを生成した後などに、


import time
n=2
time.sleep(n)

を書くと良い。これでn秒の遅延処理が発生する。

n=0.1 くらいで試してみて、ダメそうなら n = 2 など、大きめにしていく。ただし遅いとストレスなので、いい感じの値を頑張って見つける必要がある。取り急ぎ、runの前に2秒遅延を入れてみると、ロードエラーが出なくなった。

もうちょっとスマートな方法がないか、探し中。Javascriptだけならすぐに対策ができるものの。。。


テンプレートファイル(html)のロードエラー

複数のポートで公開しているときに、テンプレートファイルのロードエラーが起きることがある。

  • ポート別に、テンプレートhtmlファイルの名前を別々にする(同じだと、まずいみたいです)
  • アプリを公開しているところに、__pychash__がある。その中にキャッシュファイルがあるので、削除する。
  • サーバを再起動する。

これでスッキリする。特に、謎のエラーはサーバを再起動するとよくなることが多い。