ドキュメント: ボリュームの使用
DockerfileのRUN/CMD/ENTRYPOINT、docker-compose.yml の volume / command / entrypoint プロパティの実行順序は以下のとおりです。
RUN命令volume プロパティのマウントCMD 命令 / ENTRYPOINT 命令docker-compose.ymlのcommand/entrypointプロパティはDockerfileを上書きするDockerfileのRUN命令の後にvolumeプロパティでボリュームがマウントされることに注意。
Dockerfile内でのマウントされるディレクトリに対するファイル作成などの出力などはdocker-compose.ymlのvolumeプロパティでマウントされて上書きされる。
コンテナでデータを永続化する方法はおもに3つあります。
バインドマウントと名前付きボリュームの例を見ます。
例としてMysql 5.7.38イメージを使用します[^mount-sample]。
[^bind-mount]: Linux のバインドマウント( mount --bind )はディレクトリを別のディテクトりにマウントする技術です。
[^mount-sample]:イメージmysql:5.7.38のマウント先はmysql.5.7.38のdescriptionに記載されています。
version: "3"
services:
  db:
    image: mysql:5.7.38
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    volumes:
      - mysql-5.7-store:/var/lib/mysql    # 名前付きボリューム
      - ./logs:/var/log/mysql             # バインドマウント
    environment:
      MYSQL_ROOT_PASSWORD: example
volumes:
  mysql-5.7-store:
Docker Composeを実行します。
$ docker-compose up -d
名前付きボリュームは docker volume ls で確認できます[^volume_name]。
[^volume_name]:ボリューム名は name プロパティを省略した場合、デフォルトではdocker-compose.ymlで指定した名前にディレクトリ名が付与されます。
$ docker volume ls
DRIVER    VOLUME NAME
local     mysql-5.7-store:
コンテナにログインして example データベースを作成します。
コンテナを確認します。
docker ps --all
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                 NAMES
f1104a347bac   mysql:5.7.38   "docker-entrypoint.s…"   25 seconds ago   Up 24 seconds   3306/tcp, 33060/tcp   mysql57_db_1
コンテナに入って example データベースを作成します。
$ docker exec -it f1104a347bac /bin/bash
# mysql -uroot -pexample
> create database example;
ボリユームを残してコンテナ及びネットワークを削除します。
$ docker-compose down
ボリュームを確認します。
$ docker volume ls
DRIVER    VOLUME NAME
local     mysql-5.7-store
mysql-5.7-store ボリュームを指定してコンテナを起動します[^compose-up]。
[^compose-up]:docker-compose up -dでも同様ですが、今回はdocker runで起動してみます。
$ docker run  -v mysql-5.7-store:/var/lib/mysql --name mysql-sample -d mysql:5.7.38
mysql-storageが接続されていることを確認します。
$ docker exec -it mysql-sample /bin/bash
root@4654047770fe:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.38 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> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| example            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)
先程追加した example データベースが存在します。
volume の情報を確認します。
$ docker volume inspect mysql-5.7-store
[
    {
        "CreatedAt": "2022-05-28T07:13:21Z",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "mysql57",
            "com.docker.compose.version": "2.5.1",
            "com.docker.compose.volume": "mysql-storagee"
        },
        "Mountpoint": "/var/lib/docker/volumesmysql-storagee/_data", // ホスト側ディレクトリ
        "Name": "mysql-5.7-store",
        "Options": null,
        "Scope": "local"
    }
]
Macでは /var/lib/docker/volumes/mysql-storage/_data は存在しません。
理由は以下サイトで詳しく解説されています。
[Docker for Mac] Docker Volumeの実態がどこにあるのか、探してみた