Docker を使えば,普段使いの TeX Live 環境とは別に古い TeX 環境を保管しておいたり,あるいは逆に先端の開発中ブランチを試しに導入できたりと,色々便利です。
というわけで今回は,TeX Live 2019 + 原ノ味フォント + llmk でコンパイルできる Docker コンテナを作ってみました。
目標
- モダンな TeX Live 環境を一発で用意できる Docker のコンテナイメージを作りたい。
- pdfLaTeX / LuaLaTeX / XeLaTeX / (u)pLaTeX, dvips / dvipdfmx の全てを使えるようにする。
- Adobe の源ノ明朝/源ノ角ゴシックを Adobe-Japan1 準拠に組み直して作られた高品質なオープンソース和文フォントである原ノ味フォントを,和文標準フォントとして使えるように準備・設定しておく。
【参考】 - ビルドシステムとしては latexmk に代わる新世代ビルドシステム llmk を標準で使えるようにし,デフォルトとする。
【参考】
とりあえず完成品を使うには
イメージの pull
完成したイメージは Docker Hub に doratex/texlive2019ja-haranoaji としてアップロードしてあるので,
$ docker pull doratex/texlive2019ja-haranoaji
とすれば pull できます。(TeX Live 2019 がフルに入っているのでサイズが大きいです🙇)
使い方
コンテナ内では /workdir
が作業ディレクトリとなるので,それをカレントディレクトリと bind マウントして使うのを想定しています。
alias dockertl="docker run --rm \
--mount type=bind,src=\"\$(pwd)\",dst=/workdir \
--mount type=volume,src=ltcache,dst=/usr/local/texlive/2019/texmf-var/luatex-cache \
doratex/texlive2019ja-haranoaji"
などとエイリアスを設定しておくと楽でしょう。(--mount type=volume,...
の部分は,LuaTeX のフォントキャッシュを ltcache
というボリューム(名前は任意です)に保存し永続化させるための設定です。詳細は後述。)このエイリアスが設定されている下で
$ dockertl
とすれば,デフォルトで llmk が起動し,カレントディレクトリの llmk.toml
に基づきビルドしようとします。
$ dockertl llmk hoge.tex
のようにして特定のファイルをターゲットにすることもできます。従来の latexmk もインストールされているので
$ dockertl latexmk hoge.tex
も使えます。
またもちろん,llmk や latexmk のようなビルドシステムを用いずに,
$ dockertl lualatex fuga.tex
$ dockertl ptex2pdf -l piyo.tex
などと普通にコンパイルすることも可能です。pLaTeX
+ dvips
+ ps2pdf
のワークフローを使う場合は,
$ dockertl /bin/bash -c 'platex hoge.tex && dvips hoge.dvi && ps2pdf hoge.ps'
とすれば OK です。
(u)pLaTeX + dvips/dvipdfmx においては,デフォルトで原ノ味フォントを埋め込む設定になっています。
テスト用サンプルコード
GitHub レポジトリにテスト用サンプルコード群を置いてあります。
- (u)pLaTeX + dvips
- (u)pLaTeX + dvipdfmx
- LuaLaTeX
- XeLaTeX
のそれぞれについて,原ノ味フォントが埋め込まれるサンプルコードとなっています。test_all.sh
を起動すれば llmk による各テストファイルのビルドが走ります。また,docker-compose
を用いるサンプルも入れてあります。
Dockerfile の作り方
以下,この Docker イメージのビルドに用いる Dockerfile の作り方を述べます。
参考文献
@yyu さんがLaTeXで年賀状を作る際に製作された Dockerfile を大いに参考にさせていただきました。
迷ったこと
Alpine ベースか Ubuntu ベースか?
イメージのサイズ削減のためには,Alpine ベースでいきたいところです。が,実際にやってみたところ,大半はうまくいったのですが,XeTeX に動的リンクされる fontconfig が(apk add fontconfig-dev
してあっても)うまく呼び出せず,XeTeX を起動することができませんでした。
割り切って「XeTeX は諦めて Alpine ベースにする」という手も考えられます。実際にイメージを作って比較してみたところ,
- Ubuntu ベース(XeTeX 使用可):3.63 GB
- Alpine ベース(XeTeX 使用不可):3.52 GB
となりました。TeX Live の scheme-full の容量が圧倒的で,もはや Ubuntu と Alpine のサイズの違いは誤差みたいなものとなっていました。それなら XeTeX が使えた方がいいだろうと考え,今回は Ubuntu ベースでイメージ構築することにしました。
TeX Live は scheme-full でいくか scheme-basic + collection-langjapanese でいくか?
イメージのサイズ削減のためには scheme-basic
+ collection-langjapanese
の方がよいでしょう。が,LuaLaTeX / XeLaTeX / (u)pLaTeX で一通りの組版をできるようにするためにどのパッケージを追加すべきかを考えるのが面倒だし,「モダンな TeX Live 環境が丸ごと整う」ことが目標なので,今回はサイズは気にせずに scheme-full
でいっちゃうことにしました。(ただしサイズ削減のために option_doc
と option_src
は外す。)
原ノ味フォントへの対応方法
LuaLaTeX
TeX Live 2019 の最新レポジトリでは,luatexja-preset パッケージが haranoaji
プリセットに対応しているのでそのままで大丈夫です。
(u)pLaTeX, dvips, dvipdfmx
pxchfon パッケージ
TeX Live 2019 の最新レポジトリで haranoaji
プリセットに対応済みです。
ptex-fontmaps
TeX Live 2019 の最新レポジトリで haranoaji
プリセットに対応済みです。
cjk-gs-integrate
TeX Live 2019 の最新レポジトリで原ノ味フォントがデータベースに登録済みです。
XeLaTeX
TeX Live 2019 の最新レポジトリで haranoaji
プリセットに対応済みです。
Dockerfile でやること
Dockerfile によるイメージのビルドにおいては,大まかに次のことを行います。
- TeX Live 2019 の最新版をネットワークインストール。
-
原ノ味フォントを GitHub レポジトリから取得して(→ TeX Live に収録されたので不要になりました。)TEXMFLOCAL
内にインストール。 -
原ノ味フォントに対応した最新版(→ TeX Live に反映されたので不要になりました。)ptex-fontmaps
を GitHub レポジトリから取得してTEXMFDIST
内に配置。 -
原ノ味フォントに対応した最新版(→ TeX Live に反映されたので不要になりました。)cjk-gs-integrate
を GitHub レポジトリから取得してTEXMFDIST
内に配置。 -
原ノ味フォントに対応した最新版の(→ TeX Live に反映されたので不要になりました。)zxjafont
を GitHub レポジトリから取得してTEXMFDIST
内に配置。 mktexlsr
して原ノ味フォントを TeX システムに認識させる。-
cjk-gs-integrate
を走らせて Ghostscript の原ノ味フォント対応。 -
kanji-config-updmap-sys
で (u)pLaTeX の既定の和文フォントを原ノ味フォントにする。 - 最新版の llmk を GitHub レポジトリから取得して
/usr/local/bin
に配置。
課題の解決
XeTeX に TEXMF ツリー内のフォントを認識させる(現在では必須ではない)
(ここは原ノ味フォントを別途インストールしていた時代の記述で,現在では必須ではなくなりました。)
Linux の場合,XeTeX は fontconfig を利用してフォントを見つけていますが,上記手順では原ノ味フォントをTEXMFLOCAL
内に配置しましたので,fontconfig がそれを見つけられません。そこで,次のような内容を記載した XML ファイルを /etc/fonts/local.conf
として保存しておきます。こうすることで TEXMFDIST
,TEXMFLOCAL
内のフォントを XeTeX が見つけられるようになります。
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/usr/local/texlive/texmf-dist/fonts/opentype</dir>
<dir>/usr/local/texlive/texmf-dist/fonts/truetype</dir>
<dir>/usr/local/texlive/texmf-local/fonts/opentype</dir>
<dir>/usr/local/texlive/texmf-local/fonts/truetype</dir>
</fontconfig>
その上で fc-cache -r
することで fontconfig のキャッシュを更新しておきます。
参考: fontspec が呼び出すフォント検索エンジン
エンジン | Windows | Mac | Linux/UNIX |
---|---|---|---|
XeTeX | fontconfig | AAT | fontconfig |
LuaTeX | luaotfload | luaotfload | luaotfload |
⬆ Mac 上の TeXLive の luaotfload で「クレー」などのフォントを使えるようにする - ルギア君の戯言より。
LuaTeX の初回フォントキャッシュ作成が遅い問題
LuaTeX の使用においては,フォントを初使用したときのコンパイルが遅いという点が問題となります。
luaotfload-tool -u -f
しておくことで,TEXMFLOCAL/texmf-var/luatex-cache/generic[-dev]/names
内のフォントのデータベースは事前に作成しておくできます。ただし,それとは別に,フォントの初使用時に TEXMFLOCAL/texmf-var/luat ex-cache/generic[-dev]/fonts/otl
にフォントキャッシュが作成されるため,各フォントの初回使用時のコンパイルが遅くなります。2回目からは速くなりますが,Docker イメージからのコンテナ生成ではこれが問題になります。イメージから毎回使い捨てのコンテナを生成して使う場合,毎回が「初回起動」になるため,起動のたびに毎回フォントキャッシュ作成が入って無用に時間がかかってしまいます。
これを防ぐ方法の一案としては,次のようにして「Docker イメージ作成時に全てのフォントを1回ずつ使って全フォントのキャッシュを作成しておく」方法があります。
for x in $(luaotfload-tool --list=* --fields=fullpath); do \
/bin/echo "\\relax\\input luaotfload.sty \\font\\x[$x]\\bye" | luatex > /dev/null; \
done
しかし,このようにしてキャッシュを事前に全作成をすると,Docker イメージのサイズが 1GB 以上も増えてしまいます。そこで,キャッシュが保存されるコンテナ内のディレクトリ TEXMFLOCAL/texmf-var/luatex-cache
を,Docker コンテナ起動時に名前付きボリュームとしてマウントし,ホスト内に保存することで永続化させましょう。先ほどのエイリアスにはその設定を仕込んであります。
完成品
こうしてできあがった Dockerfile がこちらです。
イメージのビルド
$ docker build --no-cache=true -t doratex/texlive2019ja-haranoaji .