はじめに
先日ApacheとPandocを組み込んだDockerコンテナをご紹介しました → ローカル版
コンテナ内あるいはコンテナが動作するホストのディレクトリにソースファイルを置く方式でした。
そうではなく、提供したいMarkdownソースを含むWebリソースがコンテナホストの外部、つまりリモートにある場合に使えるコンテナ(リモート版)を作成したので公開します。
Dockerファイルほかソースはgithubで、作成済みのDockerイメージはDocker Hubで公開済みです(末尾参照)。
以下、前回のローカル版と共通の事柄は割愛します。
Apache
ローカル版の場合、Apache配下のディレクトリに実在するMarkdownソース(拡張子md
)の内容がフィルタの標準入力に渡されます。
しかしMarkdownファイルがApache配下のローカルディレクトリに存在しない場合、この方式は使えません。
Apacheには、アクションハンドラという、特定の拡張子を持つURLパスの要求があると、あらかじめ指定しておいたCGIスクリプトを呼び出してくれる、というしくみがあります。
要求されたパスがローカルディレクトリになくてもかまいません。
このしくみを使って、コンテナとは別のWebサーバからMarkdownソースを読み込んで、HTML変換するハンドラを作成しました。
次のApache設定でpandoc-handler
という名前のアクションハンドラを指定します。
[local.conf]
LoadModule cgid_module modules/mod_cgid.so
LoadModule actions_module modules/mod_actions.so
AddHandler markdown-text .md
Action markdown-text /cgi-bin/pandoc-handler virtual
SetEnv REMOTE_DIR https://elsewhere.com/docker
説明します。
-
LoadModule
でアクションハンドラを利用可能とするmod_actions
と、CGIスクリプトを利用可能とするmod_cgid
をロード。 -
AddHandler
とAction
ディレクティブで、URLパスで指定されたファイルが拡張子md
を持つ場合にCGIスクリプトのpandoc-handler
を呼び出してもらうよう設定 - SetEnvは次項で説明するリモートディレクトリの指定です。
ベースイメージの
httpd:2.4
ではあらかじめURLの'/cgi-bin'がスクリプト実行可能ディレクトリの'/usr/local/apache2/cgi-bin'に対応づけられているのでこれを利用する。
Apacheハンドラ
Pandocを呼び出すApacheハンドラを作成しました。
ApacheからPATH_INFO環境変数で渡されるURLパスに応じて取得したMarkdownソースをPandocで変換、標準出力にHTMLを出力するBashシェルスクリプトです。
要求されたURLパスからMarkdownソースを読み込む(あるいは生成することも可)方法はアプリケーションによって様々考えられます。
クラウドのファイルサービスから読む、どこかのデータベースから読む、リモートのgitレポジトリから取得、sftpで取得、などです。
このサンプルは固定のURLが指すリモートディレクトリからMarkdownソースファイルを読み込みます。
前項で設定済みのREMOTE_DIR
環境変数からcurl
コマンドでMarkdownファイルを読み込みます。
[pandoc-handler]
#!/bin/bash
BASENAME=$(basename -s .md $PATH_INFO)
curl -s $REMOTE_DIR$PATH_INFO | /usr/bin/pandoc -f gfm -t html5 -c "/pandoc-gfm.css" \
-T "Converted" -M title=${BASENAME}
説明します。
- 参照されたMarkdownソースのURLパスが
PATH_INFO
環境変数で渡される。 - 前項の
REMOTE_DIR
環境変数で指定しておいたリモートのWebサーバからcurl
で指定ファイルを取得。 -
pandoc
でHTMLに変換して標準出力へ出力
取得例:
- PATH_INFO = /test.md
- REMOTE_DIR = https://elsewhere.com/docker
- 取得ファイル = https://elsewhere.com/docker/test.md
Docker作成
上記のApache設定ファイルとハンドラスクリプトを組み込んだDockerコンテナを作成します。
$ ls
Dockerfile
usr-local-apache2/
$ ls usr-local-apache2
local.conf
pandoc-handler
$ cat Dockerfile
FROM httpd:2.4
RUN apt-get update && apt-get install -y \
pandoc \
curl \
ca-certificates
COPY ./usr-local-apache2 /usr/local/apache2/
RUN echo 'Include local.conf' >> /usr/local/apache2/conf/httpd.conf
$ docker build -t pandoc:remote .
前回同様、FROMで公式DockerハブからLinuxとApacheを含むベースイメージhttpd
を取得します。
前回とは異なり、RUNでpandoc
に加えてcurl
を取得します。
ca-certificate
はcurlでSSLを使うために必要だった。
前回同様、COPYでApache設定ファイルとアクションハンドラ(CGIスクリプト)をコンテナのしかるべき場所にコピーし、Dockerのビルドコマンドを実行します。
Dockerコンテナ実行
Dockerコンテナができたら作成したホスト上で実行してみます。
$ docker run --detach -publish 8080:80 pandoc:remote
前回のフィルタの場合と異なりローカルディレクトリは使わないので--mount
オプションはありません。
前回同様--public
オプションでポートの割り当てを行います。
テスト
まずコンテナを実行しているホストマシン内から:
$ curl localhost:8080/test.md
続いてホストマシンの外部からブラウザでアクセスします。
http://example.com:8080/test.md
これで 'https://elsewhere.com/docker/test.md' に置いたはずのMarkdownファイルがHTMLになって表示されれば成功です。
続いてこのDockerコンテナをAmazon AWSのコンテナサービスのひとつECS(Elastic Container Service)で動かしてみました。
次回はその顛末を書こうと思います。
使用環境
- Docker CE 19.03.12
- ベースイメージ: 公式 httpd:2.4
- テスト環境:
- Raspberry Pi 3B (raspiban/debian10-buster)
- クラウド上のVPS(同じくDebian10-Buster)
- Amazon AWS - Elastic Container Service (ECS)
参考リンク
DockerfileやApache設定ファイル、Apacheフィルタのソースはgithubで公開しました。
git cloneしてdocker buildすればコンテナが作成できます。
作成したイメージはDocker Hubからも取得できます。
- docker-hub tag:remote
横浜工文社の関連ページ
Written 2020/09/22