以前、Docker + Alpine3.5 + Apache2.4 + Python2.7で、mod_pythonをソースコードからインストールしてみました。
Docker + Alpine3.5 + Apache2.4 + Python2.7で、mod_pythonをソースコードからインストールしてみた - メモ的な思考的な
その時はPython2.x系で試したため、今回はPython3.x系でmod_pythonをコンパイル&インストールし、Hello worldしてみます。
目次
- 環境
- まとめ
- 準備:prefork MPMで動作するApache2.4のDockerイメージを作成
- masterをコンパイル&インストール
- ブランチ3.5.xをコンパイル&インストール
- masterにブランチ3.5.xをマージして、コンパイル&インストール
- masterのビルド用ファイルをブランチ3.5.xの時点に戻して、コンパイル&インストール
- ソースコード
環境
- Mac OS X 10.11.6
- Docker for Mac 17.03.1-ce-mac12
- Alpine3.5 + Apache2.4.25
- 前回同様、Apacheはprefork MPMで動作するようにDockerfileを修正
- Python3系は以下の2種類を試す
- Alpine3.5のパッケージにあるPython3.5
- Alpine EdgeのパッケージにあるPython3.6
- Alpine3.6ならPython3.6が入るが、今回はAlpine3.5で検証
- mod_python
- GitHub上のmasterの最新版
- 今回利用したコミットは
8acf1b7
なお、動作させるためのDockerfileやhttpd.conf、Hello worldスクリプトは、以前のPython2系で使ったものを流用・一部修正していきます。
まとめ
長いので最初にまとめます。
- 最新のmaster(8acf1b7)ではPython3.x系は動作しない*1
- ブランチ
3.5.x
のソースコードであれば、Python3.x系は動作する - 最新のmasterで動作させるには、ビルド用のファイルをブランチ3.5.xのコミットへと戻す
- configure〜make installはあまり詳しくないので、3.5.xから最新までの間のどこでビルド用のファイルが壊れたかまでは追っていない
準備:prefork MPMで動作するApache2.4のDockerイメージを作成
今回の件とはあまり関係ないですが、後で再利用できるよう、Apache2.4 + prefork MPMのDockerイメージを作成しておきます。
(長いので省略しますが)Dockerfileは以下を使います。
https://github.com/thinkAmi-sandbox/Docker_Apache-sample/blob/master/alpine_apache_prefork/Dockerfile
thinkami:httpd24_prefork
という名前でDockerイメージを作成します。
$ docker image build -t thinkami:httpd24_prefork .
masterをコンパイル&インストール
mod_pythonのmasterをPython3.5でコンパイル&インストールするには、以前のDockerfileを以下の内容で修正します。
- mod_pythonで使用する
python
をpython3
へと変更 - mod_pythonをビルドする時に使う
python-dev
をpython3-dev
へと変更 - configureする時の
with-python
オプションを--with-python=/usr/bin/python3
へと変更
RUN apk --update --no-cache add python3 && \ python3 -m ensurepip && \ rm -r /usr/lib/python*/ensurepip && \ pip3 install --upgrade pip setuptools && \ rm -r /root/.cache && \ # mod_pythonで必要なパッケージを追加 apk add --no-cache --virtual .mod_python_build_libs git && \ apk --no-cache --virtual .mod_python_build_libs add python3-dev && \ apk add --no-cache --virtual .mod_python_build_libs apache2-dev && \ apk add --no-cache --virtual .mod_python_build_libs flex && \ # ./configureで必要 apk add --no-cache --virtual .mod_python_build_libs build-base && \ # sudo make installで必要 apk add --no-cache --virtual .mod_python_build_libs sudo && \ # GitHubからソースコードを持ってきてインストール cd /tmp && \ mkdir mod_python && \ cd mod_python && \ git clone https://github.com/grisha/mod_python.git . && \ ./configure --with-apxs=/usr/local/apache2/bin/apxs --with-python=/usr/bin/python3 --with-flex=/usr/bin/flex && \ make && \ sudo make install && \ # 不要なパッケージやソースコードを一括削除 apk del .mod_python_build_libs && \ rm -r /tmp/mod_python
docker image build
とdocker container run
します。
# Dockerイメージのビルド $ docker image build -t thinkami:python3_httpd24_mod_python_1 . ... Successfully built e2669af0e6a4 # Dockerコンテナの起動 => エラーで起動せず $ docker container run -p 8081:80 --name mod_python_1 -v `pwd`/htdocs/:/usr/local/apache2/htdocs thinkami:python3_httpd24_mod_python_1 httpd: Syntax error on line 19 of /usr/local/apache2/conf/httpd.conf: Cannot load modules/mod_python.so into server: Error relocating /usr/local/apache2/modules/mod_python.so: PyErr_BadArgument: symbol not found
エラーPyErr_BadArgument: symbol not found
が表示され、Dockerコンテナが起動しません。
ブランチ3.5.xをコンパイル&インストール
最新のmasterでは動作しなかったため、動作するブランチを探したところ、以下のIssueにコメントがありました。
mod_python 3.5.0 (with support for Python 3!) available for pre-release testing. · Issue #9 · grisha/mod_python
3.5.x
ブランチを使えばいいようです。
そのため、Dockerfileの中でgit cloneしている部分をmasterから3.5.x
ブランチへと修正します。
# git clone https://github.com/grisha/mod_python.git . && \
git clone -b 3.5.x https://github.com/grisha/mod_python.git . && \
docker image build
& docker container run
します。
$ docker image build -t thinkami:python3_httpd24_mod_python_2 . $ docker container run -p 8081:80 --name mod_python_2 -v `pwd`/htdocs/:/usr/local/apache2/htdocs thinkami:python3_httpd24_mod_python_2 [Fri Jun 09 03:51:43.408568 2017] [:notice] [pid 1] mod_python: Creating 8 session mutexes based on 256 max processes and 0 max threads. [Fri Jun 09 03:51:43.408632 2017] [:notice] [pid 1] mod_python: using mutex_directory /tmp [Fri Jun 09 03:51:43.445271 2017] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.25 (Unix) mod_python/3.5.0-9d223c3 Python/3.5.2 configured -- resuming normal operations [Fri Jun 09 03:51:43.445310 2017] [core:notice] [pid 1] AH00094: Command line: 'httpd -D FOREGROUND' [Fri Jun 09 03:52:06.023976 2017] [:notice] [pid 6] mod_python: (Re)importing module 'mptest' 172.17.0.1 - - [09/Jun/2017:03:52:05 +0000] "GET /test/mptest.py HTTP/1.1" 200 12
mod_pythonが起動したようです。
curlで動作確認をします。
$ curl localhost:8081/test/mptest.py -D - -v * Trying ::1... * Connected to localhost (::1) port 8081 (#0) > GET /test/mptest.py HTTP/1.1 > Host: localhost:8081 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK HTTP/1.1 200 OK < Date: Fri, 09 Jun 2017 03:52:05 GMT Date: Fri, 09 Jun 2017 03:52:05 GMT < Server: Apache/2.4.25 (Unix) mod_python/3.5.0-9d223c3 Python/3.5.2 Server: Apache/2.4.25 (Unix) mod_python/3.5.0-9d223c3 Python/3.5.2 < Transfer-Encoding: chunked Transfer-Encoding: chunked < Content-Type: text/plain Content-Type: text/plain < * Connection #0 to host localhost left intact Hello World!
Hello worldが表示されたため、正常に動作しているようです。
masterにブランチ3.5.xをマージして、コンパイル&インストール
上記ではブランチ3.5.xで動かしましたが、3.5.xブランチの最新コミットは2013年10月であるため、それ以降に修正された不具合は反映されていません。
試しにブランチ3.5.xとmasterの差分を見ると、以下の4コミットでした。 Comparing master…3.5.x · grisha/mod_python
4コミットには以下の8ファイルが含まれていました。
- Doc/Makefile.in
- Doc/changes.rst
- configure
- configure.in
- scripts/mod_python.in
- src/include/mod_python.h
- src/include/mod_python.h.in
- src/mod_python.c
そこで、masterにブランチ3.5.xを単純にマージし、動作するか試してみます。
Dockerfileでは
- git cloneするのをmasterから3.5.xブランチへ
- git mergeするために、ユーザの設定を任意の値へ
を修正します。
cd mod_python && \ # gitを使うためにユーザ設定を実施 git config --global user.email "you@example.com" && \ git config --global user.name "Your Name" && \ # 現在のmasterを取得 git clone https://github.com/grisha/mod_python.git . && \ # 3.5.xブランチを取得 git branch 3.5.x origin/3.5.x && \ # 3.5.xブランチをmasterにマージ git merge 3.5.x && \ ./configure --with-apxs=/usr/local/apache2/bin/apxs --with-python=/usr/bin/python3 --with-flex=/usr/bin/flex && \
docker image build
& docker container run
します。
$ docker image build -t thinkami:python3_httpd24_mod_python_3 . $ docker container run -p 8081:80 --name mod_python_3 -v `pwd`/htdocs/:/usr/local/apache2/htdocs thinkami:python3_httpd24_mod_python_3 [Fri Jun 09 03:54:21.257839 2017] [:notice] [pid 1] mod_python: Creating 8 session mutexes based on 256 max processes and 0 max threads. [Fri Jun 09 03:54:21.257983 2017] [:notice] [pid 1] mod_python: using mutex_directory /tmp [Fri Jun 09 03:54:21.391315 2017] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.25 (Unix) mod_python/3.5.0-7e4861f Python/3.5.2 configured -- resuming normal operations [Fri Jun 09 03:54:21.393658 2017] [core:notice] [pid 1] AH00094: Command line: 'httpd -D FOREGROUND'
mod_pythonが起動したようです。
curlで動作確認をします。
$ curl localhost:8081/test/mptest.py -D - -v * Trying ::1... * Connected to localhost (::1) port 8081 (#0) > GET /test/mptest.py HTTP/1.1 > Host: localhost:8081 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 500 Internal Server Error HTTP/1.1 500 Internal Server Error < Date: Fri, 09 Jun 2017 03:54:36 GMT Date: Fri, 09 Jun 2017 03:54:36 GMT < Server: Apache/2.4.25 (Unix) mod_python/3.5.0-7e4861f Python/3.5.2 Server: Apache/2.4.25 (Unix) mod_python/3.5.0-7e4861f Python/3.5.2 < Content-Length: 528 Content-Length: 528 < Connection: close Connection: close < Content-Type: text/html; charset=iso-8859-1 Content-Type: text/html; charset=iso-8859-1 < <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>500 Internal Server Error</title> </head><body> <h1>Internal Server Error</h1> <p>The server encountered an internal error or misconfiguration and was unable to complete your request.</p> <p>Please contact the server administrator at you@example.com to inform them of the time this error occurred, and the actions you performed just before this error.</p> <p>More information about this error may be available in the server error log.</p> </body></html> * Closing connection 0
Internal Server Errorになりました。
Docker containerのコンソールを見ると
[Fri Jun 09 03:54:36.714955 2017] [:error] [pid 6] make_obcallback: could not import mod_python.apache.\n [Fri Jun 09 03:54:36.716445 2017] [:error] [pid 6] make_obcallback: Python path being used "['/usr/lib/python35.zip', '/usr/lib/python3.5/', '/usr/lib/python3.5/plat-linux', '/usr/lib/python3.5/lib-dynload']". [Fri Jun 09 03:54:36.716560 2017] [:error] [pid 6] get_interpreter: no interpreter callback found. [Fri Jun 09 03:54:36.716596 2017] [:error] [pid 6] [client 172.17.0.1:36616] python_handler: Can't get/create interpreter. 172.17.0.1 - - [09/Jun/2017:03:54:36 +0000] "GET /test/mptest.py HTTP/1.1" 500 528
と、interpreterのcallbackが見当たらないようです。
よって、単純なマージではダメなようです。
masterのビルド用ファイルをブランチ3.5.xの時点に戻して、コンパイル&インストール
差分のあった8ファイルのうちビルド用ファイル
- configure
- configure.in
- scripts/mod_python.in
- src/include/mod_python.h
- src/include/mod_python.h.in
- src/mod_python.c
を、ブランチ3.5.x時の状態に戻した上でコンパイル&インストールします。
また、コンパイルにはAPKのEdgeにあるPython3の最新版を利用してみます。
Dockerfileの変更は
# Python3まわり RUN apk --update --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/main/ add python3 && \ python3 -m ensurepip && \ rm -r /usr/lib/python*/ensurepip && \ pip3 install --upgrade pip setuptools && \ rm -r /root/.cache && \ # python3-devもEdgeから持ってくる # そうでないと、Python3のバージョンが合わずに、Downgrading python3が発生する apk --no-cache --virtual .mod_python_build_libs --repository http://dl-cdn.alpinelinux.org/alpine/edge/main/ add python3-dev && \ ... # mod_pythonまわり cd mod_python && \ # gitを使うためにユーザ設定を実施 git config --global user.email "you@example.com" && \ git config --global user.name "Your Name" && \ # 現在のmasterを取得 git clone https://github.com/grisha/mod_python.git . && \ # 3.5.xブランチを取得 git branch 3.5.x origin/3.5.x && \ # 3.5.xブランチをmasterにマージ git merge 3.5.x && \ # python3用に、masterブランチのうちの一部ファイルを3.5.xブランチの状態へ戻す => OK git checkout 2d013b353631feb7ffe29fe9946327a08fe55381 scripts/mod_python.in && \ git checkout 54d42b1810d5abfffe5b407d8e763402a0d4b2f0 configure.in && \ git checkout 9d223c39a8f27345d8c046d026468fc0c1ad5d53 configure && \ git checkout 51f7b0366d66b58b5b82874fe8a2db346f77d7fc src/include/mod_python.h && \ git checkout 51f7b0366d66b58b5b82874fe8a2db346f77d7fc src/include/mod_python.h.in && \ git checkout affc26bd69b3f5e67e8233166ff0d40c43fb7302 src/mod_python.c && \ # ビルド ./configure --with-apxs=/usr/local/apache2/bin/apxs --with-python=/usr/bin/python3 --with-flex=/usr/bin/flex && \ ...
です。
docker image build
& docker container run
します。
$ docker image build -t thinkami:python3_httpd24_mod_python_4 . $ docker container run -p 8081:80 --name mod_python_4 -v `pwd`/htdocs/:/usr/local/apache2/htdocs thinkami:python3_httpd24_mod_python_4 [Fri Jun 09 03:56:17.740963 2017] [:notice] [pid 1] mod_python: Creating 8 session mutexes based on 256 max processes and 0 max threads. [Fri Jun 09 03:56:17.741173 2017] [:notice] [pid 1] mod_python: using mutex_directory /tmp [Fri Jun 09 03:56:17.959878 2017] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.25 (Unix) mod_python/3.5.0-2b3da9d Python/3.6.1 configured -- resuming normal operations [Fri Jun 09 03:56:17.960025 2017] [core:notice] [pid 1] AH00094: Command line: 'httpd -D FOREGROUND'
curlで動作確認をします。
$ curl localhost:8081/test/mptest.py -D - -v * Trying ::1... * Connected to localhost (::1) port 8081 (#0) > GET /test/mptest.py HTTP/1.1 > Host: localhost:8081 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK HTTP/1.1 200 OK < Date: Fri, 09 Jun 2017 03:56:34 GMT Date: Fri, 09 Jun 2017 03:56:34 GMT < Server: Apache/2.4.25 (Unix) mod_python/3.5.0-2b3da9d Python/3.6.1 Server: Apache/2.4.25 (Unix) mod_python/3.5.0-2b3da9d Python/3.6.1 < Transfer-Encoding: chunked Transfer-Encoding: chunked < Content-Type: text/plain Content-Type: text/plain < * Connection #0 to host localhost left intact Hello World!
Hello Worldが表示されました。
念のため、Dockerのコンソールを見ると
[Fri Jun 09 03:56:35.416889 2017] [:notice] [pid 6] mod_python: (Re)importing module 'mptest' 172.17.0.1 - - [09/Jun/2017:03:56:34 +0000] "GET /test/mptest.py HTTP/1.1" 200 12
と、無事に動いているようです。
ソースコード
GitHubに上げました。
thinkAmi-sandbox/Docker_Apache-sample
関係するディレクトリは以下の通りです。
alpine_apache_python3x_mod_python
- 今回試したソースコード一式
executable_py36_all_in_one
は、Alpine3.5のDockerイメージから、Apache2.4(prefork) + EgeのPython3.x + mod_python が動作する環境を作るDockerfile
alpine_apache_prefork
- Apache2.4をprefork MPMでビルドするDockerfile
*1:前回の記事にある通りこのコミットは自分のプルリクのものですが、動作しない原因は自分のコミットではありません、たぶん