山麓エンジニアからの備忘録

クラウド・ETL/ELT・Nocode・BigQuery などを中心に書ければね。最近触ったサービス・フレームワークなどのメモ

Docker ボリュームマウントしたときのバックアップ方法

前回はボリュームマウントを試してみたので、今回はそのマウントしたボリュームをバックアップする方法についてやってみます。

ボリュームのバックアップ方法

バインドマウントと違ってボリュームの場合は、対象のパスをそのまま tar などで固めてもバックアップファイルとしては有効ではないようです。
というのも、Docker Engine からバックアップを実行しているので、Docker Engineとしてのシステム領域をバックアップするということになり、対象のコンテナにリストアできないかもしれないのです。

バックアップ方法ですが、適当なLinux系のコンテナを起動して、そこに対して対象コンテナをマウントしてバックアップする形となります。

まずは対象コンテナが停止していることを確認します。

[ec2-user@~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
a6a1c6b8eb7a        mysql:5.7           "docker-entrypoint.s…"   7 minutes ago       Exited (0) 20 seconds ago                       mysqldb
[ec2-user@~]$

Linux のコンテナをここで起動します。バックアップとしてしか使用しないので、 busybox という軽量 Linux を使用します。

[ec2-user@~]$ docker run --rm -v samplevol:/src -v "$PWD":/dest busybox tar czvf /dest/backup.tar.gz -C /src .
~
[ec2-user@~]$ ll
total 7036
-rw-r--r-- 1 root root 7202585 Jan 13 21:46 backup.tar.gz
drwxr-xr-x 2 root root      24 Jan  9 21:49 bindData
[ec2-user@~]$

backup.tar.gz がカレントディレクトリに作成されているのが確認できました。

ちなみにそれぞれのオプションの意味ですが、

  • rm :コマンド実行後、コンテナを削除します
  • samplevol:/src :samplevol ボリュームを /src にマウントする
  • "$PWD":/dest busybox : Docker ホストのカレントディレクトリを /dest にバインドマウントする
  • tar czvf /dest/backup.tar.gz -C /src . : /src 以下を /dest/backup.tar.gz にバックアップする(/dest はカレントディレクトリにマウントしてる)

リストアしてみる

まずはボリュームを使用しているコンテナとボリュームを削除してみます。

[ec2-user@~]$ docker rm mysqldb
mysqldb
[ec2-user@~]$ docker volume rm samplevol
samplevol
[ec2-user@~]$

次にボリュームを作成します。

[ec2-user@~]$ docker volume create samplevol
samplevol

ここで、先ほどバックアップしたファイルを使ってリストアしてみます。

[ec2-user@~]$ docker run --rm -v samplevol:/dest -v "$PWD":/src busybox tar xzf /src/backup.tar.gz -C /dest
[ec2-user@~]$

/dest にボリュームマウント、/src にバインドマウントとし、カレントディレクトリにある backup.tar.gz が /src/backup.tar.gz として扱うことができます。
/dest はリストア先のボリュームにマウントしているので、/dest に展開されていきます。

これでボリュームをリストアしたので、MySQLコンテナを起動してみます。

[ec2-user@~]$ docker run --name mysqldb -dit -p 3306:3306 -v samplevol:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pwsswd mysql:5.7
9aa13f0f109e531714cd22c241dbffbdcf2d23e349b20d316df3a152aa4069c6
[ec2-user@~]$

MySQL WorkBench で接続してみると、前に作成したテーブルが新しいコンテナでも見れるようになっていることを確認できました。
f:id:sennanvolar44:20210120063039p:plain

Docker ボリュームマウントしてDBデータを永続化してみる

今回は MySQL コンテナでボリュームマウントについて試してみます。ちなみに、前回はバインドマウントをやってみました。

miyamon44.hatenablog.jp

ボリュームマウントとは

Docker ホストで確保した領域を利用することで、前回試したバインドマウントはDocker ホストとは関係なしにホスト上のディレクトリをマウントする方法でした。

ボリュームマウントを使うメリットは、Docker で管理するので特にパスなどを考える必要がないということです。
自分のようにすぐにパスを忘れてしまうようなら、ボリュームマウントの方が必須かもですね。というより、どちらも利用ケースはあるにせよ、全体的にこっちの方が使いやすいのかな。

けど、Docker ホストのある場所でファイルやデータを格納してやりとりしたいときは、バインドマウントの方がわかりやすいかも。

なので使い分けは、

  • 単純にコンテナのデータを保存 ボリュームマウント
  • データのやり取り、保存データをホストで編集 バインドマウント

ですかね。

ボリューム関連のコマンド

コマンド 内容 サンプル
cretae ボリュームを作成 docker volume create samplevol
inspect ボリューム情報を確認 docker volume inspect samplevol
ls ボリュームリスト表示 docker volume ls
prune マウントされてないボリュームを削除 docker volume prune
rm ボリューム削除 docker volume create samplevol

ボリュームマウントでコンテナを起動

まずはボリュームを作成します。

[ec2-user@~]$ docker volume create samplevol
samplevol
[ec2-user@~]$ docker volume ls
DRIVER              VOLUME NAME
local               samplevol
[ec2-user@~]$

今回は MySQL コンテナを使ってデータ登録などを行い、その後コンテナを入れ替えてもデータが永続化されてるか確認します。
ではボリュームマウントで MySQL コンテナを起動します。

[ec2-user@~]$ docker run --name mysqldb -dit -p 3306:3306 -v samplevol:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pwsswd mysql:5.7
d90f630bca70b3a53834584434ffba3a4033c90bac4be37cb5beb906bd4998d1
[ec2-user@~]$

MySQL コンテナに入ってデータを登録

コンテナ起動時に -p で3306 でパブリッシュしてるので MySQL WorkBench からアクセスすることができます。※EC2 のセキュリティインバウンドルールにポート3306 は追加しておく必要はあります。
f:id:sennanvolar44:20210111071003p:plain

適当にスキーマとテーブルを作成
f:id:sennanvolar44:20210111071448p:plain

もし、teraterm で直で MySQL コンテナに入る場合は docker exec コマンドを使います。

[ec2-user@~]$ docker exec -it mysqldb /bin/bash
root@d90f630bca70:/#
root@d90f630bca70:/#
root@d90f630bca70:/# mysql -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.32 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

コンテナ再作成

ではコンテナを削除→新規作成しても、先ほど作成したデータが表示されるか確認します。

まずはコンテナを削除

[ec2-user@~]$ docker stop mysqldb
mysqldb
[ec2-user@~]$ docker rm mysqldb
mysqldb
[ec2-user@~]$
[ec2-user@~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS                    PORTS               NAMES
d256c64c0371        httpd:2.4           "httpd-foreground"   24 hours ago        Exited (0) 24 hours ago                       webapp2
[ec2-user@~]$

さっき作成したボリュームをマウントして mysqldb2 という名前で MySQL コンテナを起動してみます。

[ec2-user@~]$ docker run --name mysqldb2 -dit -p 3306:3306 -v samplevol:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pwsswd mysql:5.7
3e442b1084df59a740b96c11218fc2a773133ad587ce90a62b68169b1f1cc6cc
[ec2-user@~]$

MySQL Workbench でアクセスしてみると、先ほど作成したテーブルやレコードが表示されました!
f:id:sennanvolar44:20210111072238p:plain

Docker バインドマウントしてデータを永続化してみる

前回はApache コンテナを起動してみました。

miyamon44.hatenablog.jp

このままだと一度コンテナを削除するとファイルや設定情報などは消えてしまいますので、バインドマウントをしてデータ保存先を Docker から分離してみたいと思います。

バインドマウントしてみる

最初に対象のディレクトリを作成してみます。

[root@ec2-user]# mkdir bindData
[root@ec2-user]# ll
total 0
drwxr-xr-x 2 root root 6 Jan  9 21:01 bindData
[root@bindData]# pwd
/home/ec2-user/bindData

作成した以下ディレクトリをバインド先にします。
/home/ec2-user/bindData

ではコンテナを起動してみようと思いますが、その前に前回作成したコンテナが残ってたので削除しちゃいます。

[root@bindData]# docker stop webapp1
webapp1
[root@bindData]# docker rm  webapp1
webapp1
[root@bindData]#

これできれいになったのでコンテナを起動してみますが、その際に赤字部分にマウントするパスをセットしてあげます。
docker run -dit --name webapp1 -p 8080:80 -v /home/ec2-user/bindData:/usr/local/apache2/htdocs/ httpd:2.4

[root@bindData]# docker run -dit --name webapp1 -p 8080:80 -v /home/ec2-user/bindData:/usr/local/apache2/htdocs/ httpd:2.4
1e6796d3fd27a9d0a630d7c6809d53aa86eb723345e7da93300363445f295bdd
[root@bindData]#
[root@bindData]# docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                  NAMES
1e6796d3fd27        httpd:2.4           "httpd-foreground"   5 seconds ago       Up 4 seconds        0.0.0.0:8080->80/tcp   webapp1
[root@bindData]#

コンテナは起動されましたので、URL:ポートでアクセスしてみます。
f:id:sennanvolar44:20210110064315p:plain
何もないのでこうなりますよね。ではindex.html を置いてみます。

[root@bindData]# ll
total 4
-rw-r--r-- 1 root root 154 Jan  9 21:49 index.html
[root@bindData]# cat index.html
<html>
  <head>
    <meta http-equiv="content-type" charset="utf-8">
  </head>
  <body>
    <div>Docker バインドマウント</div>
  </body>
</html>

[root@bindData]#  

再度ブラウザをリロードしてみると表示されました。
f:id:sennanvolar44:20210110065102p:plain

コンテナを新たに作成

今起動しているコンテナを停止、削除後、再度Apacheコンテナを起動します。(今回はwebapp2という名前にしてみました)

[root@bindData]# docker stop webapp1
webapp1
[root@bindData]# docker rm webapp1
webapp1
[root@bindData]#  
[root@bindData]# docker run -dit --name webapp2 -p 8080:80 -v /home/ec2-user/bindData:/usr/local/apache2/htdocs/ httpd:2.4
d256c64c0371a6e961ee66b6fc1e84f85fa9810ba165e23df91e3f0e739fbf41
[root@bindData]#

新たに作成したコンテナでも index.html ちゃんと表示されました。 f:id:sennanvolar44:20210110070557p:plain

おわり。

Amazon Linux にDocker を入れてApache コンテナを起動してみた

EC2でDocker を使ってWebサーバを作ってみたのでメモ。

EC2 準備

まずは EC2 で VM を用意します。今回は Amazon Linux を利用。

f:id:sennanvolar44:20210108063522p:plain

ポートはとりあえずデフォルトの22 に加えて、8080 も追加。
f:id:sennanvolar44:20210108063839p:plain

キーは以前作成してたのでそれを流用しましたが、なければ新規作成する。
f:id:sennanvolar44:20210108064759p:plain

これで VM の用意が完了です。

Docker Engine のインストール

まずは Teraterm で作成した VM にアクセスします。
Amazon Linux の場合、ユーザー名は ec2-user になります。あとは VM 作成時に指定した秘密鍵を設定。
f:id:sennanvolar44:20210108065412p:plain

以下コマンドで Docker Engine をインストールします。

$ sudo yum update -y
$ sudo amazon-linux-extras install docker
$ sudo yum install docker

インストール後、バージョンを確認する場合

# docker --version
Docker version 19.03.13-ce, build 4484c46

今回は Amazon Linux へのインストールだったので、手順はこちらを参考にしました。
docs.aws.amazon.com

もし、一般ユーザーでdocker コマンドが実行できない場合は、docker グループに入れてあげることで実行できるようになります。

$ sudo usermod -a -G docker ec2-user

Webサーバ起動

いまは VM で Docker を動かすための Docker Engine をインストールまでしたところなので、以下のコマンドで Docker Hub から Apache の Docker Image をダウンロードして実行します。

docker run -dit --name webapp1 -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4

  • -dit : コンテナをバックグラウンドで実行させる
  • --name : コンテナ名
  • -p : Docker ホストとコンテナのポート番号。外部からは8080 でアクセスし、ホストからは 8080 と紐づいたコンテナのポート80 にアクセス
  • -v : ホストのディレクトリ、コンテナのディレクト

それでは実行してみます。

[ec2-user@ip-172-31-42-9 ~]$ docker run -dit --name webapp1 -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
See 'docker run --help'.

もし上記のようなエラーが発生した場合、Docker 自体が起動していないという意味ですので、起動してあげます。

[ec2-user@ip-172-31-42-9 ~]$ sudo service docker start
Redirecting to /bin/systemctl start docker.service
[ec2-user@ip-172-31-42-9 ~]$

実行して ID が返ってきたら起動できたということですので、 ステータスをみてみます。

[ec2-user@ip-172-31-42-9 ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED              STATUS              PORTS                  NAMES
a374217edee6        httpd:2.4           "httpd-foreground"   About a minute ago   Up About a minute   0.0.0.0:8080->80/tcp   webapp1

Status がUp になってるので起動しているのが確認できます。
ちなみに、-a を最後に付与すると停止中のコンテナも表示されます。

この状態で EC2 のIPアドレスと8080でブラウザからアクセスするとWeb ページが表示されるようになります。(まだ何もしてないのでカレントディレクトリの中身が表示されてしまいますが・・)
f:id:sennanvolar44:20210109133959p:plain

もし以下のように 403 エラーが出たら、対象ディレクトリのパーミッションを変更してあげます。 f:id:sennanvolar44:20210109133655p:plain

[ec2-user@ip-172-31-33-236 home]$ chmod 755 ec2-user/
[ec2-user@ip-172-31-33-236 home]$ ll
total 0
drwxr-xr-x 2 root     root       6 Jan  9 04:33 centos
drwxr-xr-x 4 ec2-user ec2-user 109 Jan  9 04:24 ec2-user
[ec2-user@ip-172-31-33-236 home]$

あとは、ホスト側の対象ディレクトリ内にindex.html 置くなどして利用できます。

OnsenUIを触ってみたのでタグとかのメモ

f:id:sennanvolar44:20200211003300p:plain
結構前に初めて monaca で Onsen UI を触ってみましたので、ほんの少しだけタグ中心のメモです。

Onsen UI とは

アプリ開発の際に画面を作成するためのフレームワークだそう。

ja.onsen.io

各種タグや処理の説明

<ons-navigator>

複数のHTML ファイルを操作する役割を持つ。画面上には表示されない。また、次ページ前ページへのページ遷移機能も持っている。

<ons-navigator page="初期表示ページ"></ons-navigator>

<ons-page>

Onsen UI でページを定義するために必要なタグとなる。

<ons-page>
  ・
   ・
   ・
  ・
</ons-page>

<ons-toolbar>

画面上部に表示されるツールバー

    <ons-toolbar>
        <div class="center">画面1</div>
    </ons-toolbar>

<ons-button>

画面に表示されるボタン。

        <ons-button> OKボタン</ons-button>

OKボタン押下でページ遷移する場合

<ons-button onclick="document.getElementById('id').pushPage('B.html')">
OKボタン
</ons-button>

TOP画面に戻る。内部で保持していたページの履歴もリセットされる。

<ons-button onclick="document.getElementById('id').resetToPage('TOP.html')">
TOPボタン
</ons-button>

<ons-back-button>

前の画面に戻るボタン。

<ons-back-button>Back</ons-back-button>

<ons-list>と<ons-listi-tem>

リスト形式でデータを一覧表示するためのタグ。リスト内のデータを1件ずつ扱う場合は、<ons-listitem>。

<ons-list>
 <ons-list-item>項目1</ons-list-item>
 <ons-list-item>項目2</ons-list-item>
 <ons-list-item>項目3</ons-list-item>
</ons-list>

初期処理

Onsen UI でのInit処理。

document.addEventListener("init", function(event) {
 if (event.target.id == "ページの ID") {
 //ページの初期処理
 }
});