Tangible

例えば今年「某電子書籍のサービスが終了してそれまで購入していたマンガや書籍にアクセスできなくなってしまった」という話を聞いたことはあるだろうか。
あるいは「Steamは実際にゲームを購入する権利を与えられているだけであって、実際にゲームそのものを購入しているわけではない」という話。
ところが本やゲームなら光学ディスク、ないしカセットはその内容が媒体に保存されている。
これがプログラムだとどうだろうか。
私はこれまでGitHubやセルフホスティングのGitLab、Giteaなどあわせて300個以上のリポジトリを保存している。未整理のハードディスクのものを含めたらさらにその数は測りきれないだろう。
ただしこれらのプログラムは当然本やカセットのような媒体ではなく、いうなればテキストファイルや画像ファイルなどのバイナリの寄せ集めに過ぎない。
そしてさらには別のプログラムとの組み合わせであったり、あくまでプログラムというのはプログラム同士のレイヤーに過ぎない。1
私はこれまでブログを通じて様々な記録を残してきた。
これはよい。なにせ単純なHTMLというフォーマットであればブラウザを通じていつでも閲覧することができる。
もちろん私がアップロードしたWebサーバーが生きていればの話ではあるが、少なくともそのサーバーを経由してHTMLドキュメントを配布することができる。
Goは簡単である。ただビルドすればよい。
まだGoを使って大規模なプログラムを書いた経験はないのだが、プログラムの本体とそれに必要なファイルをまとめていれば簡単にバックアップすることができる。
しかし厄介なのはRailsなどで構築されたアプリケーション郡だ。
Rubyそのものは非常に美しく整っており、まさしくRubyという言語の名の通り洗練されたプログラム言語だと思う。
しかしその表の姿に比べて、裏側は果てしなく深い闇を落としている。このトレードオフはRubyという言語を知るものであれば誰しも共感できるものであろう。
例えばRubyひとつとってもマイナー、パッチ番号含めてほぼ同じRubyであっても実行するには完全に一致したバイナリが必要である。
そしてRailsを始めとしたライブラリも必要である。これらはrubygemsを通じて取得できる。最近は減ってはきたけれどもC/C++拡張のコンパイルをする必要がある。
そしてようやく動かせるようになったと思ったら今度はデータベース、外部サーバーなどの接続も確立しないといけない。

なにが言いたいのかというと、その当時に作ることは簡単でも、あとからそれを復元するのはそれ以上に困難である。
私はこれまでバックアップ作業として、Gitリポジトリという形式にして詰め込んでしまっておけばあとからそれを復元できると考えていた。
- しかし実際にそれをいざやろうという時間は確保できるだろうか?
- 当時は発生しなかった、あるいは今はもう見なくなったエラーを再び修正できるだろうか?
- その時存在していたサービスやパッケージ、あるいはライブラリが現在も取得できるだろうか?
- そしてかつて自分が何らかの理由で諦めたコードと再度向き合う勇気はあるだろうか?
これらの現実がワッと振り重なってくる。
そうなってくると、これまで積み重ねてきたコードのバックアップは資産どころか負債にすら思えてくるかもしれない。
――もし当時の自分に対してアドバイスを送ることが許されるのであれば、真にバックアップすべきなのはDockerイメージとのペアだったと言いたい。
これはWebサービスにおける本やカセットのようなものだ。
そしてもし私はDockerというものの移植再現性以外を理解していなかったためにこの悲劇を生んでしまった。
Dockerのもうひとつ重要な側面はWebサービスをコンテナという形に変換すれば、Railsのようなセットアップが煩雑なアプリケーションもひとつにまとめることができる。
もちろんイメージだけではその中身まで知ることは難しいので、コードのバックアップはやはり残しておくべきだ。
しかし一番重要なのはコンテナの方だったのだと思う。
もちろんコンテナを保持し続けるのはテキスト形式ほど簡単ではないし、Gitリポジトリに比べて慎重にならざるを得ない。
それでもこの仕組みを実現するためにHDDを購入するのはなんら問題ない出費だったと今なら思える。
後悔は先に立たないが、少なくとも今年はもう少ない。
現時点ですぐにこの方法は確立しきれていないが、今後はコンテナごと保存する方法について模索していこうと思う。
Updated: 翌日へ続く
-
抽象化レイヤー、アプリケーション層、OSI参照などの単語を思い出しただろうか ↩