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の人たち面倒くさいな」
と思っているだろう。