1時に寝て明け方に起きて7時に起きた。あまり眠れてない雰囲気がある。

docker/compose の運用

いま作っているアプリケーションは docker compose で構成している。マージ単位で gitlab ci/cd から docker image をビルドしていて、テスト環境のデプロイスクリプトで最新の docker image を取得してコンテナを再作成するようにしている。デプロイスクリプトは docker cli と docker compose cli の2つを組み合わせてシェルスクリプトで実装しているが、複数のアプリケーションやミドルウェアがあるのでそれらを統合的に扱うことはできないし、さまざまな状況を想定して動くようにもなっていない。がんばれば doccker/compose cli と jq とシェルスクリプトで細かい要件を実装することもできるけど、それをお客さんの本番環境においても使うには一定の cli 操作に慣れが必要な上、docker/compose の知識やスキルも要求してしまう。少なくとも頻繁にある運用作業として docker image の更新やコンテナの再作成が想定される。ローリングアップデートまでは実装しないけど、アプリケーションの要件にあわせた docker image の更新とコンテナの再作成 (アプリケーションの再起動) ぐらいはまとめてやってしまってよいと思う。

github.com/docker/docker は github.com/moby/moby にリダイレクトされる。docker は開発ツール、moby はインフラやライブラリという住み分けでそれぞれに関心のあることに注力するようにモジュール構成を分離している。それが2019年に行われていまもおそらくまだ途上だと思う。あと docker のモジュール群は go modules に対応していない。大きなプロジェクトが移行するのが大変なのは理解できるけれど、依存解決のような複雑なところを放置するのはまったく賛成できない。そこが不健全だと依存ライブラリの整理やモジュール分割がうまく進まない気がする。docker の client は https://github.com/moby/moby/tree/master/client に定義されていて、readme のサンプルコードにあるようにすぐに使えるようになっている。一方で compose の spec は github.com/compose-spec/compose-go で定義されていて、github.com/docker/compose はまだライブラリとして使いやすいようにはなっていない。仕様と実装が混在していて動いている状態。そういう issue もあげられている。

testcontainers-go というアプリケーションが compose をライブラリとして使う実装をしている。このコードをみれば compose をどう使えばよいのかはわかる。

自分で compose を実装してもよいけれど、compose の service を扱うための project やオプションの設定が煩雑なことも伺える。仕様と実装が混在しているというのはそこら変の整理ができていないようにみえるからだ。testcontainers-go も自前の client を用意して使いやすいようにしているのでそれを再利用した方が運用ツールを作るのは簡単になる。testcontainers-go の compose client 経由で compose の up/down を制御する。その他のコンテナの操作は docker client を直接使って実装する。この組み合わせで自分たちのアプリケーション向けの運用ツールを作ろうと思う。