python

Pythonで書いた自前のCGIをConoHa WINGで動かしてみる

ConoHa WINGというレンタルサーバーでCGIを動かす際の手順やハマりポイントなどを解説します。

Pythonで書いたCGIプログラムをローカルでテストする方法については別記事で紹介していますので、まだローカル環境ですらCGI動かしたことないよって人はまずこちらからどうぞ。
>> ローカルにpythonのCGI環境を構築 ほどよく解説しながらスピード重視で説明するよ

ConoHa WINGはこんなレンタルサーバー

ConoHa WINGは、レンタルサーバーの中でも最速と言われているサーバーです。

>> 国内最速・高安定の高性能レンタルサーバー【ConoHa WING】

実はこのブログもConoHa WINGで運営しています。

このブログのページ読み込み、すごい速くないですか?
最も安いベーシックプランで、しかも速度チューニングには特に工夫していないのに、です。

さらに言うと、このブログの他にも10ドメインくらいを同じベーシックプランのアカウントにつっこんで管理しているので、10サイト分の負荷を受けてもなお、この軽さなわけです。

へー、なんかよさそうだけど、他のレンタルサーバーからWordPressの引っ越しとかするの大変なんだよねー…
と思ったあなた。

大丈夫です。
簡単に引っ越しできる仕組みが用意されています。(これも体験済み)

料金が格安というわけではないけど、この速度で一般的な水準の価格に抑えられているので、費用対効果としてはバツグンだと思います。

そして今回のテーマである、Pythonで記述したCGIの動作検証も、後述するようにバッチシとれています。

前準備:PyCharmのエディタ設定で.cgiファイルを関連づけよう

さて、本題に入る前に、開発環境に.cgiファイルを関連付けておきましょう。

というのも、ConoHaをはじめとするレンタルサーバーでは、pythonで記述したCGIプログラムは .py というファイル拡張子ではなく .cgi というファイル拡張子にしないといけないという仕様になっているからです。

僕はPythonの開発環境にはPyCharmを使っているのですが、デフォルトでは.cgiファイルはPythonプログラムと認識されないため、ハイライトや入力補完などをしてくれず不便です。

ノート

PyCharmを使ったことがないよという方は、PyCharm - Wikipediaが参考になります。
とにかくPythonプログラマになっては人気なためオススメです。

もしPyCharmを使ってないという人は、Pythonの開発をするならすごくオススメなのでぜひこちらからPyCharmをインストールすることをオススメします。

とういことで、話それましたが.cgiをPythonプログラムファイルとして関連づける手順解説いきます。

  • PyCharmのメニューからSettings(Windowsの場合)またはPreferences(Macの場合)を選択して、設定ウインドウを表示する。
  • Editor → File Types と進み、Recognized file types: からPythonを選択する。
  • Registered patternsに .cgi を追加する。
PyCharmでPythonエディタに.cgiファイルを関連付ける手順

これで、.cgiという拡張子でファイルを作成しても、Pythonファイルとして扱ってくれるようになります。

CGIプログラムを書こう

CGIプログラムの基本については別記事を参照下さい。
>> ローカルにpythonのCGI環境を構築 ほどよく解説しながらスピード重視で説明するよ

今回ConoHa WINGで動作させるCGIプログラムがこちらです。

hello.cgi:

#!/opt/alt/python36/bin/python3.6

import sys
import io
sys.stdout = io.TextIOWrapper(
    sys.stdout.buffer, encoding='utf-8')

print("Content-Type: text/html")
print()
print('ケンヂまるだぜひゃっほーい')

順に説明していきます。

shebangでpythonを指定する

1行目の

#!/opt/alt/python36/bin/python3.6

という部分はシェバン(shebang)と飛ばれる記述です。
これは、サーバー上のパス「/opt/alt/python36/bin/python3.6」にあるプログラムインタープリタでこのファイルを実行しなさいという命令で、必ずCGIファイルの先頭に記述します。

python意外にも、サーバー上で実行できるプログラムで、なおかつ管理者から許可されているものであれば指定することができます。
例えばpythonではなくphpを使いたい場合は

#!/opt/alt/php70/usr/bin/php

といった指定になります。

サーバー上にあるプログラムなんてどうやってわかるの?
というと、レンタルサーバーのFAQなどにこういった情報が載っていますので、それを参考に指定します。
>> ConoHa プログラム言語のパスを教えてください。

ConoHa WINGの2020年6月25日現在でpythonで指定できるshebangは

  • python2系 → #!/opt/alt/python27/bin/python2.7
  • python3系 → #!/opt/alt/python36/bin/python3.6

のどちらかになっています。

print()関数からの出力がutf-8になるように指定する

import sys
import io
sys.stdout = io.TextIOWrapper(
    sys.stdout.buffer, encoding='utf-8')

3〜6行目では、sysモジュールとioモジュールを使って、標準出力がutf-8になるように置き換えています。

WindowsやMacなどのローカル環境でpythonを実行すると、print()関数などの標準出力のエンコーディングはそもそもutf-8ですから、特に意味はありません。

しかし、多くのレンタルサーバーはOSにLinuxを使っていて、そのデフォルトのエンコーディングはasciiになっています。

そのため何も対策をせずにマルチバイト文字をprint()関数などで出力しようとするとコーデイングエラーになってしまいます。

ココ、自分のPCで動作確認した時は動いていたのにサーバーにアップした途端動かなくなる…という時に要チェックのポイントです。

Content-typeヘッダを出力する

print("Content-Type: text/html")
print()

これはCGIでWebプログラミングをするならもはやおまじないの部分なので説明は割愛します。

ひゃっほーいと出力する

print('ケンヂまるだぜひゃっほーい')

最後に、print()関数を使って、今の自分の気持ちを表現しましょう。

サーバーにアップロードする

プログラムを作ったら、次はサーバーにアップロードする手順です。

まずはConoHa WINGにログインし、コントロールパネルを開きます。

サイト管理→ファイルマネージャー と選択し、public_htmlのどこでもいいのでフォルダを選択します。

(今回の確認のためにsamplesフォルダを作りました。)

そして自分のPCからファイルをドラッグ&ドロップで移動します。

アップロードされたファイルを右クリック→属性変更

パーミッションを755に変更(.cgiファイルの一般的な設定)

さてこれで、準備完了。

パーミッションとは

オーナー・グループ・他のユーザー(その他)が、そのファイルに対して読み取り・書き込み・実行できる権限を指定するものです。
(permit≒許可する)

この設定データは実際にはビットフラグで管理されているため、読み取りの4、書き込みの2、実行の1を合わせた値で表現されます。

CGIプログラムファイルは「755」として保存され、ログファイルなどは「666」として保存されるのが一般的です。

動作確認

ファイルを置いたパスにhttp://~と指定してブラウザのアドレス欄に入力し、動作確認してみましょう。

問題なく日本語も表示できてますね。
こんな感じで、あなたもいいプログラム作れたなと思ったら、CGIとして気軽に公開できるようになりましたね!

ConoHa WINGでCGIを実行する時ハマった話

実は、今回すんなりいかなかった部分もありました。

サーバーにPythonで作ったCGIファイルをアップロードして実行しようとした時に、次のようなエラーが出て解決に1時間以上要しました。

[Tue Jun 23 07:15:10.512906 2020] [cgi:error] [pid 293011] [client 182.251.128.150:0] AH01215: UnicodeEncodeError: 'ascii' codec can't encode character '\\u3042' in position 6: ordinal not in range(128): /home/c5334400/public_html/jimaru.blog/samples/hello.cgi

原因は、ConoHa WINGのサーバーのデフォルトの文字セットがASCII(シングルバイト文字)なのに対して、マルチバイト文字を出力しようとしていたのが原因でした。

今回作ったサンプルプログラムに書いてある

import sys
import io
sys.stdout = io.TextIOWrapper(
    sys.stdout.buffer, encoding='utf-8')

の部分は、悩んだうえで解決策として辿り着いたものですw
デフォルトのsys.stdoutがシングルバイト文字しか受け付けなかったので、utf-8の出力を作成してそれで置き換えるということをしています。

このように、レンタルサーバーそれぞれにクセがあるので、僕がある程度道を切り開いておきましたから、もしレンタルサーバーでCGIを動かしてみたいなって方は、今回紹介したConoHa WINGで試すのが一番安全だと思いますよ。

-python

© 2022 ヂまるBlog