在 Docker 中混合命名卷和绑定安装?
Mixing named volumes and bind mounting in Docker?
如何混合使用命名卷和绑定装载?使用以下设置,绑定挂载的路径是否仍然可以在绑定挂载中使用,因为它们存在于绑定挂载中?
/var/www/html/wp-content/uploads
使用我附加到命名卷的单独容器似乎表明情况并非如此,因为从单独容器的角度来看,这些路径完全是空的。有没有办法让它在某种意义上起作用?
volumes:
- "wordpress:/var/www/html"
- "./wordpress/uploads:/var/www/html/wp-content/uploads"
- "./wordpress/plugins:/var/www/html/wp-content/plugins"
- "./wordpress/themes:/var/www/html/wp-content/themes"
我相信答案是配置绑定传播。
会回来汇报的。
编辑:似乎您只能在绑定安装的卷上配置绑定传播,并且只能在 linux 主机系统上配置。
主机卷:对于主机卷,在您的 docker 组合文件中使用路径定义,例如:
volumes:
- "./wordpress/uploads:/var/www/html/wp-content/uploads"
您不会从图像内容中接收到主机目录的任何初始化信息。这是设计使然。
命名卷:您可以定义映射回本地目录的命名卷:
version: "2"
services:
your-service:
volumes:
- uploads:/var/www/html/wp-content/uploads
volumes:
uploads:
driver: local
driver_opts:
type: none
o: bind
device: /path/on/host/to/wordpress/uploads
这将提供命名卷的初始化属性。当您的主机目录为空时,在创建容器时 docker 会将位于 /var/www/html/wp-content/uploads 的图像内容复制到 /path/on/host/to/wordpress/uploads.
带有 Docker 的嵌套安装:如果您有多个嵌套卷安装,docker 仍将从图像目录内容复制,而不是从父目录复制音量。
这是该初始化的示例。从文件系统开始:
testvol/
data-image/
sub-dir/
from-image
data-submount/
Dockerfile
docker-compose.yml
Docker文件包含:
FROM busybox
COPY data-image/ /data
docker-compose.yml包含:
version: "2"
services:
test:
build: .
image: test-vol
command: find /data
volumes:
- data:/data
- subdir:/data/sub-dir
volumes:
data:
subdir:
driver: local
driver_opts:
type: none
o: bind
device: /path/on/host/test-vol/data-submount
并且命名卷已经初始化:
$ docker run -it --rm -v testvol_data:/data busybox find /data
/data
/data/sub-dir
/data/sub-dir/from-named-vol
运行 测试显示副本来自 from-image
而不是 from-named-vol
:
$ docker-compose -f docker-compose.bind.yml up
...
Attaching to testvol_test_1
test_1 | /data
test_1 | /data/sub-dir
test_1 | /data/sub-dir/from-image
testvol_test_1 exited with code 0
并且 docker 已将此复制到主机文件系统:
$ ls -l data-submount/
total 0
-rw-r--r-- 1 root root 0 Jan 15 08:08 from-image
Linux 中的嵌套安装:从你的问题来看,Linux 中安装本身的工作方式似乎有些混乱。每个卷挂载都在容器的挂载命名空间中运行。这个命名空间为容器提供了它自己的文件系统树视图。当您将一个卷挂载到该树中时,您不会修改父文件系统的内容,它只是覆盖了该位置父文件系统的内容。所有更改都直接发生在新挂载的目录中,如果您要卸载它,则父目录将以其原始状态可见。
因此,如果您在一个容器中挂载两个嵌套目录,例如/data
和 /data/a
,然后在第二个容器中挂载 /data
,您将不会在第二个容器中看到第一个容器中的 /data/a
,只有 [=20] 的内容=] 将在那里,包括安装在上面的所有文件夹。
我试过让它工作几个小时,但我得出的结论是它根本行不通。我的案例是将特定插件添加到 CMS 作为本地开发的卷。我想在这里 post 因为我在任何地方都没有遇到过这个解决方法。
因此以下内容会遇到重叠卷的问题,导致文件夹为空。
services:
your-service:
volumes:
- web-data:/var/www/html
- ./wordpress/plugins:/var/www/html/wp-content/plugins
- ./wordpress/themes:/var/www/html/wp-content/themes
通过将主题和插件绑定到不同的目录,不在 /var/www/html
.
中,这就是避免这种情况的方法
services:
your-service:
volumes:
- web-data:/var/www/html
- ./wordpress/plugins:/tmp/plugins
- ./wordpress/themes:/tmp/themes
但现在您必须将这些文件放在正确的位置,并让它们与主机上的文件保持同步。
简单版
注意:这些示例假设您有一个 shell 脚本作为入口点。
在您的 Docker 入口点:
#!/bin/bash
ln -s /tmp/plugins/my-plugin /var/www/html/wp-content/plugins/my-plugin
ln -s /tmp/themes/my-theme /var/www/html/wp-content/themes/my-theme
只要您的 system/software 解析符号链接,这就应该有效。
更多模块化解决方案
我只是为插件写的,但你可以用同样的方式处理主题。这会在 /tmp/plugins
文件夹中找到所有插件并将它们符号链接到 /var/www/html/wp-content/plugins/<plugin>
,而无需在脚本中编写硬编码的 folder/plugin 名称。
#!/bin/bash
TMP_PLUGINS_DIR="/tmp/plugins"
CMS_PLUGINS_DIR="/var/www/html/wp-content/plugins"
# Loop through all paths in the /tmp/plugins folder.
for path in $TMP_PLUGINS_DIR/*/; do
# Ignore anything that's not a directory.
[ -d "${path}" ] || continue
# Get the plugin name from the path.
plugin="$(basename "${path}")"
# Symlink the plugin to the real plugins folder.
ln -sf $TMP_PLUGINS_DIR/$plugin CMS_PLUGINS_DIR/$plugin
# Anything else you might need to do for each plugin, like installing/enabling it in your CMS.
done
如何混合使用命名卷和绑定装载?使用以下设置,绑定挂载的路径是否仍然可以在绑定挂载中使用,因为它们存在于绑定挂载中?
/var/www/html/wp-content/uploads
使用我附加到命名卷的单独容器似乎表明情况并非如此,因为从单独容器的角度来看,这些路径完全是空的。有没有办法让它在某种意义上起作用?
volumes:
- "wordpress:/var/www/html"
- "./wordpress/uploads:/var/www/html/wp-content/uploads"
- "./wordpress/plugins:/var/www/html/wp-content/plugins"
- "./wordpress/themes:/var/www/html/wp-content/themes"
我相信答案是配置绑定传播。
会回来汇报的。
编辑:似乎您只能在绑定安装的卷上配置绑定传播,并且只能在 linux 主机系统上配置。
主机卷:对于主机卷,在您的 docker 组合文件中使用路径定义,例如:
volumes:
- "./wordpress/uploads:/var/www/html/wp-content/uploads"
您不会从图像内容中接收到主机目录的任何初始化信息。这是设计使然。
命名卷:您可以定义映射回本地目录的命名卷:
version: "2"
services:
your-service:
volumes:
- uploads:/var/www/html/wp-content/uploads
volumes:
uploads:
driver: local
driver_opts:
type: none
o: bind
device: /path/on/host/to/wordpress/uploads
这将提供命名卷的初始化属性。当您的主机目录为空时,在创建容器时 docker 会将位于 /var/www/html/wp-content/uploads 的图像内容复制到 /path/on/host/to/wordpress/uploads.
带有 Docker 的嵌套安装:如果您有多个嵌套卷安装,docker 仍将从图像目录内容复制,而不是从父目录复制音量。
这是该初始化的示例。从文件系统开始:
testvol/
data-image/
sub-dir/
from-image
data-submount/
Dockerfile
docker-compose.yml
Docker文件包含:
FROM busybox
COPY data-image/ /data
docker-compose.yml包含:
version: "2"
services:
test:
build: .
image: test-vol
command: find /data
volumes:
- data:/data
- subdir:/data/sub-dir
volumes:
data:
subdir:
driver: local
driver_opts:
type: none
o: bind
device: /path/on/host/test-vol/data-submount
并且命名卷已经初始化:
$ docker run -it --rm -v testvol_data:/data busybox find /data
/data
/data/sub-dir
/data/sub-dir/from-named-vol
运行 测试显示副本来自 from-image
而不是 from-named-vol
:
$ docker-compose -f docker-compose.bind.yml up
...
Attaching to testvol_test_1
test_1 | /data
test_1 | /data/sub-dir
test_1 | /data/sub-dir/from-image
testvol_test_1 exited with code 0
并且 docker 已将此复制到主机文件系统:
$ ls -l data-submount/
total 0
-rw-r--r-- 1 root root 0 Jan 15 08:08 from-image
Linux 中的嵌套安装:从你的问题来看,Linux 中安装本身的工作方式似乎有些混乱。每个卷挂载都在容器的挂载命名空间中运行。这个命名空间为容器提供了它自己的文件系统树视图。当您将一个卷挂载到该树中时,您不会修改父文件系统的内容,它只是覆盖了该位置父文件系统的内容。所有更改都直接发生在新挂载的目录中,如果您要卸载它,则父目录将以其原始状态可见。
因此,如果您在一个容器中挂载两个嵌套目录,例如/data
和 /data/a
,然后在第二个容器中挂载 /data
,您将不会在第二个容器中看到第一个容器中的 /data/a
,只有 [=20] 的内容=] 将在那里,包括安装在上面的所有文件夹。
我试过让它工作几个小时,但我得出的结论是它根本行不通。我的案例是将特定插件添加到 CMS 作为本地开发的卷。我想在这里 post 因为我在任何地方都没有遇到过这个解决方法。
因此以下内容会遇到重叠卷的问题,导致文件夹为空。
services:
your-service:
volumes:
- web-data:/var/www/html
- ./wordpress/plugins:/var/www/html/wp-content/plugins
- ./wordpress/themes:/var/www/html/wp-content/themes
通过将主题和插件绑定到不同的目录,不在 /var/www/html
.
services:
your-service:
volumes:
- web-data:/var/www/html
- ./wordpress/plugins:/tmp/plugins
- ./wordpress/themes:/tmp/themes
但现在您必须将这些文件放在正确的位置,并让它们与主机上的文件保持同步。
简单版
注意:这些示例假设您有一个 shell 脚本作为入口点。
在您的 Docker 入口点:
#!/bin/bash
ln -s /tmp/plugins/my-plugin /var/www/html/wp-content/plugins/my-plugin
ln -s /tmp/themes/my-theme /var/www/html/wp-content/themes/my-theme
只要您的 system/software 解析符号链接,这就应该有效。
更多模块化解决方案
我只是为插件写的,但你可以用同样的方式处理主题。这会在 /tmp/plugins
文件夹中找到所有插件并将它们符号链接到 /var/www/html/wp-content/plugins/<plugin>
,而无需在脚本中编写硬编码的 folder/plugin 名称。
#!/bin/bash
TMP_PLUGINS_DIR="/tmp/plugins"
CMS_PLUGINS_DIR="/var/www/html/wp-content/plugins"
# Loop through all paths in the /tmp/plugins folder.
for path in $TMP_PLUGINS_DIR/*/; do
# Ignore anything that's not a directory.
[ -d "${path}" ] || continue
# Get the plugin name from the path.
plugin="$(basename "${path}")"
# Symlink the plugin to the real plugins folder.
ln -sf $TMP_PLUGINS_DIR/$plugin CMS_PLUGINS_DIR/$plugin
# Anything else you might need to do for each plugin, like installing/enabling it in your CMS.
done