こんにちは。(ほ)です。
前回、GitbookのプロジェクトをCodePipeline, CodeBuildを使用してビルドをする方法について記載しました。
しかし、PDFのビルドについては触れていませんでしたので、今回はPDFを作成したいと思います。
GitbookでPDFを作成する場合は下記のようなコマンドを使用します。
| # HTML作成 | 
| $ gitbook build | 
| # PDF作成 | 
| $ gitbook pdf | 
しかし、CodeBuildで実行すると下記の4つのエラーが発生するため対処が必要です。
GitbookでPDFを作成するにはcalibreというebook-converterが必要です。
未インストールの場合は下記のようなエラーが出力されます。
| InstallRequiredError: "ebook-convert" is not installed. | 
| Install it from Calibre: https://calibre-ebook.com | 
下記のコマンドでcalibreをインストールすることで対処できます。
| apt-get update | 
| apt-get install calibre | 
GitbookでPDFを作成するにはディスプレイバッファが必要なのですが、CodeBuildなどのヘッドレス環境では存在しないため下記のようなエラーが出力されます。
| Traceback (most recent call last): | 
| File "/usr/bin/ebook-convert", line 20, in <module> | 
| sys.exit(main()) | 
| File "/usr/lib/calibre/calibre/ebooks/conversion/cli.py", line 359, in main | 
| plumber.run() | 
| File "/usr/lib/calibre/calibre/ebooks/conversion/plumber.py", line 1189, in run | 
| self.opts, self.log) | 
| File "/usr/lib/calibre/calibre/ebooks/conversion/plugins/pdf_output.py", line 123, in convert | 
| must_use_qt() | 
| File "/usr/lib/calibre/calibre/gui2/__init__.py", line 1041, in must_use_qt | 
| raise RuntimeError('X server required. If you are running on a' | 
| RuntimeError: X server required. If you are running on a headless machine, use xvfb | 
これはエラーメッセージにも出力されているとおり “xvfb” を使用することで対処できます。
| apt-get update | 
| apt-get install xvfb | 
| xvfb-run gitbook pdf | 
CodeBuildの環境には日本語フォントが含まれていないため文字化けしてしまいます。
下記のようにフォントをインストールすることで対処できます。
| apt-get update | 
| apt-get install fonts-ipafont-gothic fonts-ipafont-mincho | 
Calibreのプラグインの初期化時にエラーが発生します。
| [0;31mEbookError: Error during ebook generation: Failed to initialize plugin: Apple iTunes interface (1, 1, 1) | 
| Failed to initialize plugin: <class 'calibre.devices.apple.driver.ITUNES'> | 
| Traceback (most recent call last): | 
| File "/usr/bin/ebook-convert", line 20, in <module> | 
| sys.exit(main()) | 
| File "/usr/lib/calibre/calibre/ebooks/conversion/cli.py", line 341, in main | 
| parser, plumber = create_option_parser(args, log) | 
| File "/usr/lib/calibre/calibre/ebooks/conversion/cli.py", line 294, in create_option_parser | 
| from calibre.ebooks.conversion.plumber import Plumber | 
| File "/usr/lib/calibre/calibre/ebooks/conversion/plumber.py", line 16, in <module> | 
| from calibre.utils.date import parse_date | 
| File "/usr/lib/calibre/calibre/utils/date.py", line 13, in <module> | 
| from dateutil.tz import tzlocal, tzutc, EPOCHORDINAL | 
| File "/usr/local/lib/python2.7/dist-packages/dateutil/tz/__init__.py", line 1, in <module> | 
| from .tz import * | 
| File "/usr/local/lib/python2.7/dist-packages/dateutil/tz/tz.py", line 23, in <module> | 
| from ._common import tzname_in_python2, _tzinfo, _total_seconds | 
| File "/usr/local/lib/python2.7/dist-packages/dateutil/tz/_common.py", line 2, in <module> | 
| from six.moves import _thread | 
| ImportError: cannot import name _thread | 
ログを見ると “_thread” が import出来なくて発生しているようです。
別件ですが、同様のエラーが下記でも報告されています。
どうも、python-dateutilの2.6.0以降で発生するようですので、下記のように古いバージョンをインストールすることで回避できます。
| pip uninstall -y python-dateutil | 
| pip install python-dateutil==2.5.3 | 
上記の4つのエラーに対処すると、下記のようなbuildspec.ymlが出来上がります。
| version: 0.2 | 
| phases: | 
| install: | 
| commands: | 
| - apt-get update | 
| - apt-get install -y calibre xvfb fonts-ipafont-gothic fonts-ipafont-mincho | 
| - pip uninstall -y python-dateutil | 
| - pip install python-dateutil==2.5.3 | 
| - npm install -g gitbook-cli | 
| pre_build: | 
| commands: | 
| - gitbook install | 
| build: | 
| commands: | 
| - xvfb-run gitbook pdf | 
| post_build: | 
| commands: | 
| - ls -la | 
| artifacts: | 
| files: | 
| - book.pdf | 
このbuildspec.ymlを使用することで日本語を含むPDFを作成することが出来たのですが、HTMLのビルドに比べてinstall phaseに時間がかかってしまいます。
(当然、それに合わせて使用料も上がります。一番安い環境で $0.005/分)
そこで、CodeBuildで用意されている標準の環境イメージではなく、PDF作成用のイメージを作成してみたいと思います。
Docker Imageを作成する方法はいくつかあるのですが、CodeBuildで使用する必要があるため、下記で公開されているCodeBuildの標準イメージのDockerfileを参考にするのが良いと思います。
私の場合はnodejs:7.0.0環境をベースに下記のようなDockerfileを作成しました。
(&などがエスケープされています)
| FROM ubuntu:14.04.5 | 
| # Building git from source code: | 
| # Ubuntu's default git package is built with broken gnutls. Rebuild git with openssl. | 
| ########################################################################## | 
| RUN apt-get update \ | 
| && apt-get install -y --no-install-recommends \ | 
| wget python python2.7-dev fakeroot ca-certificates tar gzip zip \ | 
| autoconf automake bzip2 file g++ gcc imagemagick libbz2-dev libc6-dev libcurl4-openssl-dev \ | 
| libdb-dev libevent-dev libffi-dev libgeoip-dev libglib2.0-dev libjpeg-dev libkrb5-dev \ | 
| liblzma-dev libmagickcore-dev libmagickwand-dev libmysqlclient-dev libncurses-dev libpng-dev \ | 
| libpq-dev libreadline-dev libsqlite3-dev libssl-dev libtool libwebp-dev libxml2-dev libxslt-dev \ | 
| libyaml-dev make patch xz-utils zlib1g-dev unzip curl calibre xvfb fonts-ipafont-gothic fonts-ipafont-mincho \ | 
| && apt-get -qy build-dep git \ | 
| && apt-get -qy install libcurl4-openssl-dev git-man liberror-perl \ | 
| && mkdir -p /usr/src/git-openssl \ | 
| && cd /usr/src/git-openssl \ | 
| && apt-get source git \ | 
| && cd $(find -mindepth 1 -maxdepth 1 -type d -name "git-*") \ | 
| && sed -i -- 's/libcurl4-gnutls-dev/libcurl4-openssl-dev/' ./debian/control \ | 
| && sed -i -- '/TEST\s*=\s*test/d' ./debian/rules \ | 
| && dpkg-buildpackage -rfakeroot -b \ | 
| && find .. -type f -name "git_*ubuntu*.deb" -exec dpkg -i \{\} \; \ | 
| && rm -rf /usr/src/git-openssl \ | 
| # Install dependencies by all python images equivalent to buildpack-deps:jessie | 
| # on the public repos. | 
| && rm -rf /var/lib/apt/lists/* \ | 
| && apt-get clean | 
| RUN wget "https://bootstrap.pypa.io/get-pip.py" -O /tmp/get-pip.py \ | 
| && python /tmp/get-pip.py \ | 
| && pip install awscli==1.11.25 \ | 
| && pip uninstall -y python-dateutil \ | 
| && pip install python-dateutil==2.2 \ | 
| && rm -fr /var/lib/apt/lists/* /tmp/* /var/tmp/* | 
| ENV NODE_VERSION="7.0.0" | 
| RUN set -ex \ | 
| && for key in \ | 
| 9554F04D7259F04124DE6B476D5A82AC7E37093B \ | 
| 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \ | 
| 0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93 \ | 
| FD3A5288F042B6850C66B31F09FE44734EB7990E \ | 
| 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \ | 
| DD8F2338BAE7501E3DD5AC78C273792F7D83545D \ | 
| B9AE9905FFD7803F25714661B63B535A4C206CA9 \ | 
| C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ | 
| ; do \ | 
| gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ | 
| done | 
| RUN wget "https://nodejs.org/download/release/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz" -O node-v$NODE_VERSION-linux-x64.tar.gz \ | 
| && wget "https://nodejs.org/download/release/v$NODE_VERSION/SHASUMS256.txt.asc" -O SHASUMS256.txt.asc \ | 
| && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ | 
| && grep " node-v$NODE_VERSION-linux-x64.tar.gz\$" SHASUMS256.txt | sha256sum -c - \ | 
| && tar -xzf "node-v$NODE_VERSION-linux-x64.tar.gz" -C /usr/local --strip-components=1 \ | 
| && rm "node-v$NODE_VERSION-linux-x64.tar.gz" SHASUMS256.txt.asc SHASUMS256.txt \ | 
| && ln -s /usr/local/bin/node /usr/local/bin/nodejs \ | 
| && rm -fr /var/lib/apt/lists/* /tmp/* /var/tmp/* | 
| CMD [ "node" ] | 
| RUN npm install -g gitbook-cli svgexport | 
作成したDocker Imageは、DockerHubで公開したり、Amazon EC2 Container Registryに登録することでCodeBuildから使用することができます。
CodeBuildの「環境: ビルド方法」を下記のように変更します。
- 環境イメージ : Docker イメージの指定
 - 環境タイプ : Linux
 - カスタムイメージタイプ : Other(DockerHub) or Amazon ECR(Container Registry)
 - カスタムイメージ ID : repo-name/image-name:tag
 
カスタムイメージ ID の tag は latest の場合は不要ですが、その他の場合は必須です。
Docker ImageをCodeBuildで使用すると、buildspec.ymlの時よりも install phase分を短くすることができます。
install phaseに時間がかかっている場合は、Docker Imageを使用することを考えてみてください。


