開発が一旦完了し、保守やメンテナンスのフェーズに入ったアプリケーションの仕事をしていて、こんな事を思った。
「データベースのコンテナとホスト間に共有フォルダを設定しておいた方がよいのではないだろうか」
例えば、こんな感じ。
docker-compose.yml
mysql:
image: mysql:8.0.29
container_name: mysql
environment:
MYSQL_DATABASE: myapp01
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: password
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
- ./shared_db:/shared_db # DBコンテナとホストとの間に、共有ディレクトリを設定
理由としては、サービスが稼働した後、本番環境のデータをローカル環境に落として実験しやすいようにするため。
例えば、本番稼働後にエラー報告があって調査するも、ローカル環境では再現できず、その内容が特定の条件が揃った時にしか発生しない可能性が高い場合、本番環境と同内容のデータを用意して実験したい場合も多いと思う。
そんな時、本番環境のデータをエクスポートするなり、定期エクスポートしているファイルをローカルにインポートする事になる。
が、このインポート作業は意外と面倒な事になるケースがある。
最近は、開発にて使用するマシンを指定せず、Mac・Windows・Linux 等、個人の好きなOSを使ってもらう事も多いと思う。
何より、Docker を筆頭とした仮想化技術が、それを容易に実現できている。
この場合、インポートコマンドをコンテナ内部(MySQL や PostgresSQL のコンテナ)で実行する時、インポート対象ファイルをコンテナ内部から参照できる場所に保存しておく必要がある。
(もしかしたらホスト側のファイルを指定する方法があるかもしれないけど、見つけることができませんでした)
その場合、ホストとコンテナの間にファイル交換プロトコルを用意したり、双方で参照できるストレージを仲介してファイルを受け渡したりする方法が考えられるが、正直面倒くさい。
他には、インポートコマンドをホスト側から実行する方法があるが、この場合はホスト側のシェルの都合に振り回される事になる。
特に PowerShell はクセが強く、MySQL のインポートコマンド実行に必要な「<
」の文字が予約語のために使用不可のため迂回路を探すハメになったりと、何かと余計な調査を強いられる。
(ちなみにその問題を解決しても、ファイルはコンテナ内部から参照できる場所に保持しておく必要があったりと、結局無駄に時間を溶かしただけだった。)
他に考えられる方法としては、MySQL Workbench などのアプリケーションを使用するという方法だが、OSごとに使えるアプリケーションに違いがあるし、同じアプリケーションでも操作方法やできる事に差があったりと、チーム内で共有する情報としては、ちょっと重たい内容となる。
というか、せっかくホストの環境を無視できる Dockerという仮想化技術を使っているのに、ホストの OS ごとに異なる操作方法が必要になってしまうというのはいかがなものか。その点でも、OSごとに個別の方法を用意するのが適切とは思えない。
ちなみにインポートが成功する状態まで持って行ったとしても、今度は文字コードによるエラーに悩まされたりと、何かと障害が多い。
ちなみに、この辺の調査内容をまとめたエントリがこちらです。
【MySQL・Windows・Docker】MySQLコンテナに dumpファイルをインポートする方法
これらの問題を綺麗に解決してくれる方法が、冒頭で紹介した
「データベースのコンテナとホスト間に共有フォルダを設定しておく」
という方法。
こうしておく事で、dumpファイルをローカル環境にインポートしたい場合、
「DBコンテナとホスト間の共有フォルダにファイルを置いて、コンテナ内部からインポートコマンドを実行してね」
これだけの説明で完結する。
シェルの違いにも、ホストOSの都合にも一切引っ張られる事がない、最適な解決方法だと思うのだが、どうだろう。
何より docker-compose.yml をいくら編集しようとも、影響があるのはローカルの開発環境のみで、本番環境やステージング環境には一切悪影響を及ぼさずに解決できる。
ただ、こんな事を主張している人は見た事がないし(自分の観測範囲)、仮に docker-compose.yml に上記のような設定を入れると、「これはなんのための設定なの?」と突っ込まれる事必死なので、その有益性とその設定を入れない場合の課題を説明したいと思ってブログにておく事にした。
コメント