指定共享卷的数据来源
Specify origin of data for a shared volume
我有一个任务已经解决,但我对解决方案不满意。基本上,我有一个网络服务器容器 (Nginx) 和一个快速 CGI 容器 (PHP-FPM)。 Web 服务器容器构建在现成的镜像上,FCGI 容器基于自定义镜像并包含应用程序文件。现在,由于并非所有内容都是源代码并在 FCGI 容器上进行处理,我还需要使应用程序文件在 Web 服务器容器内可用。
这是执行此任务的 docker-compose.yml
:
version: '3.3'
services:
nginx:
image: nginx:1-alpine
volumes:
- # customize just the Nginx configuration file
type: bind
source: ./nginx.conf
target: /etc/nginx/nginx.conf
- # mount application files from PHP-FPM container
type: volume
source: www-data
target: /var/www/my-service
read_only: true
volume:
nocopy: true
ports:
- "80:80"
depends_on:
- php-fpm
php-fpm:
image: my-service:latest
command: ["/usr/sbin/php-fpm7.3", "--nodaemonize", "--force-stderr"]
volumes:
- # create volume from application files
# This one populates the content of the volume.
type: volume
source: www-data
target: /var/www/my-service
volumes:
# volume with application files shared between nginx and php-fpm
www-data:
我不喜欢这里的地方主要反映在有关卷的评论中。谁创建和存储数据应该从代码而不是评论中显而易见。另外,我真正不喜欢的是 docker 实际上创建了一个地方来存储该卷的数据。这不仅会耗尽磁盘 space 并增加启动时间,还要求我永远不要忘记使用 docker-compose down --volumes
以便在下次启动时刷新内容。想象一下当我发现 down
没有拆除 up
创造的东西并且我正在寻找以前运行的幽灵时我的愤怒。
我的问题是:
- 我可以用代码更清楚地表达一个容器包含的数据应该提供给其他容器吗?上面的代码可以运行,但是完全没有表达意图。
- 我可以避免创建任何持久性内容来避免上述缺点吗?
- 我本来想研究 tmpfs 卷或其他卷选项之类的东西。我的问题是我找不到可用卷驱动程序的文档,甚至找不到存在哪些卷驱动程序。也许我为此错过了一些 CLI,我真的很感激在这里朝着正确的方向轻推。
您可以使用带选项 type=tmpfs
的 local
驱动程序,例如:
volumes:
www-data:
driver: local
driver_opts:
type: tmpfs
device: tmpfs
哪个将符合您的要求:
- 数据将在运行时在容器之间共享
- 数据不应持久化,即当容器停止、重新启动或销毁时卷将被清空
这是 CLI 等效于
docker volume create --driver local --opt type=tmpfs --opt device=tmpfs www-data
重要说明:这不是 Docker tmpfs
坐骑,而是 Docker volume
使用 tmpfs
选项 。正如 local
volume driver documentation it uses the Linux mount
选项中所述,在我们的例子中 --types
指定一个 tmpfs
文件系统。与简单的 tmpfs
挂载相反,它将允许您在容器之间共享卷,同时保留临时文件系统的经典行为
I can't find documentation for available volume drivers or even explore which volume drivers exist
- Volume doc, including tmpfs, Bind mount and Volumes
local
driver options 可在 docker volume create
文档中找到
- Volume driver plugins - some are still updated regularly or seem maintained, but most of them have not been updated for a long time or are deprecated. The list does not seem exhaustive though, for instance
vieux/sshfs
没有提到。
Can I express in code that one container contains data that should be made available to other containers more clearly? The above code works, but it fails utterly to express the intent.
我不这么认为,关于本卷的意图,您的代码已经很清楚了:
- 这就是卷的用途:在容器之间共享数据。正如文档中所述 卷可以更安全地在多个容器 之间共享,而且只有容器应该写入卷。
nocopy
和 read_only
明确表示 nginx
依赖于另一个容器写入的数据,因为它只能从该卷中读取
- 鉴于您的卷不是
external
,可以安全地假设只有同一堆栈中的另一个容器可以使用它
- 一些关于 Docker 的逻辑和经验可以让我们快速回到前一点,但即使对于经验不足的 Docker 用户,您的评论也给出了明确的指示,您的注释是代码的一部分 ;)
您还可以使用 php 图像
中的静态副本制作自定义 nginx 图像
这里是 nginx 的 Dockerfile
FROM my-service:latest AS src-files
FROM nginx
COPY --from=src-files /path-to-static-in-my-service-image /path-to-static-in-nginx
这将允许您不使用带有源代码的卷
也可以在 Dockerfile 中使用环境变量中的 TAG
FROM my-service:${TAG} AS src-files
...
这取决于您设置的用例。如果它仅适用于本地开发人员,或者如果您想要在生产环境中使用同样的东西。在开发人员中,手动填充卷或由一个容器为其他容器填充卷可能没问题。
但如果您想要在生产中以相同方式 运行 的东西,您可能需要其他东西。例如,在生产中,我不想将我的代码放在卷中,而是以不可变的方式放在我的映像中,我只需要重新部署它。
对我来说,卷不是用于存储应用程序代码,而是用于存储缓存、用户上传内容等数据。我们希望在部署之间保留一些东西。
所以,如果我们想要 2 个具有相同文件的图像而不在一个卷中,我将使用应用程序代码和静态内容构建 2 个图像,一个用于 php,一个用于 nginx。
但是这两个图像的部署通常是不同步的。我们通过先部署 PHP 应用程序然后部署 nginx 应用程序来解决这个问题。在 nginx 上,我们添加了一个配置,它首先尝试从中提供静态内容,如果该文件不存在,则向 PHP.
询问
对于开发环境,我们将重用相同的图像,但使用卷将当前代码挂载到容器内(主机绑定挂载)。
但在某些情况下,绑定挂载可能会出现一些问题:
- 在 Mac 上,文件共享速度很慢,但在 Edge 频道 (2.3.1.0) 中使用最新版本的 Docker 桌面应该会更好
- 在 Windows 上,文件共享也很慢
- 在 Linux 上,我们需要注意容器内使用的文件权限和用户
如果您尝试使用卷解决方案解决 one/many 个问题,我们可以找到一些解决方案。例如,在 Mac 上,我将首先尝试 docker 的 Edge 版本,在 Windows 上,如果可能,我将使用 WSL2 并且 Docker 设置为使用 WSL2 后端。
我有一个任务已经解决,但我对解决方案不满意。基本上,我有一个网络服务器容器 (Nginx) 和一个快速 CGI 容器 (PHP-FPM)。 Web 服务器容器构建在现成的镜像上,FCGI 容器基于自定义镜像并包含应用程序文件。现在,由于并非所有内容都是源代码并在 FCGI 容器上进行处理,我还需要使应用程序文件在 Web 服务器容器内可用。
这是执行此任务的 docker-compose.yml
:
version: '3.3'
services:
nginx:
image: nginx:1-alpine
volumes:
- # customize just the Nginx configuration file
type: bind
source: ./nginx.conf
target: /etc/nginx/nginx.conf
- # mount application files from PHP-FPM container
type: volume
source: www-data
target: /var/www/my-service
read_only: true
volume:
nocopy: true
ports:
- "80:80"
depends_on:
- php-fpm
php-fpm:
image: my-service:latest
command: ["/usr/sbin/php-fpm7.3", "--nodaemonize", "--force-stderr"]
volumes:
- # create volume from application files
# This one populates the content of the volume.
type: volume
source: www-data
target: /var/www/my-service
volumes:
# volume with application files shared between nginx and php-fpm
www-data:
我不喜欢这里的地方主要反映在有关卷的评论中。谁创建和存储数据应该从代码而不是评论中显而易见。另外,我真正不喜欢的是 docker 实际上创建了一个地方来存储该卷的数据。这不仅会耗尽磁盘 space 并增加启动时间,还要求我永远不要忘记使用 docker-compose down --volumes
以便在下次启动时刷新内容。想象一下当我发现 down
没有拆除 up
创造的东西并且我正在寻找以前运行的幽灵时我的愤怒。
我的问题是:
- 我可以用代码更清楚地表达一个容器包含的数据应该提供给其他容器吗?上面的代码可以运行,但是完全没有表达意图。
- 我可以避免创建任何持久性内容来避免上述缺点吗?
- 我本来想研究 tmpfs 卷或其他卷选项之类的东西。我的问题是我找不到可用卷驱动程序的文档,甚至找不到存在哪些卷驱动程序。也许我为此错过了一些 CLI,我真的很感激在这里朝着正确的方向轻推。
您可以使用带选项 type=tmpfs
的 local
驱动程序,例如:
volumes:
www-data:
driver: local
driver_opts:
type: tmpfs
device: tmpfs
哪个将符合您的要求:
- 数据将在运行时在容器之间共享
- 数据不应持久化,即当容器停止、重新启动或销毁时卷将被清空
这是 CLI 等效于
docker volume create --driver local --opt type=tmpfs --opt device=tmpfs www-data
重要说明:这不是 Docker tmpfs
坐骑,而是 Docker volume
使用 tmpfs
选项 。正如 local
volume driver documentation it uses the Linux mount
选项中所述,在我们的例子中 --types
指定一个 tmpfs
文件系统。与简单的 tmpfs
挂载相反,它将允许您在容器之间共享卷,同时保留临时文件系统的经典行为
I can't find documentation for available volume drivers or even explore which volume drivers exist
- Volume doc, including tmpfs, Bind mount and Volumes
local
driver options 可在docker volume create
文档中找到- Volume driver plugins - some are still updated regularly or seem maintained, but most of them have not been updated for a long time or are deprecated. The list does not seem exhaustive though, for instance
vieux/sshfs
没有提到。
Can I express in code that one container contains data that should be made available to other containers more clearly? The above code works, but it fails utterly to express the intent.
我不这么认为,关于本卷的意图,您的代码已经很清楚了:
- 这就是卷的用途:在容器之间共享数据。正如文档中所述 卷可以更安全地在多个容器 之间共享,而且只有容器应该写入卷。
nocopy
和read_only
明确表示nginx
依赖于另一个容器写入的数据,因为它只能从该卷中读取- 鉴于您的卷不是
external
,可以安全地假设只有同一堆栈中的另一个容器可以使用它 - 一些关于 Docker 的逻辑和经验可以让我们快速回到前一点,但即使对于经验不足的 Docker 用户,您的评论也给出了明确的指示,您的注释是代码的一部分 ;)
您还可以使用 php 图像
中的静态副本制作自定义 nginx 图像这里是 nginx 的 Dockerfile
FROM my-service:latest AS src-files
FROM nginx
COPY --from=src-files /path-to-static-in-my-service-image /path-to-static-in-nginx
这将允许您不使用带有源代码的卷
也可以在 Dockerfile 中使用环境变量中的 TAG
FROM my-service:${TAG} AS src-files
...
这取决于您设置的用例。如果它仅适用于本地开发人员,或者如果您想要在生产环境中使用同样的东西。在开发人员中,手动填充卷或由一个容器为其他容器填充卷可能没问题。
但如果您想要在生产中以相同方式 运行 的东西,您可能需要其他东西。例如,在生产中,我不想将我的代码放在卷中,而是以不可变的方式放在我的映像中,我只需要重新部署它。
对我来说,卷不是用于存储应用程序代码,而是用于存储缓存、用户上传内容等数据。我们希望在部署之间保留一些东西。
所以,如果我们想要 2 个具有相同文件的图像而不在一个卷中,我将使用应用程序代码和静态内容构建 2 个图像,一个用于 php,一个用于 nginx。
但是这两个图像的部署通常是不同步的。我们通过先部署 PHP 应用程序然后部署 nginx 应用程序来解决这个问题。在 nginx 上,我们添加了一个配置,它首先尝试从中提供静态内容,如果该文件不存在,则向 PHP.
询问对于开发环境,我们将重用相同的图像,但使用卷将当前代码挂载到容器内(主机绑定挂载)。
但在某些情况下,绑定挂载可能会出现一些问题: - 在 Mac 上,文件共享速度很慢,但在 Edge 频道 (2.3.1.0) 中使用最新版本的 Docker 桌面应该会更好 - 在 Windows 上,文件共享也很慢 - 在 Linux 上,我们需要注意容器内使用的文件权限和用户
如果您尝试使用卷解决方案解决 one/many 个问题,我们可以找到一些解决方案。例如,在 Mac 上,我将首先尝试 docker 的 Edge 版本,在 Windows 上,如果可能,我将使用 WSL2 并且 Docker 设置为使用 WSL2 后端。