在不同 docker 撰写文件之间共享的命名容器



我见过一些类似的问题,但找不到自己的解决方案。

我有 2 个 docker 撰写文件,我创建了一个命名卷,我目前正在像这样使用它:

app:
...
volumes:
- volume_static:/path/to/container
...
...
volumes:
...
volume_static:
external:
name: static
...
...

在构建过程中,碰巧脚本向该卷添加了一些新文件,但是,以完全相同的方式挂载卷的第二个docker-compose无法访问新数据,我需要重新启动它才能使其工作。

这是正确的方法吗?

我只需要从一个 docker-compose 推送卷中的一些新文件,并直接在第二个 docker-compose 上查看它们(是的,我知道,docker,但说指定 compose 可以更好地了解我的问题是什么(,而无需重新启动和构建服务

这可能吗?

谢谢!

Docker认为命名卷用于保存用户数据,以及其他不属于正常容器生命周期的内容。

如果启动一个具有空卷的容器,则仅在第一次运行它时,Docker 才会将内容从映像加载到卷中。 Docker 没有为此提供更新机制:由于卷可能包含用户数据,因此 Docker 不会通过用更新映像中的内容覆盖文件来破坏它。

这里最好的方法是完全避免共享文件。 如果文件类似于后端应用程序的静态资产,则可以使用后端应用程序的映像名称和标记 (COPY --from=my/backend ...( 将这些文件从后端映像COPY --from到代理映像中。 这完全避免了对卷的需求。

如果确实必须在卷中共享文件,则提供文件的容器需要在启动时负责复制文件本身。 入口点脚本是最简单的位置;它为您提供了一个钩子,可以在容器启动(并且卷存在并已挂载(时但在运行主容器进程之前运行内容。

#!/bin/sh
set -e
# Populate (or update) the shared static tree
cp -r ./app/assets /static
# Now run the image CMD
exec "$@"

使此脚本成为 Dockerfile 中的ENTRYPOINT;它必须使用 JSON 数组语法。 您可以保持CMD不变。 如果您已将解释器和文件名拆分为单独的ENTRYPOINTCMD则可以将它们合并为一个CMD行(无论如何可能都应该如此(。

...
ENTRYPOINT ["entrypoint.sh"]
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

在构建生命周期方面,构建映像时没有任何周围的 Compose 生态系统;它们不知道网络环境、卷、环境变量、绑定挂载;因此,当您重建映像时,您构建一个新的更改映像,但根本不修改卷。 第一次运行整个文件时,由于命名卷为空,因此会填充卷中的内容,但这仅在您第一次运行它时发生。

在 Docker 中,重建映像和重新启动容器是非常常规的,我不会试图避免这种情况。 (这是例行公事,如果需要更改设置,重新运行docker-compose up -d将删除并重新创建现有容器。

最新更新