使用“-v /path:/path”参数执行 docker 运行 时,在 Dockerfile 中生成的文件丢失
File made in Dockerfile lost when exec docker run with "-v /path:/path" params
我遇到了 docker 音量 的麻烦。我想 mkdir
目录和 touch
文件在 Dockerfile 中。
当我用 -v /path:/path image_name
参数执行 docker run -it --name any_name
时,在 Dockerfile 中创建的目录和文件都丢失了。
例如:
构建映像的 Dockerfile BB:tag。
FROM AA:tag
RUN set -ex \
&& mkdir -p /var/log/my_directory/ \
&& touch /var/log/my_directory/my_file.log
CMD ["anything_cmd"]
如果我执行
docker run -it --name any_name BB:tag
my_directory 和 my_file.log 都在那里。
但是如果我执行
docker run -it --name any_name -v /var/log/container_logs/any_name:/var/log/ BB:tag
my_directory 和 my_file.log 都丢失了。
当 docker run
时 -v
发生了什么?做这种事情的最佳做法是什么?
Dockerfile 中的步骤用于创建映像。
docker run
命令获取镜像并创建容器。
挂载卷(-v
参数)会将目录绑定挂载到容器中的给定位置。主机挂载在该卷上没有任何初始化步骤。
因此,预计只能在位于 /var/log/
的容器内的主机上看到来自 /var/log/container_logs/any_name
的文件。
如果您需要初始化卷,有几个选项:
您可以使用命名卷而不是主机卷。这将被初始化,但仅当该命名卷为空时。一旦命名卷中有文件,docker 将不会再次初始化它,因为这可能会导致数据丢失。
您可以在容器内使用入口点脚本将文件从保存的位置复制到卷位置。图像中的这个保存位置不能用体积覆盖,否则你会遇到同样的问题。
如果你想要一个指向主机目录的命名卷,你可以使用带有选项的本地卷驱动程序(这是默认设置)来绑定挂载特定目录。各种实现方法包括:
# create the volume in advance
$ docker volume create --driver local \
--opt type=none \
--opt device=/home/user/test \
--opt o=bind \
test_vol
# create on the fly with --mount
$ docker run -it --rm \
--mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/home/user/test \
foo
# inside a docker-compose file
...
volumes:
bind-test:
driver: local
driver_opts:
type: none
o: bind
device: /home/user/test
...
如果您想使用入口点脚本,请参阅 my base image repo 中的卷缓存说明。
我遇到了 docker 音量 的麻烦。我想 mkdir
目录和 touch
文件在 Dockerfile 中。
当我用 -v /path:/path image_name
参数执行 docker run -it --name any_name
时,在 Dockerfile 中创建的目录和文件都丢失了。
例如:
构建映像的 Dockerfile BB:tag。
FROM AA:tag
RUN set -ex \
&& mkdir -p /var/log/my_directory/ \
&& touch /var/log/my_directory/my_file.log
CMD ["anything_cmd"]
如果我执行
docker run -it --name any_name BB:tag
my_directory 和 my_file.log 都在那里。
但是如果我执行
docker run -it --name any_name -v /var/log/container_logs/any_name:/var/log/ BB:tag
my_directory 和 my_file.log 都丢失了。
当 docker run
时 -v
发生了什么?做这种事情的最佳做法是什么?
Dockerfile 中的步骤用于创建映像。
docker run
命令获取镜像并创建容器。挂载卷(
-v
参数)会将目录绑定挂载到容器中的给定位置。主机挂载在该卷上没有任何初始化步骤。
因此,预计只能在位于 /var/log/
的容器内的主机上看到来自 /var/log/container_logs/any_name
的文件。
如果您需要初始化卷,有几个选项:
您可以使用命名卷而不是主机卷。这将被初始化,但仅当该命名卷为空时。一旦命名卷中有文件,docker 将不会再次初始化它,因为这可能会导致数据丢失。
您可以在容器内使用入口点脚本将文件从保存的位置复制到卷位置。图像中的这个保存位置不能用体积覆盖,否则你会遇到同样的问题。
如果你想要一个指向主机目录的命名卷,你可以使用带有选项的本地卷驱动程序(这是默认设置)来绑定挂载特定目录。各种实现方法包括:
# create the volume in advance
$ docker volume create --driver local \
--opt type=none \
--opt device=/home/user/test \
--opt o=bind \
test_vol
# create on the fly with --mount
$ docker run -it --rm \
--mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/home/user/test \
foo
# inside a docker-compose file
...
volumes:
bind-test:
driver: local
driver_opts:
type: none
o: bind
device: /home/user/test
...
如果您想使用入口点脚本,请参阅 my base image repo 中的卷缓存说明。