序文
wamw Friday I/O 2日目です。
株式会社ワムウでは、毎週金曜日は 興味がある事柄に取り組み、その成果を何らかの形でアウトプットする日 としています。
最近ドキュメントを書く機会が増えてきて、Markdownで書いたり、Keynoteで書いたり、残念ながらWordで書く必要があったりしていたのですが、色々とダルいのでこれを機にreStructuredTextで書くことに統一しようかなと思った次第であります。
欲しいもの
- reStructuredTextが簡単にビルドできる
- ReadTheDocsテーマで吐き出される
- アウトプット形式はとりあえずHTMLのみ
- blockdiagが埋め込める
- とにかくさっくり書ける
と言ったもの。
ドキュメントを公開してどうにかする話は一旦考えません。
作ったもの
- https://github.com/suttang/docker-sphinx-rtd-theme
- https://hub.docker.com/r/suttang/sphinx-rtd-theme/
以下構築時のログ
方向性としては Docker に alpine で良いのですが、Python入れたりなんやかんやが面倒なのでベースは python:alpine3.6
を使用します。
それでは作っていきましょう。
構築手順
まず立ち上げて
docker run --rm -it python:alpine3.6 sh
コンテナ内で作業しましょう。
apk のアップデート
apk update
次に Sphinx のインストール
pip install sphinx
ReadTheDocs テーマのインストール
pip install sphinx_rtd_theme
blockdiag を使えるように
pip install sphinxcontrib-blockdiag
すると下記エラーが発生します。
The headers or library files could not be found for zlib,
a required dependency when compiling Pillow from source.
Please see the install instructions at:
https://pillow.readthedocs.io/en/latest/installation.html
上記URIによると blockdiag が依存している Pillow には zlib
と libjpeg
が必要らしいので追加します。
apk add zlib-dev libjpeg-turbo-dev
そして再度 sphinxcontrib-blockdiag
のインストール
pip install sphinxcontrib-blockdiag
するとまたエラー
unable to execute 'gcc': No such file or directory
error: command 'gcc' failed with exit status 1
gcc
ねーよですね、わかります。追加します。
apk add alpine-sdk
そしてふたたび sphinxcontrib-blockdiag
のインストール
pip install sphinxcontrib-blockdiag
したら
Installing collected packages: Pillow, webcolors, blockdiag, sphinxcontrib-blockdiag
Successfully installed Pillow-4.2.1 blockdiag-1.5.3 sphinxcontrib-blockdiag-1.5.5 webcolors-1.7
GOOD
良さそうなので動かしてみましょう。
適当なディレクトリを作成して sphinx-quickstart
します。
mkdir documents
cd documents
sphinx-quickstart
で、Enter連打します。
/documents # ls -l
total 32
-rw-r--r-- 1 root root 607 Aug 4 05:52 Makefile
drwxr-xr-x 2 root root 4096 Aug 4 05:52 _build
drwxr-xr-x 2 root root 4096 Aug 4 05:52 _static
drwxr-xr-x 2 root root 4096 Aug 4 05:52 _templates
-rw-r--r-- 1 root root 5129 Aug 4 05:52 conf.py
-rw-r--r-- 1 root root 437 Aug 4 05:52 index.rst
-rw-r--r-- 1 root root 805 Aug 4 05:52 make.bat
良さそうですね。
ReadTheDocs テーマと blockdiag を使うために conf.py
を書き換えます。
書き換え内容は下記を参照してください。
sphinxcontrib-blockdiag の設定を見ていて思い出しましたが、 blockdiag で日本語を利用する場合日本語フォントが必要です。
サクッと入れましょう。
mkdir /fonts
cd /fonts
wget -O ipag00303.zip http://ipafont.ipa.go.jp/old/ipafont/ipag00303.php
unzip ipag00303.zip
rm ipag00303.zip
では conf.py
を書き換えます。
cd /documents
vi conf.py
変更点はざっくりと以下の通りです。
# (略
# 上の方に追加
import sphinx_rtd_theme
# (略
extensions = ['sphinxcontrib.blockdiag']
blockdiag_fontpath = '/fonts/ipag00303/ipag.ttf'
# (略
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
では、適当な blockdiag を index.rtd
に追加してビルドできるか試してみましょう。
追加する blockdiag は下記。
これを index.rtd
最下部に追加します。
vi index.rtd
.. blockdiag::
blockdiag {
A -> B;
}
それではお待ちかねのビルド。
make html
どうだ!?
WARNING: dot code 'blockdiag {\n A -> B;\n}': The _imagingft C module is not installed
あんれ〜???
謎エラー発生によりテンションが下がりましたが、気を取り直して行きましょう。
ググると freetype
が無い、とか freetype
を入れる前に PIL
を入れた、とかそんなことが原因のようです。
厳密には PIL
というか blockdiag が依存している Pillow
のようなので、 freetype
を入れて、 Pillow
を入れ直します。
apk add freetype freetype-dev
pip uninstall Pillow
pip install --no-cache-dir Pillow
Installing collected packages: Pillow
Running setup.py install for Pillow ... done
Successfully installed Pillow-4.2.1
はいOK。
再度HTMLのビルドを試します。
index.rst
の変更がないまま make html
するとスルーされるので、変更が無いファイルもビルドするように直接コマンドを叩きます。
/documents # sphinx-build -b html . build -a
Running Sphinx v1.6.3
loading pickled environment... done
building [mo]: all of 0 po files
building [html]: all source files
updating environment: 0 added, 0 changed, 0 removed
looking for now-outdated files... none found
preparing documents... done
writing output... [100%] index
generating indices... genindex
writing additional pages... search
copying static files... done
copying extra files... done
dumping search index in English (code: en) ... done
dumping object inventory... done
build succeeded.
やっとできましたー!バンザイ!
Dockerfile 化する
ではコンテナを落として、上記手順をDockerfile化します。
FROM python:alpine3.6
RUN apk add --update alpine-sdk zlib-dev libjpeg-turbo-dev freetype freetype-dev
# Setup sphinx
RUN pip install sphinx
RUN pip install sphinx_rtd_theme
RUN pip install sphinxcontrib-blockdiag
# Download IPA font
RUN wget -O ipag00303.zip http://ipafont.ipa.go.jp/old/ipafont/ipag00303.php
RUN unzip ipag00303.zip
RUN mkdir /fonts
RUN mv ipag00303 /fonts/ipag00303
RUN rm ipag00303.zip
# Create workspace
RUN mkdir documents
WORKDIR /documents
VOLUME /documents
CMD sphinx-build -b html source build
ビルド
$ docker build -t "suttang/sphinx-rtd" .
Sending build context to Docker daemon 2.56kB
Step 1/14 : FROM python:alpine3.6
---> d3265765e054
Step 2/14 : RUN apk add --update alpine-sdk zlib-dev libjpeg-turbo-dev freetype freetype-dev
---> Using cache
---> f9b74dfbe0e5
Step 3/14 : RUN pip install sphinx
---> Using cache
---> 481679fabb80
Step 4/14 : RUN pip install sphinx_rtd_theme
---> Using cache
---> f4624f1c9cd5
Step 5/14 : RUN pip install sphinxcontrib-blockdiag
---> Using cache
---> 4a8f1215942c
Step 6/14 : RUN wget -O ipag00303.zip http://ipafont.ipa.go.jp/old/ipafont/ipag00303.php
---> Running in 8c50a21d1d55
Connecting to ipafont.ipa.go.jp (192.218.88.244:80)
Connecting to dl.ipafont.ipa.go.jp (192.218.88.241:80)
ipag00303.zip 22% |****** | 927k 0:00:03 ETA
ipag00303.zip 46% |************** | 1952k 0:00:02 ETA
ipag00303.zip 70% |********************* | 2954k 0:00:01 ETA
ipag00303.zip 94% |***************************** | 3968k 0:00:00 ETA
ipag00303.zip 100% |*******************************| 4194k 0:00:00 ETA
---> 7bbd1be59b06
Removing intermediate container 8c50a21d1d55
Step 7/14 : RUN unzip ipag00303.zip
---> Running in 8b9ec2261aa6
Archive: ipag00303.zip
inflating: ipag00303/IPA_Font_License_Agreement_v1.0.txt
inflating: ipag00303/ipag.ttf
inflating: ipag00303/Readme_ipag00303.txt
---> 9135aa18dbcd
Removing intermediate container 8b9ec2261aa6
Step 8/14 : RUN mkdir /fonts
---> Running in 2d655893af56
---> b1d088bf26d0
Removing intermediate container 2d655893af56
Step 9/14 : RUN mv ipag00303 /fonts/ipag00303
---> Running in 9f12be5ee89d
---> a6cc6b5c11eb
Removing intermediate container 9f12be5ee89d
Step 10/14 : RUN rm ipag00303.zip
---> Running in fa890dc377b8
---> 7feacda3729e
Removing intermediate container fa890dc377b8
Step 11/14 : RUN mkdir documents
---> Running in 9c42f44088cb
---> 8626b91e8118
Removing intermediate container 9c42f44088cb
Step 12/14 : WORKDIR /documents
---> a531d8f1ed3c
Removing intermediate container da3f03619764
Step 13/14 : VOLUME /documents
---> Running in 8386cf1e1598
---> f05dab1e7b73
Removing intermediate container 8386cf1e1598
Step 14/14 : CMD sphinx-build -b html source build
---> Running in 591ded5dff8a
---> 13c675be97fc
Removing intermediate container 591ded5dff8a
Successfully built 13c675be97fc
Successfully tagged suttang/sphinx-rtd:latest
EXCELLENT
設定初期化スクリプト
ただ、このままだと conf.py
を自分で用意する必要があるので面倒ですね。
上の方で作った conf.py
をイメージに保持して、 /documents/conf.py
がなかったらそこにコピーする、としましょう。
まず初期化用のディレクトリを作成します。
mkdir init
conf.py
をうまいことします。
cd init
vi conf.py.example
内容はこんな感じ。
そしてこの conf.py.example
をコピーするスクリプトを追加します。
vi init.sh
#!/bin/sh
cp /init/conf.py.example /documents/conf.py
chmod 755 init.sh
で Dockerfile にこんな感じに追加
# Copy initialize scripts
COPY init init
そしてイメージのビルド
cd ..
docker build -t "suttang/sphinx-rtd" .
はい、では先程の初期化スクリプトが動くか確かめてみましょう。
docker run --rm -it -v $(pwd)/documents:/documents/ suttang/sphinx-rtd /init/init.sh
問題なく documents/conf.py
が出来上がりましたね。
よかったよかった。
このあと色々といじって最終的な生成物はこちらになります。