1. abun-kobu

    Posted

    abun-kobu
Changes in title
+Apache/PandocでMarkdownをHTMLで配信するDockerコンテナの作成
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,162 @@
+ # Apache/PandocでMarkdownをHTMLにして配信するDockerコンテナの作成
+
+## はじめに
+
+ApacheとPandocを組み込んだDockerコンテナを作成してみたので体験を共有します。
+
+Pandocを使用するとMarkdownをHTMLやPDFに変換できます。
+これをApacheに組み込むとMarkdownをダイナミックにHTMLに変換できます。
+こうして作ったWebサイトをDockerコンテナに入れると構築や配布が楽になります。
+たとえばAmazon AWSのコンテナサービスに登録するなど利用範囲が広がります。
+
+>Dockerファイルほかソースはgithubで、作成済みのDockerイメージはDocker Hubで公開済みです(末尾参照)。
+
+## Pandoc
+
+ローカルPCで(たとえばWindows WSLを用いて)Pandocコンバータを使ってMarkdownをHTMLに変換するには:
+
+```
+$ ls
+ test.md
+$ cat test.md
+ # test.md
+ Hello **Wonderful** World.
+$ pandoc test.md > test.html
+$ ls
+ test.md
+ test.html
+$ cat test.html
+ <h1 id="test.md">test.md</h1>
+ <p>Hello <strong>Wonderful</strong> World.</p>
+$
+```
+
+## Apache
+
+ApacheでMarkdownファイルの拡張子`md`が参照された場合にPandocが実行されるようにすればHTMLへの自動変換が実現できます。
+それにはApacheの外部フィルタというしくみを使うのが簡単です。
+Apacheで次のような設定をすれば、Markdownファイルが参照された場合に指定のフィルタが実行されます。
+ここでは`pandoc-filter`という名前です。
+
+[local.conf]
+```
+LoadModule ext_filter_module modules/mod_ext_filter.so
+
+ExtFilterDefine pandoc-filter \
+ mode=output intype=text/markdown outtype=text/html \
+ cmd="/usr/local/apache2/pandoc-filter"
+
+<Directory /usr/local/apache2/htdocs>
+ SetOutputFilter pandoc-filter
+ AddType text/markdown .md
+</Directory>
+```
+
+説明します。
+- `LoadModule`で外部フィルタを利用可能とする`ext_filter_module`をロード。
+- `ExtFilterDefine`でフィルタが対象とするMIMEタイプとコマンドのパスを指定。
+- `Directory`内は、指定ディレクトリ内で拡張子`md`を持つファイルが参照された場合にフィルタを実行してもらう設定。
+
+## Apacheフィルタ
+
+Pandocを呼び出すApacheフィルタを作成しました。
+標準入力で渡されるMarkdownソースをPandocを呼び出して標準出力に変換結果のHTMLを出力するBashシェルスクリプトです。
+
+[pandoc-filter]
+```
+ #!/bin/bash
+ BASENAME=$(basename -s .md $DOCUMENT_URI)
+ /usr/bin/pandoc -f gfm -t html5 -c "/pandoc-gfm.css" \
+ -T "Converted" -M title=${BASENAME}
+```
+
+補足します。
+- 参照されたMarkdownファイルのパスがDOCUMENT_URI環境変数で渡される。
+ たとえば「/test.md」など。ここからPandocに渡すタイトルを取る。
+- `-f`は変換元の形式、`-t`は変換先の形式、`-c`はスタイルシートの場所、
+ `-T`と`-M title=`で出力されるHTMLのタイトルを指定。
+- Pandocは何も指定しないと標準入力から読み込み標準出力へ出力する。
+
+## Docker作成
+
+上記のApache設定ファイルとフィルタスクリプトを組み込んだDockerコンテナを作成します。
+
+```
+$ ls
+ Dockerfile
+ usr-local-apache2/
+$ ls usr-local-apache2
+ local.conf
+ pandoc-filter
+$ cat Dockerfile
+ FROM httpd:2.4
+ RUN apt-get update && apt-get install -y pandoc
+ COPY ./usr-local-apache2 /usr/local/apache2/
+ RUN echo 'Include local.conf' >> /usr/local/apache2/conf/httpd.conf
+$ docker build -t pandoc:test .
+```
+
+順に説明します。
+- Dockerコンテナを作る場合にはビルド手順を書いたDockerfileを作成する。
+- FROMで元になるDockerイメージを指定。
+ 公式DockerハブからLinuxとApacheを備えたhttpdというイメージを取得。
+- RUNでPandocをインストール。
+- COPYで先に用意したApache設定ファイルとフィルタをコンテナにコピー。
+ コピー先は/usr/local/apachce配下。
+- Dockerのビルドコマンドを実行。
+
+## Dockerコンテナ実行
+
+Dockerコンテナができたら作成したホスト上で実行してみます。
+
+```
+$ docker run --detach -publish 8080:80 \
+ --mount type=bind,src=/var/docker/pandoc/htdocs,dst=/usr/local/apache2/htdocs,ro \
+ pandoc:test
+```
+
+順に説明します。
+- `--detach`はコンテナをバックグラウンド(デーモンとして)実行する指定。
+- `--publish`で外部からもアクセスできるようホストマシンのポートとコンテナ内で使用するポートを結びつける。
+- `--mount`はコンテナ内のドキュメントディレクトリの/usr/local/apache2/htdocsをホスト側のディレクトリに結びつける。
+そうしないといちいちコンテナにファイルを追加しなくてはなりません。
+
+## テスト
+
+まずコンテナを実行しているホストマシン内から:
+
+```
+$ curl localhost:8080/test.md
+```
+
+続いてホストマシンの外部からブラウザでアクセスします。
+
+```
+http://example.com:8080/test.md
+````
+
+## 使用環境
+
+- Docker CE 19.03.12
+- ベースイメージ: 公式 [httpd:2.4](https://hub.docker.com/_/httpd)
+- テスト環境: Raspberry Pi 3B (raspiban/debian10-buster)、クラウド上のVPS(同じくDebian10-Buster)
+
+## 参考リンク
+
+- [Apache](https://httpd.apache.org/)
+- [Pandoc](https://pandoc.org/)
+- [Docker](https://www.docker.com/)
+
+DockerfileやApache設定ファイル、Apacheフィルタのソースはgithubで公開しました。
+git cloneしてdocker buildすればコンテナが作成できます。
+
+- [github](https://github.com/kobucom/docker-pandoc)
+
+作成したイメージはDocker Hubからも取得できます。
+
+- [docker-hub](https://hub.docker.com/r/kobucom/pandoc)
+
+横浜工文社の関連ページ
+
+- [docker](https://kobu.com/docker/)
+