Dockerのオーバーライドが開発DBを吹き飛ばしかけた話

先日、久しぶりに嫌な汗をかいた。

開発サーバーのDBが空になった。

幸いバックアップから復旧できたので大惨事にはならなかったが、確認や復旧作業でかなりの時間を持っていかれた。

原因を追っていくと、Docker Composeの設定変更だった。

発端はWindows対応

チームにはWindows利用者がいる。

Dockerを触っている人なら分かると思うが、WindowsとLinuxではボリュームマウント周りで微妙な違いが出ることがある。

今回もその対応だった。

Windows環境で動作するようにDocker Composeの設定が修正された。

変更した本人に悪意はない。

自分の環境を直したかっただけだ。なのでオーバーライドを利用した。

問題は、その変更がGitにコミットされ、そのままmainに入ったことだった。

Linuxは言われた通りに動いただけ

CI/CDがその設定を取得し、開発サーバーへデプロイした。

するとLinux上のDBコンテナが想定外のデータ領域を見るようになった。

結果として、データベースは新品の状態で起動した。

コンピュータは空気を読まない。

「この設定はWindows用だから怪しいな」

などとは考えてくれない。

設定された通りに実行するだけである。

そして人間だけが慌てる。

最初はオーバーライドの問題だと思った

最初は、

「個人用のオーバーライド設定をコミットしたのが悪い」

と思っていた。

確かにそれも一因ではある。

しかし落ち着いて考えると、本質は少し違った。

Docker Composeにはオーバーライドの仕組みがある。

個人用設定を別ファイルに分離するのは普通の運用だ。

ではなぜ事故が起きたのか。

本当の問題はCI/CDだった

振り返ると、CI/CD側がComposeファイルを固定していなかった。

もしCI/CDが

docker compose -f docker-compose.yml up -d

のように明示的にファイルを指定していたらどうなっただろう。

仮に誰かがオーバーライドファイルをコミットしても、CI/CD側では読み込まれない。

少なくとも今回と同じ事故は起きなかった可能性が高い。

つまり問題は、

「オーバーライドファイルが存在したこと」

ではなく、

「CI/CDがどの設定を使うのか明確に固定されていなかったこと」

だった。

開発環境だからこそ危ない

こういう話をすると、

「開発環境なんだから別にいいじゃないか」

と言う人もいる。

私も昔はそう思っていた。

だが実際に障害対応をやる側になると考えが変わる。

データを戻す。

動作確認をする。

関係者に説明する。

再発防止を考える。

誰も価値を生まない作業に何時間も使うことになる。

本番障害ほどではないが、十分に痛い。

教訓

今回の件で学んだことは単純だ。

ローカル開発では柔軟性が重要。

しかしCI/CDでは柔軟性は敵になる。

人によって設定が変わる余地を残してはいけない。

CI/CDで使うComposeファイルは明示的に固定する。

そして個人環境用の設定はそこから完全に切り離す。

たったそれだけの話なのだが、実際に事故が起きるまで気付かないことも多い。

システム障害というのは案外そんなものだ。

壮大な設計ミスや難解なバグではない。

「ちょっと設定を変えておきました」

その一言から始まることが多い。

そして障害対応が終わったあと、私はこう思ったのである。

「やっぱりWindowsの人たちと仕事するのは怖いな」

たぶん向こうも、

「Macの人たち面倒くさいな」

と思っているだろう。