GitHub上にあがっているプロジェクトをgit clone
し、ローカルで展開するときに、接続先のDBがオンライン上で共有されている場合はデータの共有ができます。
一方で、DBをローカルサーバー(ローカルのコンテナ)として作成している場合は、元のコンテナのデータが入らず、空の状態となっています。
このような、ローカルのDBコンテナの中身を、他のDBコンテナに移動する方法について解説しています。
Dockerのボリュームを出力する
Dockerコンテナの中に入っているデータはDocker内のボリュームに保存されています。
対象のコンテナのボリュームを特定
まずは、対象のコンテナのボリュームを特定します。docker inspectコマンド を使うと、指定したコンテナの詳細情報を確認できます。
docker inspect <コンテナ>
コンテナの指定はコンテナIDとコンテナ名のどちらでも可能です。
実行結果は大量のデータが表示されます。ボリュームについて記述があるのはMounts というプロパティです。
実例
#コンテナ一覧の表示
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
8b9be3262d72 rails-base_aa-web "entrypoint.sh bash …" 17 hours ago Up 15 hours 0.0.0.0:3001->3000/tcp, :::3001->3000/tcp rails-aa-web
f730e12e64e4 postgres
#コンテナの情報を表示
$ docker inspect rails-aa-db
[
{
(省略)
"Mounts": [
{
"Type": "bind",
"Source": "C:\\Users\\documents\\projects\\rails\\rails-base\\tmp\\db",
"Destination": "/var/lib/postgresql/data",
"Mode": "rw",
"RW": true,
"Propagation": "rprivate"
}
],
(省略)
}
]
Sourceがホスト側(自分のPC)におけるデータが保存されている場所です。
なお、DestinationはDockerコンテナ内の保存場所になります。
ディレクトリをまとめてtarファイルを作成する
tarコマンドを使って、指定のディレクトリをまとめた tarファイルを作成します。
tar cvf <ファイルパス>.tar <ファイルパス>
上記の場合は、cvfオプションを指定しているので、無圧縮の丸め込み(tarファイル作成)です。
<ファイルパス>.tarでファイルパスを指定せず、ファイル名だけを記述した場合は、コマンドを実行したディレクトリに生成されます。
tarコマンドは、ファイルを丸めて.tarファイルを作成したり、ファイルを展開するコマンドです。
次の形が基本形です。
tar <オプション> <出力先ファイルパス> <元のファイルパス>
オプションに「-」は不要です。よく使うオプションは決まっています。
オプション | 内容 | 使用例 |
---|---|---|
cvf | tarファイルの作成(無圧縮) | tar cvf <出力先ファイルパス> <元のファイルパス> |
rvf | tarファイルにファイルを追加 (圧縮済みも同じ) | tar rvf <出力ファイルパス> <元のファイルパス> |
tvf | tarファイルの中のファイル名を表示(圧縮済みも同じ) | tar tvf <ファイルパス> |
xvf | tarファイルを展開(元のディレクトリ構造を保持) | tar xvf <ファイルパス> |
オプション | 内容 |
---|---|
c | tarファイルの作成 |
v | 処理内容を画面に表示 |
f | ファイル指定 |
r | 追加 |
x | 展開 |
t | 中身を表示 |
ちなみに、tarは、Tape Archival Format(テープ・アーカイバル・フォーマット)の略です。昔、磁気テープをアーカイブするために使われたため、この呼び名です。歴史ですね。
出力元ファイルは相対パスで指定する
tarで圧縮すると、ディレクトリ構造もそのまま圧縮します。このため絶対パスを指定して圧縮すると、展開先で、cディレクトリを作成し同じディレクトリ構造として出力します。
このため、プロジェクトのルートディレクトリに移動してから、対象ファイルパスを指定します。
$ tar cvf rails_db.tar tmp/db
バックスラッシュは使えない
docker inspect で表示されたSourceのパスをコピペして実行すると次のようなエラーが発生します。
Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
これは、バックスラッシュ(\)が読み込めないためです。通常のスラッシュに変更すればOKです。
結果 | 指定例 |
---|---|
NG | C:\Users\documents\projects\rails\rails-base\tmp\db |
OK | Users/documents/projects/rails/rails-base/tmp/db |
OK | ~/documents/projects/rails/rails-base/tmp/db |
チルダ「~」はホームディレクトリを指します。
実例
#プロジェクト直下に移動
cd rails-vue
#tarファイルの作成
$ tar cvf rails_db.tar tmp/db
tmp/db/
tmp/db/base/
(大幅に省略)
#ファイル存在の確認
$ ls | grep tar
rails-db.tar
tarファイルを展開する
tarファイルをgit clone
したプロジェクトのルートディレクトリ配下に配置し、展開する。
tar xvf <ファイルパス>
実例
#tarファイルを移動
$ mv rails_db.tar ../rails-base
#ディレクトリを移動
$ cd ../rails-base
#tarファイルを解凍
$ tar xvf rails_db.tar
tmp/db/
(省略)
プロジェクトの確認
コンテナのデータの移行が完了したので、実際にプロジェクトに反映されているか確認します。
tarファイルを展開する前にプロジェクトのURLにアクセスすると次の画面が表示されていました。(DBが存在しないというエラーです)

↓ tarファイル展開後
tarファイルを展開しリロードすると、DBの設定がコピーされるため、ページが正常に表示されます。

git clone先のコンテナに入ってDBの中身を確認してみます。
#起動中のコンテナに入る
$ docker exec -it rails-vue-web bash
#railsの対話モードを起動
root@a3d49a8a5adf:/rails-vue# rails c
Running via Spring preloader in process 48
Loading development environment (Rails 6.1.4)
irb(main):001:0>
#テーブル一覧を表示
irb(main):001:0> ActiveRecord::Base.connection.tables
=> ["schema_migrations", "ar_internal_metadata", "clients"]
#テーブルのデータを確認
irb(main):002:0> Client.all
Client Load (2.0ms) SELECT "clients".* FROM "clients" /* loading for inspect */ LIMIT $1 [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Client id: 1, created_at: "2021-07-24 03:19:48.321563000 +0000", updated_at: "2021-07-24 03:19:48.321563000 +0000", name: "test">]>
rails console でActiveRecord::Base.connection.tables
を実行すると、移管元のテーブルが移行できていることがわかります。
実際に、Client.all
でテーブルの中身を表示すると、中のデータも以降できています。
以上でDBの中身の移管は完了です。
なお、Railsコンソールからモデルを使ってDBのデータを確認する方法については、下記をご参考ください。
(参考)【Rails】コンソールからモデルを使ってテーブルの一覧表示やデータ追加・更新・変更・削除する方法(データベース操作)