外部依存を排除: Dockerイメージのバックアップと環境移行方法

Dockerの魅力の一つは、docker-compose.ymlDockerfileをプロジェクトディレクトリに保存しておくことで、どこでも簡単にコンテナを構築できることです。特にGitHubにこれらのファイルを保存しておけば、デプロイ時にも本番環境でのコンテナ構築がスムーズに進むはず……と思いきや、この方法には隠れたリスクが潜んでいます。

以下のような外部的な要因により、予期せぬトラブルが生じる可能性があります。

  • パッケージの配信元が一時的・永続的に利用できなくなる
  • Dockerfileに記載したコマンドや設定が将来的に非推奨・廃止となる
  • デプロイ先のネットワークがプロキシにより制限される(特に社内ネットワーク)

例えば、php.iniの設定を変更するためにDockerfileを少し修正しただけなのに、コンテナの再構築が中途半端に止まってしまうなんて事態も考えられます。

これらのリスクを回避し、安定してコンテナを再構築するための方法として、イメージのバックアップが有効です。イメージをバックアップしておけば、外部通信の影響を受けずにコンテナを再構築できます。

結論

下記の方法でイメージバックアップとリストアが可能

#バックアップファイルの生成
docker commit バックアップしたいコンテナ名 バックアップ後のイメージ名
docker save -o /ホストOSのバックアップ先/バックアップファイル名.tar バックアップ後のイメージ名

##復元
docker load -i /ホストOSのバックアップ先/バックアップファイル名.tar

ただし下記はバックアップされない

  • アプリケーションのプロジェクトディレクトリ自体の実データ
  • データベースの中身

こいつらは別でバックアップをとってくれ。

あと、コンテナは1個あたり500MBぐらいの容量になったりするのでその点だけ注意。

バックアップファイルを別のマシンにコピーしてリストアするなんてこともできるぜ。

コンテナのイメージバックアップとは

イメージバックアップを理解するために、料理の例を考えてみましょう。

レストランのシェフが特別なレシピで絶品の料理を作りました。通常、このレシピを使えば同じ料理を再現できるはずです。しかし、材料の不足や品質の変動(例: パッケージ配信元の停止やライブラリの更新)で、料理の味が変わることがあります。

この際、事前に作った完璧な料理を冷凍保存しておくと、原材料が不足してもすぐに提供可能です。この「冷凍保存」がコンテナのイメージバックアップになります。外部の変動でレシピ通りに作れなくなったとき、このバックアップは頼りになる「保険」のような存在です。

バックアップするコンテナの確認

docker psコマンドで表示される現在稼働中のコンテナのnames欄を確認する。

yaju@MacBookPro976f11 crm % docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED              STATUS                        PORTS                                      NAMES
a82edbba510e   phpmyadmin/phpmyadmin   "/docker-entrypoint.…"   About a minute ago   Up About a minute             0.0.0.0:8081->80/tcp                       crm_phpmyadmin_1
c622d94dca3e   nginx:latest            "/docker-entrypoint.…"   About a minute ago   Up About a minute             0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   crm_web_1
961fd5d778a9   crm_app         "docker-php-entrypoi…"   About a minute ago   Up About a minute             9000/tcp                                   crm_app_1
5545b21b83b0   crm_db          "/entrypoint.sh mysq…"   About a minute ago   Up About a minute (healthy)   3306/tcp, 33060-33061/tcp                  crm_db_1

上記の例だと

  • crm_phpmyadmin_1
  • crm_web_1
  • crm_app_1
  • crm_db_1

がバックアップ対象に当たります。

バックアップファイルの生成

現在のコンテナの状態を記憶

docker commit crm-phpmyadmin_1 backup_crm-phpmyadmin
docker commit crm-web_1 backup_crm-web
docker commit crm-app_1 backup_crm-app
docker commit crm-db_1 backup_crm-db

ホストOSの任意の場所にコピー

docker save -o /Users/ユーザー名/Downloads/backup_crm-phpmyadmin.tar backup_crm-phpmyadmin
docker save -o /Users/ユーザー名/Downloads/backup_crm-web.tar backup_crm-web
docker save -o /Users/ユーザー名/Downloads/backup_crm-app.tar backup_crm-app
docker save -o /Users/ユーザー名/Downloads/backup_crm-db.tar backup_crm-db

dockerにより立ち上げられた仮想OSから、ホストOS(実機)の任意のフォルダにファイルを吐き出す。

上記はホストマシンがMacの例。ダウンロードフォルダにtarファイルを生成している。

復元

バックアップファイルをロード

docker load -i /Users/ユーザー名/Downloads/backup_crm-phpmyadmin.tar
docker load -i /Users/ユーザー名/Downloads/backup_crm-web.tar
docker load -i /Users/ユーザー名/Downloads/backup_crm-app.tar
docker load -i /Users/ユーザー名/Downloads/backup_crm-db.tar

それを元にコンテナを再構

docker-compose down
docker-compose up -d

ただし、docker-compose.yml内に記述ミスがあったりすると、このタイミングでそれが発覚してコンテナが立ち上がらないこともあるから注意adafs

気になったこと

SQLはバックアップされる?
→されない。別でバックアップを取る必要がある。

参考:
Docker環境におけるデータベースのバックアップとリストア方法 | 結論から答えるIT技術ブログ

別のマシンにリストアできる?
→できる。移行先のマシンがMacのDockerデスクトップだろうがUbuntuのDocker Engineだろうが、イメージファイルなので関係なくできる。

プロジェクトディレクトリは必要?
→これは必要。なかったらdocker-compose up -dできない。
docker-compose.ymlとそれに関連する必要なファイルたちがないといけないわけ。

無制限に質問可能なプログラミングスクール!

万が一転職できない場合は、転職保障全額返金できるコースもあり!!

無制限のメンター質問対応

 

DMMウェブキャンプでプログラミングを学習しませんか?

独学より成長スピードをブーストさせましょう!

 

まずは無料相談から!

おすすめの記事