Dockerで、Alpine3.4 + Apache2.4.25 + Python3.6.0の環境を作って、CGIを動かしてみた

以前、httpd:alpineのApacheを使ってみました。
Docker for Macにて、httpd:alpineのApacheを使ってみた - メモ的な思考的な

今回は、DockerでAlpine3.4 + Apache2.4.25 + Python3.6.0の環境を作って、CGIPythonスクリプトを動かしてみます。

 
目次

 

環境

 

Dockerfile作成

当初、ApacheとPython3.6のDockerfileをマージしようかと考えました。

ただ、両者のDockerfileを比べると、

と、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

 
追加箇所としては、

です。

それを反映させた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 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.confhttpd -Mを見ると、いくつか不要そうなのがあったため、ロードするモジュールを以下に変更します。

 
上記を反映した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

 
これを元に、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