こんにちは。(ほ)です。
前回、GitbookのプロジェクトをCodePipeline, CodeBuildを使用してビルドをする方法について記載しました。
しかし、PDFのビルドについては触れていませんでしたので、今回はPDFを作成したいと思います。
GitbookのPDF作成で発生するエラーと対処
GitbookでPDFを作成する場合は下記のようなコマンドを使用します。
1 2 3 4 5 |
# HTML作成 $ gitbook build # PDF作成 $ gitbook pdf |
しかし、CodeBuildで実行すると下記の4つのエラーが発生するため対処が必要です。
1. ebook-convertが未インストール
GitbookでPDFを作成するにはcalibreというebook-converterが必要です。
未インストールの場合は下記のようなエラーが出力されます。
1 2 3 |
InstallRequiredError: "ebook-convert" is not installed. Install it from Calibre: https://calibre-ebook.com |
下記のコマンドでcalibreをインストールすることで対処できます。
1 2 3 |
apt-get update apt-get install calibre |
2. X server がない
GitbookでPDFを作成するにはディスプレイバッファが必要なのですが、CodeBuildなどのヘッドレス環境では存在しないため下記のようなエラーが出力されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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” を使用することで対処できます。
1 2 3 4 |
apt-get update apt-get install xvfb xvfb-run gitbook pdf |
3. 日本語が文字化けする
CodeBuildの環境には日本語フォントが含まれていないため文字化けしてしまいます。
下記のようにフォントをインストールすることで対処できます。
1 2 3 |
apt-get update apt-get install fonts-ipafont-gothic fonts-ipafont-mincho |
4. Apple iTunes interface プラグインの初期化エラー
Calibreのプラグインの初期化時にエラーが発生します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[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出来なくて発生しているようです。
別件ですが、同様のエラーが下記でも報告されています。
ImportError: cannot import name _thread #161
どうも、python-dateutilの2.6.0以降で発生するようですので、下記のように古いバージョンをインストールすることで回避できます。
1 2 3 |
pip uninstall -y python-dateutil pip install python-dateutil==2.5.3 |
buildspec.yml
上記の4つのエラーに対処すると、下記のようなbuildspec.ymlが出来上がります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
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の作成
Docker Imageを作成する方法はいくつかあるのですが、CodeBuildで使用する必要があるため、下記で公開されているCodeBuildの標準イメージのDockerfileを参考にするのが良いと思います。
https://github.com/aws/aws-codebuild-docker-images
Dockerfile
私の場合はnodejs:7.0.0環境をベースに下記のようなDockerfileを作成しました。
(&などがエスケープされています)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
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の設定
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分を短くすることができます。
buildspec.yml(3分28秒)
Docker Image(1分34秒)
install phaseに時間がかかっている場合は、Docker Imageを使用することを考えてみてください。