Google Cloud Shell で F# スクリプトを書きたかった。Google Cloud Shellには .NET Core SDK がインストールされているのでdotnet fsi
コマンドで F# の REPL が使える。
nuget パッケージを使うときに Paket があると便利だが、Paket の実行には mono が必要。mono は apt でインストールができる。
Cloud Shell のインスタンスに毎回インストールしてもいいが時間がかかるので、Cloud Shell のカスタム環境として用意することにした。
カスタム環境は Google Container Registory に置いた Docker イメージを Cloud Shell として利用する。Google によって提供される Docker イメージをベースにする必要がある。提供されるベースイメージは debian 9 (strech)。
カスタム環境用の Docker イメージをビルドする Dockerfile を書いた。 mono のパッケージリポジトリと鍵を追加して、apt install で mono-runtime と必要なライブラリをインストールする。
FROM gcr.io/cloudshell-images/cloudshell:latest RUN apt-get update \ && apt-get install -y --no-install-recommends gnupg dirmngr \ && export GNUPGHOME="$(mktemp -d)" \ && gpg --batch --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \ && gpg --batch --export --armor 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF > /etc/apt/trusted.gpg.d/mono.gpg.asc \ && gpgconf --kill all \ && rm -rf "$GNUPGHOME" \ && APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn apt-key list | grep Xamarin \ && apt-get purge -y --auto-remove gnupg dirmngr \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* RUN echo "deb http://download.mono-project.com/repo/debian stable-stretch main" > /etc/apt/sources.list.d/mono-official-stable.list \ && apt-get update \ && apt-get install -y \ mono-runtime \ libmono-system-data4.0-cil \ libmono-system-io-compression-filesystem4.0-cil \ libmono-system-net-http4.0-cil \ libmono-system-runtime-serialization4.0-cil \ libmono-system-xml-linq4.0-cil \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/*
Paketを実行するためのライブラリ
Paket.exe を実行するには mono-runtime だけでは足りない。mono-complete パッケージであれば十分だけど使わないライブラリもインストールされる。mono-runtime で Paket を実行してみてエラー表示から足りないdllを確認した。以下はとりあえずパッケージダウンロードを試してエラーになったものだけ。これらのライブラリがあれば nuget からライブラリのダウンロードはできるようになる。
- System.Data.dll
- System.IO.Compression.FileSystem.dll
- System.Net.Http.dll
- System.Runtime.Serialization.dll
- System.Xml.Linq.dll
必要になったmonoプロジェクトの情報
- 鍵IDとパッケージリポジトリURL
- https://www.mono-project.com/download/stable/#download-lin-debian
- パッケージリポジトリの追加のしかた
- https://github.com/mono/docker/blob/1d31220a290b2b4d19654a8cdb4ba13888e29717/6.4.0.198/slim/Dockerfile
- dllとパッケージ名の対応
- https://github.com/mono/linux-packaging-mono/blob/master/debian/control
Dockerfileのベストプラクティ
apt update, install, clean を同じ RUN で実行する。
RUN apt-get update \ && apt-get install ... \ ... && apt-get clean \ && rm -rf /var/lib/apt/lists/*