CentOS 7: Apache (httpd)のCGIでpyenvを使えるようにする

　本稿が初投稿になります。プログラミングも駆け出しの初心者です。至らない点が多いかと思いますので、ご指摘お待ちしております。


# 1. 目的
　本稿の主題は、CentOS 7のApache (httpd)のCGI で仮想環境のpyenvを利用できるように設定している最中に直面したエラーとその解決策です。仮想環境ごとにPythonを実行できるWebサーバーを構築します。（セクション5にApacheやpyenvのインストールなど、一連の手順を記述しています）


# 2. 動作環境
・ CentOS 7

```
$ cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
$ uname -r
3.10.0-514.26.2.el7.x86_64
```
・ Apache (httpd)
・ [pyenv](https://github.com/yyuu/pyenv.git)
・ SELinux は disabled


# 3. 動機
　機械学習で注目を集めるPythonを実行できるWebサーバーを作ろうと思いました。機械学習に欠かせないAnacondaやTensorflowなどを使用したいので、仮想環境の下で動作するサーバーが望ましいでしょう。
　
　いざpyenvとhttpdをインストールしてテスト用の.pyファイルをサーバー上で実行してもエラーが出てしまい、直接的な解決策がどこにも見当たらなかったので、忘備録として、これからCentOSでpyenvを利用したサーバーを作りたい方々の参考になるように認（したた）めておきます。

# 4. エラーと解決策
## 4.1. 発生したエラー
　pyenvをrootユーザーで、

```
# git clone git://github.com/yyuu/pyenv.git ~/.pyenv
```

でインストールしました。（もちろんpyenv-virtualenvも。）
　`/var/www/cgi-bin/`に、Shebang（シバン）を以下のように指定したsample.pyファイル

```py3:/var/www/cgi-bin/sample.py
#!/root/.pyenv/versions/{VIRTUAL_ENV_NAME}/bin/python
```

を配置し、

```
# chmod 755 sample.py
```

でパーミッションの変更を行いましたが、http://127.0.0.1/cgi-bin/sample.py （127.0.0.1はローカルマシンのブラウザーで閲覧する場合のIPアドレス）で表示されたブラウザーのページはInternal Server Errorでした。下記がその内容：

### 500 Internal Server Error
Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.

### エラーログ

```
# tail /var/log/httpd/error_log
```

曰く、

```text:/var/log/httpd/error_log
[Fri Sep 15 18:39:12.890589 2017] [cgi:error] [pid 1302] [client 192.168.10.2:60025] AH01215: (13)Permission denied: exec of '/var/www/cgi-bin/sample.py' failed
[Fri Sep 15 18:39:12.890725 2017] [cgi:error] [pid 1302] [client 192.168.10.2:60025] End of script output before headers: sample.py
```

（日時とclientのIPアドレス、ポート番号は編集しています）

　シバンがデフォルトのPython2.7のPath、`#!/usr/local/bin/python`だと動作しました。シバンに原因があるようです。

## 4.2. 原因と解決策
　rootでのログイン時、pyenvを`/root`直下に置いた（つまり`/root/.pyenv`）ことがInternal Sever Errorの原因だったようです。（`/root`にはアクセス権限が無いのでしょうか。システム全体にpyenvをインストールする必要があるみたいです）
　pyenvを`/usr/local/pyenv`にインストールすることで上記の問題が解決しました。そこで、pyenvをGithubからインストールするときは、下のコマンドで実行しましょう。

```
# git clone git://github.com/yyuu/pyenv.git /usr/local/pyenv
# git clone git://github.com/yyuu/pyenv-virtualenv.git /usr/local/pyenv/plugins/pyenv-virtualenv
```

# 5. ApacheとpyenvのインストールからWebサーバーでの仮想環境の実行まで
　ここからはおまけのセクションです。ApacheとpyenvのインストールからWebサーバーでpyenvの仮想環境を実行する一連の手順を記します。

## 5.1. Apache(httpd)のインストールとconfig設定
　Apacheをインストールします。

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

　`vim /etc/httpd/conf/httpd.conf`を実行し、下記を追記します。

```xml:/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
</Dicrectory>
```

（最後の行のコマンドはOSの起動時にApacheを起動するためのものです。）


## 5.2. SELinux の disabled 化
　SELinuxのconfigの編集には十分注意して下さい。最悪の場合、カーネルパニックに陥るようです。

```
$ getenforce
Disabled
```

となるか確認します。`Disabled`でない場合、SELinuxを編集する必要があります。

```
$ sudo setenforce 0
$ sudo vim /etc/selinux/config
```

```properties:/etc/selinux/config
SELINUX=disabled
```


## 5.3. pyenvのインストール
　前提となるパッケージのインストールをします。

```
$ sudo yum -y install git
$ sudo yum -y group install "Development Tools"
$ sudo yum -y install readline-devel lib-devel bzip2-devel sqlite-devel openssl-devel
```

　pyenvをGithubからインストールします。

```
# git clone git://github.com/yyuu/pyenv.git /usr/local/pyenv
# git clone git://github.com/yyuu/pyenv-virtualenv.git /usr/local/pyenv/plugins/pyenv-virtualenv
```

をTerminalで実行します。

　仮想環境の作成に関しては、本稿では割愛させて下さい。

## 5.4. Apacheでpyenvの仮想環境を実行する
　あとは、

```py3:/var/www/cgi-bin/sample.py
#!/usr/local/pyenv/versions/{YOUR_VIRTUAL_ENV_NAME}/bin/python

print("Content-Type text/html")
print("")
print("<!DOCTYPE html>")
print("<html>")
print("<head>")
print("    <metacharset='utf-8'>")
print("    <title>SAMPLE</title>")
print("</head>")
print("<body>")
print("    <h1>Hello, world!</h1>")
print("</body>")
print("</html>")

```

を`/var/www/cgi-bin/`のディレクトリに配置します。{YOUR_VIRTUAL_ENV_NAME}はご自身の仮想環境の名前に当てはめて下さい。

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

と、パーミッションの変更をお忘れなく。

　ブラウザーで http://{Server's IP Address}/cgi-bin/sample.py をURL検索欄に入力して下さい。Hello, world!が表示されたら完了です。


# 6. 参照
　問題解決および寄稿にあたって引用・参考にさせていただいたリファレンスです。
・ [CentOS7上でPython3をCGIとして動かすまで - Qiita](http://qiita.com/kusyami_p/items/7ca4fd774c12fc6324a2)
・ [CentOSにpyenvとrbenvをシステム全体にインストール - Qiita](http://qiita.com/nyango/items/f227c259485fbd3c7c9c)
・ [pyenv + virtualenv (CentOS7) - Qiita](http://qiita.com/saitou1978/items/e82421e29e118bd397cc)