2022/10/02 Updated by

Docker

コンテナ内のファイルと永続化


[Up] Japanese English

コンテナとファイルの独立性

まず、どのような docker image が手元にあるか、一覧を表示する。

$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
httpd        2.4       f2789344c573   3 weeks ago   145MB
golang       1.13      d6f3656320fe   2 years ago   803MB
この httpd:2.4 を使うことにする。

2つのhttpdコンテナを起動する

"docker run" コマンドで "-v"オプションを使わずに、2つの httpd コンテナを起動してみる。
[マシン名とポート番号]
  web01  8080
  web02  80801

[起動方法]
  $ docker run -dit --name web01 -p 8080:80 httpd:2.4
  $ docker run -dit --name web02 -p 8081:80 httpd:2.4

[起動を確認する]
  $ docker ps -a
  CONTAINER ID   IMAGE       COMMAND              CREATED          STATUS          PORTS                                   NAMES
  c502be372b49   httpd:2.4   "httpd-foreground"   21 seconds ago   Up 20 seconds   0.0.0.0:8081->80/tcp, :::8081->80/tcp   web02
  3ce2f4c419a3   httpd:2.4   "httpd-foreground"   28 seconds ago   Up 27 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   web01
docker ホストの IP Address を 3.113.245.228 とすると、次の URL にブラウザでアクセスする。
http://3.113.245.228:8080/
http://3.113.245.228:8081/

コンテナの中にファイルをコピーする

docker cp オプション  コピー元のパス名   コンテナ名:コピー先のパス名
docker cp オプション  コンテナ名:コピー元のパス名   コピー先のパス名

[オプション]
    -a, --archive    ユーザーIDとグループIDを保ったままコピーする
    -l, --follow-link  コピー元のシンボリックリンクをたどる

ホスト側でファイルを編集して、コンテナの中にコピーする

web01/index.html
<html>
<body>
<div>web01: hello web server</div>
</body>
</html>


web02/index.html
<html>
<body>
<div>web02: hello web server</div>
</body>
</html>
  $ docker cp web01/index.html web01:/usr/local/apache2/htdocs
  $ docker cp web02/index.html web02:/usr/local/apache2/htdocs






コンテナの中に入って確認する

web01 内でshellを使って確認
ubuntu@ip-172-30-2-68:~$ docker exec -it web01 /bin/bash
root@e46b22761f4a:/usr/local/apache2# cd htdocs
root@e46b22761f4a:/usr/local/apache2/htdocs# ls -l
total 4
-rwxr-xr-x 1 1000 1000 65 Oct  4 13:56 index.html
root@e46b22761f4a:/usr/local/apache2/htdocs# cat index.html
<html>
<body>
<div>web01: hello web server</div>
</body>
</html>
root@68fa0d402a2a:/usr/local/apache2/htdocs# exit


web02 内でshellを使って確認
ubuntu@ip-172-30-2-68:~$ docker exec -it web02 /bin/bash
root@68fa0d402a2a:/usr/local/apache2# cd htdocs
root@68fa0d402a2a:/usr/local/apache2/htdocs# ls -l
total 4
-rwxr-xr-x 1 1000 1000 65 Oct  4 13:56 index.html
root@68fa0d402a2a:/usr/local/apache2/htdocs# cat index.html
<html>
<body>
<div>web02: hello web server</div>
</body>
</html>
root@68fa0d402a2a:/usr/local/apache2/htdocs# exit
これ以後 web01 コンテナや web02 コンテナを削除すると、その中のファイルは失われることに注意すること。

データを独立させる

docker ホストのフォルダをマウントすれば、コンテナを削除しても、ファイルは失われない。

設定ファイルの受け渡しや作業フォルダを受け渡す。

ホストのファイルシステムをマウントする場合は、コンテナ起動前に設定ファイルを変更することができる。

ホストのファイルシステムをマウントしないが、コンテナ起動前に設定ファイルを変更したい場合は、docker run は使えない。 一旦 docker create しておいて、docker cp などでファイルを送り込んでから 、docker start で起動することになる。

バインドマウントとボリュームマウント

「バインドマウント」とは、Docker ホスト上にあらかじめディレクトリを作っておき、それをマウントする方法である。 また、「ボリュームマウント」とは、Docker Engine 上で確保した領域(データボリューム)をマウントする方法である。

MySQL コンテナを使った例

mysql:5.7 イメージを用いて、ボリュームマウントを使ってみる。

  1. docker でボリュームを作成する
  2.   $ docker volume create mysqlvolume
      mysqlvolume
    
  3. 作成したボリュームを確認する
  4.   $ docker volume ls
      DRIVER    VOLUME NAME
      local     mysqlvolume
    
  5. MySQL 5.7 のコンテナを起動する。
  6. ubuntu@ip-172-30-2-68:~$ docker run --name db01 -dit -v mysqlvolume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mypassword mysql:5.7
    Unable to find image 'mysql:5.7' locally
    5.7: Pulling from library/mysql
    a2a00260331c: Pull complete
    6d8167f2fcbe: Pull complete
    32454e9854ca: Pull complete
    473e2917b0d5: Pull complete
    5173f8104ec8: Pull complete
    32e218351f9a: Pull complete
    fc9e1a82359a: Pull complete
    c602a3ea2ce7: Pull complete
    3c9ea9927039: Pull complete
    dfb1b236c7fc: Pull complete
    e2ad62bd72a7: Pull complete
    Digest: sha256:94fe67a04001e9841f68f114c8e9b5231c1d012e6b00d3b8ade42c0c5e239a0f
    Status: Downloaded newer image for mysql:5.7
    
  7. コンテナの起動を確認する。
  8. ubuntu@ip-172-30-2-68:~$ docker ps
    CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                 NAMES
    f3fe4b31d415   mysql:5.7   "docker-entrypoint.s…"   53 seconds ago   Up 52 seconds   3306/tcp, 33060/tcp   db01f3fe4b31d415a6b40d66931046df3847cdfd00db89bafa8a1dadd739b56747e2
    
  9. mysql コンテナに入る
  10. ubuntu@ip-172-30-2-68:~$ docker exec -it db01 /bin/bash
    
  11. mysql コマンドでデータベースを操作する
  12. bash-4.2# mysql -p
    Enter password:
    ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    bash-4.2# mysql -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 3
    Server version: 5.7.39 MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2022, Oracle and/or its affiliates.
    
    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> CREATE DATABASE exampledb;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> use exampledb;
    Database changed
    mysql> CREATE TABLE exampletable (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(50), PRIMARY KEY(id));
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> INSERT INTO exampletable (name) VALUES ('user01');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> INSERT INTO exampletable (name) VALUES ('user02');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> SELECT * FROM exampletable;
    +----+--------+
    | id | name   |
    +----+--------+
    |  1 | user01 |
    |  2 | user02 |
    +----+--------+
    2 rows in set (0.00 sec)
    
    mysql> \q
    Bye
    
  13. mysql コンテナから出る
  14. bash-4.2# exit
    exit
    
  15. mysql コンテナを停止し、破棄する
  16. ubuntu@ip-172-30-2-68:~$ docker stop db01
    dockerdb01
    ubuntu@ip-172-30-2-68:~$ docker rm db01
    db01
    
  17. コンテナが破棄されたことを確認する
  18. ubuntu@ip-172-30-2-68:~$ docker ps -a
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    ubuntu@ip-172-30-2-68:~$
    

ボリュームの場所

ubuntu@ip-172-30-2-68:~$ docker volume inspect mysqlvolume
[
    {
        "CreatedAt": "2022-10-05T01:36:48Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/mysqlvolume/_data",
        "Name": "mysqlvolume",
        "Options": {},
        "Scope": "local"
    }
]