2015/04/01

昔のTeX環境をDockerのコンテナ化する

大きく進化した日本語TeX環境

新しいLinuxマシンで、とりあえず日本語TeXを使えるようにするまでの時間は、ここ数年で信じられないほど短くなりました。それもこれも、TeX Liveが2010で日本語に完全対応してくれたおかげです。

いまのように「TeX Liveをインストールするだけ」となる以前、Linuxで日本語TeX環境を整備するのは、ほとんど腫物に障るようなものでした。 ディストリビューションの各種パッケージから必要なものを適切な順番にインストール、フォントの実体ファイルへのシンボリックリンクをTEXMF以下に作成、mktexlsrを実行、otfパッケージを手動でインストール、mktexlsrを実行、dvipdfmxの設定ファイル群を編集、mktexlsrを実行。 なんとかインストールを終えてplatexを実行し、dvipdfmxにかけると、なぜかPDFのしおりが文字化けしてしまい、よくよく調べてみると上流で日本語EUC用のCMapファイルが勝手に消されている! あのころのdvipdfmxはいろいろとひどかったのですが、日本語でPDFを作るときの現実的な選択肢がほかにはなかったのです。

ところが2000年代後半になると、日本語TeX環境が思い出したように進化を再開します。具体的には、e拡張やUTF-8に対応したエンジンが登場してきました。 dvipdfmの亜種のような扱いを受けながら鬼子となっていたdvipdfmxも、XeTeXで見直されたおかげか、まっとうなDVIウェアとして主要パッケージでネイティブ対応されるようになりました。 おかげで不可解なバッドノウハウの数々がずいぶん不必要になったはずです。

過去の環境で作ったドキュメントが負債に

しかし前述したように、いったんうまく動くようになった日本語TeX環境に手を入れるのは、とくに業務で使っているとなかなか勇気がいることでした。 必然的に、更新をさぼります。その結果、古い環境で作られたドキュメントがどんどんたまっていきます。 さすがに、e拡張なしではtikzが満足に使えなかったり、UTF-8でない原稿をバージョン管理するのはつらかったりで、いまでは現代的な日本語TeX環境に移行したのですが、そうなると今度は過去のドキュメントが負債としてのしかかってきます。 過去のTeX環境で作ったドキュメントを当時と同じ見た目に再現しなければいけない場合、どうしても当時のマシン環境が必要です。 過去の環境を仮想マシンとしてそのまま残して凌いできたものの、ディスクイメージだけで100G近くあるので、管理コストがバカになりません。 作業としても、ドキュメントを編集するだけなのにOSをまるごとブートするというのは、どう考えても面倒くさい。

過去の環境をDockerコンテナ化

そこで、過去のマシンと同じ環境をDockerのコンテナとして作成することにしました。 古いドキュメントの編集が必要なときには、この古い日本語TeX環境を閉じ込めたコンテナ内でPDFを作るようにすればよかろう、というわけです。

いろいろなドキュメントに応じて必要となるパッケージはDockerfileを使ってそのつどインストールすることにすれば、コンテナ自体は最小の構成にしておけます。 コンテナ化したいのはあくまでもTeX環境だけなので、仮想マシンと違って実体フォントをインストールする必要がないっていうのも利点です。

Debian Lennyをベースとした日本語TeX環境コンテナ化の手順

Dockerのマニュアルによれば、ルートファイルシステムのtarアーカイブに対して docker import を実行すれば、コンテナ(の基になるイメージ)が生成できるとのことです。

自分が必要とする Debian Lenny のルートファイルシステムを、ふつうのディレクトリ(以下の例では ./lenny4debootstrap/)に取ってくるには、以下のように debootstrap コマンドを使います。ちなみに、この作業をしているのは jessie/sid 上です。

$ sudo debootstrap lenny ./lenny4debootstrap http://archive.debian.org/debian/

取ってきたルートファイルシステムを tar で固めて、docker import します。

$ sudo tar -C lenny4debootstrap -c . | sudo docker import - lenny

これで、lennyという名前のDockerイメージができました。 このイメージを docker run すれば、Dockerコンテナができて、その中で好きなことができます。 とりあえず、お約束のバージョン確認。

$ sudo docker run lenny cat /etc/debian_version
5.0.10

上記の cat /etc/debian_version の部分に /bin/bash とかを指定すれば、コンテナ内で好きなシェルが立ち上がります。 しかし仮想コンソールがない状態で起動してしまうので、これだけだとコンテナ内で起動してるシェルからコマンドを入力できません。 仮想コンソールを有効にするには、docker run-t オプションを付けます。

さらに、これだけではコンテナ内で実行したコマンドの結果が標準入力にリダイレクトされず、コンテナ内のシェルから対話的なことが何もできません。 これを有効にするためには -i オプションが必要です。

というわけで、コンテナ内でシェルを実行してコマンドを実行するには、こんなふうにします。

$ sudo docker run -i -t lenny /bin/bash
e606e97b3187:/# ls
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var
e606e97b3187:/# exit
$ 

コンテナ内のシェルのプロンプト e606e97b3187:/# に表示されている12桁の16進数は、コンテナのIDです。 以下のコマンドで最近実行したコンテナのIDが表示できますが、確かに上記と同じ文字列になっているのが分かります。

$ sudo docker ps -l
ONTAINER ID   IMAGE  COMMAND      CREATED        STATUS        PORTS  NAMES
e606e97b3187  lenny  "/bin/bash"  2 minutes ago  Up 2 minutes         romantic_poincare

さて、これでコンテナ内のシェルから apt-get install ptex-base とかできれば話は簡単なんですが、archive.debian.org から取ってきた Lenny のルートファイルシステムには apt が入っていません。 /etc/apt/source.listこそありますが、無効なアドレスが入っています。 そこで、まずは apt が使えるようにがんばってください。 たぶん以下を個別にDebianのアーカイブから取ってきて、dpkg -i で入れればよいはずです。

apt_0.7.20.2+lenny2_i386.deb
coreutils_6.10-6_i386.deb
debian-archive-keyring_2010.08.28~lenny1_all.deb
gcc-4.3-base_4.3.2-1.1_i386.deb
gnupg_1.4.9-3+lenny1_i386.deb
gpgv_1.4.9-3+lenny1_i386.deb
libacl1_2.2.47-2_i386.deb
libattr1_2.4.43-2_i386.deb
libbz2-1.0_1.0.5-1+lenny1_i386.deb
libc-bin_2.11.3-4_i386.deb
libc6_2.11.3-4_i386.deb
libc6_2.7-18lenny7_i386.deb
libgcc1_4.3.2-1.1_i386.deb
liblocale-gettext-perl_1.05-4_i386.deb
libncurses5_5.7+20081213-1_i386.deb
libreadline5_5.2-3.1_i386.deb
libselinux1_2.0.65-5_i386.deb
libstdc++6_4.3.2-1.1_i386.deb
libusb-0.1-4_0.1.12-13_i386.deb
lzma_4.43-14_i386.deb
readline-common_5.2-3.1_all.deb
zlib1g_1.2.3.3.dfsg-12_i386.deb

もちろんコンテナ内には wget もないので、ホストOSで取ってきた .deb をルートファイルシステムに配置して docker import するか、以下のようにdocker run-v オプションを付けて .deb のあるディレクトリをマウントします。

$ sudo docker run -t -i -v /home/k16/temp/debs:/root/temp lenny /bin/bash
1be08b199276:/# cd root/temp
1be08b199276:/# dpkg -i ...

source.listはこれ。

1be08b199276:/# cat /etc/apt/sources.list
deb http://archive.debian.org/debian/ lenny main contrib non-free

無事に apt が入ったら、必要な日本語TeX環境を入れましょう。 当時の情報としては、このへんのリンクが参考になると思います。