以前、httpd:alpineのApacheを使ってみました。
Docker for Macにて、httpd:alpineのApacheを使ってみた - メモ的な思考的な
今回は、DockerでAlpine3.4 + Apache2.4.25 + Python3.6.0の環境を作って、CGIでPythonスクリプトを動かしてみます。
目次
環境
Dockerfile作成
当初、ApacheとPython3.6のDockerfileをマージしようかと考えました。
ただ、両者のDockerfileを比べると、
- Apache2.4.25のDockerfileは、alpine3.5
- Python3.6のDockerfileは、alpine3.4
と、alpineのバージョンが異なっていました。試しに、PythonのDockerfileをalpine3.5としてコピペして作ってみましたが、うまくいきませんでした。
そこで今回は、Python3.6のalpine版のイメージ + ApacheをセットアップするDockerfileを作成することにしました。
Apacheのalpine3.4版を探したところ、このあたりがApache2.4.25 + alpine3.4の組み合わせでしたので、これを流用します。
https://github.com/docker-library/httpd/blob/0e4a0b59e1f4e2a5a14ca197516beb2d4df1ffb8/2.4/alpine/Dockerfile
追加箇所としては、
- Apacheをバックグラウンドで動かすための
httpd-foreground
ファイルを、build前に自分のローカルへコピーしておき、それをDockerに渡すCOPY httpd-foreground /usr/local/bin/
httpd-foreground
ファイルのパーミッションを変更RUN ["chmod", "+x", "/usr/local/bin/httpd-foreground"]
- これをやらないと、エラー
/bin/sh: httpd-foreground: Permission denied
- shell - docker entrypoint running bash script gets “permission denied” - Stack Overflow
httpd-foreground
ファイルの実行の仕方を、CMD httpd-foreground
へと変更- ローカルにあるhttpd.confをコピー
COPY httpd.conf /usr/local/apache2/conf/
- ディレクトリは、公式サイトの記載に従った(httpd - Docker Store)
- ローカルにあるCGIで動かすPythonスクリプトをコピー
- Pythonスクリプトのパーミッションを変更
RUN ["chmod", "755", "/usr/local/apache2/cgi-bin/hello.py"]
です。
それを反映させたDockerfileは以下です。
FROM python:3.6.0-alpine # ここにhttpd:2.4.25-alpineの内容をコピー(記載は省略) COPY httpd-foreground /usr/local/bin/ RUN ["chmod", "+x", "/usr/local/bin/httpd-foreground"] COPY httpd.conf /usr/local/apache2/conf/ COPY hello.py /usr/local/apache2/cgi-bin/ RUN ["chmod", "755", "/usr/local/apache2/cgi-bin/hello.py"] EXPOSE 80 CMD httpd-foreground
Apacheの設定
デフォルトの設定を確認
alpine3.4に設定されているApacheの状態が分からなかったため、以下を参考に、一度DockerでApacheを起動して確認します。
- Dockerであそぶ(4)Apacheの設定を変える | TECH Projin
- Docker チートシート - Qoosky
- dockerのapacheコンテナにすぐログインできるワンライナー - Qiita
# ビルド $ docker build -t alpine:python360_httpd2425_cgi . ... Successfully built b49daed5ae56 # 起動 $ docker run -p 8081:80 --name temp alpine:python360_httpd2425_cgi # Apacheでloadされているモジュールを確認 $ docker exec -it `docker ps | grep temp | awk '{print $1}'` /bin/bash bash-4.3# httpd -M Loaded Modules: core_module (static) so_module (static) http_module (static) mpm_event_module (static) authn_file_module (shared) authn_core_module (shared) authz_host_module (shared) authz_groupfile_module (shared) authz_user_module (shared) authz_core_module (shared) access_compat_module (shared) auth_basic_module (shared) reqtimeout_module (shared) filter_module (shared) mime_module (shared) log_config_module (shared) env_module (shared) headers_module (shared) setenvif_module (shared) version_module (shared) unixd_module (shared) status_module (shared) autoindex_module (shared) cgid_module (shared) dir_module (shared) alias_module (shared) # 別のコンソールを起動して、Dockerを停止 $ docker stop temp temp # ローカルでhttpd.confを確認するため、 # tempコンテナからhttpd.confをローカルの任意のディレクトリ(ここではdir)へコピー $ docker cp temp:/usr/local/apache2/conf/httpd.conf /path/to/dir/httpd.conf
httpd.confを読むと、コメントアウトされているものの#Include conf/extra/httpd-mpm.conf
との記載があっため、そちらもローカルへコピーして内容を確認します。
$ docker cp 4ee9667e6b7e:/usr/local/apache2/conf/extra/httpd-mpm.conf /path/to/dir/httpd-mpm.conf
必要最低限の設定へと変更
httpd.conf
やhttpd -M
を見ると、いくつか不要そうなのがあったため、ロードするモジュールを以下に変更します。
authz_core_module modules/mod_authz_core.so
とauthz_host_module modules/mod_authz_host.so
- Directoryディレクティブで
Require
を使うため - Gentooの~amd64にApache 2.4.1が来たので試してみた
- Directoryディレクティブで
mime_module modules/mod_mime.so
- content-typeの設定で使うため
- HTML5時代の Contents-type 設定 - Qiita
log_config_module modules/mod_log_config.so
- ログまわり
env_module modules/mod_env.so
unixd_module modules/mod_unixd.so
- UserやGroupを使うため
- Apache2.2の設定ファイルをApache2.4に移植するためにやったことまとめ
status_module modules/mod_status.so
cgid_module modules/mod_cgid.so
- event MPMでCGIを動かすため、mod_cgiではなく
mod_cgid
を使う - mod_cgid - Apache HTTP サーバ バージョン 2.4
- event MPMでCGIを動かすため、mod_cgiではなく
LoadModule alias_module modules/mod_alias.so
- その他参考
上記を反映したhttpd.confは以下です。
# ServerRoot: The top of the directory tree ServerRoot "/usr/local/apache2" # Listen: Allows you to bind Apache to specific IP addresses and/or ports Listen 80 # LoadModule LoadModule authz_core_module modules/mod_authz_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule unixd_module modules/mod_unixd.so LoadModule status_module modules/mod_status.so LoadModule cgid_module modules/mod_cgid.so # CGIをAliasで動かすので使用 LoadModule alias_module modules/mod_alias.so # unixd_module settings User daemon Group daemon # 'Main' server configuration # ServerAdmin: Your address, where problems with the server should be e-mailed. ServerAdmin you@example.com # Deny access to the entirety of your server's filesystem. <Directory /> AllowOverride none Require all denied </Directory> # DocumentRoot DocumentRoot "/usr/local/apache2/htdocs" <Directory "/usr/local/apache2/htdocs"> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory> # The following lines prevent .htaccess and .htpasswd files <Files ".ht*"> Require all denied </Files> # Log settings ErrorLog /proc/self/fd/2 LogLevel warn # log_config_module settings LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common CustomLog /proc/self/fd/1 common # alias_module settings ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/" # CGI directory <Directory "/usr/local/apache2/cgi-bin"> AllowOverride None Options ExecCGI SetHandler cgi-script Require all granted </Directory> # mime_module settings TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz
Pythonスクリプトの作成
Hello worldなスクリプトを作成します。
CGIで動かすため、先頭のshebangも必要です。そのため、shebangに指定するPythonを調べてみました。
# コンテナに入る $ docker exec -it `docker ps | grep temp | awk '{print $1}'` /bin/bash # pythonのありかを調べる bash-4.3# which python /usr/local/bin/python
#!/usr/local/bin/python # デバッグのために使用 import cgitb cgitb.enable() print('Content-Type: text/plain;charset=utf-8\n') print('Hello World!')
Dockerを起動して確認
設定ファイルを色々修正したため、Dockerイメージを作り直して動作を確認します。
# コンテナの全削除 docker rm $(docker ps -a -q) # イメージIDの確認 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE alpine python360_httpd2425_cgi b49daed5ae56 About an hour ago 170 MB # イメージの削除 $ docker rmi b49daed5ae56 # イメージの再作成 $ docker build -t alpine:python360_httpd2425_cgi . # 起動 $ docker run -p 8081:80 --name temp2 alpine:python360_httpd2425_cgi # 別のコンソールからアクセス $ curl http://localhost:8081/cgi-bin/hello.py Hello World!
動作しているようです。
ソースコード
GitHubに上げました。alpine_apache_python36_cgi
ディレクトリの中が、今回のものです。
thinkAmi-sandbox/Docker_Apache-sample