Cgi
python3
centos7

CentOS7上でPython3をCGIとして動かすまで

More than 1 year has passed since last update.

タイトルの通り。wsgiではなく伝統的なCGIとして動かすまで。

1. 前提条件

  1. Python3.xがインストールされていること
  2. CentOS7.x系であること
  3. SELinuxはdisabledであること

2. コマンド

2.1. Apacheインストール・起動

$ sudo yum -y install httpd
$ sudo systemctl start httpd
$ sudo systemctl enable httpd

この時点でhttp://[サーバのIPアドレス]/を入力してApacheのデフォルトページが表示されることを確認
※ virtualboxでNATをしている場合はhttp://[サーバのIPアドレス]:[指定したポート番号]/

2.2. Apache設定

$ sudo vim /etc/httpd/conf/httpd.conf
/etc/httpd/conf/httpd.conf
<IfModule alias_module>
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options ExecCGI
    Require all granted
    AddHandler cgi-script .py .pyc
</Directory>

2.3. Pythonファイルの作成

$ sudo vim /var/www/cgi-bin/sample.py
/var/www/cgi-bin/sample.py
#!/usr/bin/python3

print("Content-Type: text/html;")
print("")
print("<!DOCTYPE html>")
print("<html lang='ja'>")
print("<head>")
print("    <meta charset='utf-8'>")
print("    <title>hello world.</title>")
print("</head>")
print("<body>")
print("    <h1>hello world.</h1>")
print("</body>")
print("</html>")

シバン(1行目の#!/usr/bin/python3)は、各々の環境に読み替えてください。Python3.xの実行ファイルが入っている場所を書く必要があります。
特にpyenvなどを使っている場合はここの指定は気を付けてあげてください。

先にwhich pythonなどとして場所を確認しておくとよいです。

!日本語を表示したい場合は下記を2行目(シバンのすぐ下)に追加!

import sys
import io

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

2.4. Pythonファイルのパーミッションの変更

755になってたら変更しなくていいですが、そうでない場合は変更。

sudo chmod 755 /var/www/cgi-bin/sample.py

2.5. 表示確認

http://[サーバのIPアドレス]/cgi-bin/sample.pyを入力して「hello world.」が表示されることを確認

3. トラブルシューティング

Internal Server Errorなどと表示されうまくいかない場合の対処法が下記。
とりあえず下記コマンドでApacheのログを確認。

$ sudo tail /var/log/httpd/error_log

3.1. (13)Permission denied: exec of '/var/www/cgi-bin/sample.py' failedと書かれている

3.1.1. Apacheの設定ミス

もう一度正しく設定が行なわれているか確認してください。

3.1.2. ファイルのパーミッション

ls -al /var/www/cgi-bin/sample.pyなどでパーミッションを確認し、-rwxr-xr-x(755)になっているか確認してください。

3.1.3. SELinuxの設定ミス

getenforceを実行して結果が「Enforcing」の場合、SELinuxが効いている可能性があります。virtualbox上で動かしているなどの場合は必要ないかと思いますので、設定をオフにしましょう。何かの本番用であれば、それ相応の設定をしておきましょう。オフにする場合は下記です。

$ sudo setenforce 0
$ sudo vim /etc/selinux/config
/etc/selinux/config
SELINUX=disabled

ちなみに設定をミスしてしまうと最悪カーネルパニックだそうなので気を付けましょう。

3.1.4. シバンで指定しているPythonのパーミッション

pyenvなど仮想環境を使っている場合、配置されているディレクトリによってはパーミッションが適切ではない場合があります。ls -la [対象のPython実行ファイルまでのパス]などとし、-rwxr-xr-x(755)であることを確認してください。
ちなみにpyenvを使っている場合のシバンは#!/home/[username]/.pyenv/versions/3.5.2/bin/python#!/home/[username]/.pyenv/shims/python#!/usr/local/.pyenv/versions/3.5.2/bin/pythonなどとなると思いますので、自分の環境に読み替えたうえでパーミッションが適切か確認してください。

3.2. それ以外のエラー

単純に文法をミスしているか、Content-Type:text/htmlを忘れているか、日本語を表示しようとしているのに上記の行を追加していないなどがあると思います。

4. 結びに

Python3+CGIの組み合わせでの記事がほとんどなく、はまったときのトラブルシューティングなどもなかったため、書いてみました。何か誤り等あればコメントいただければ幸いです。