向 Docker 个容器提供配置文件的推荐方法

Recommended way to provide configuration files to Docker containers

我正在将我们的 Web 应用程序移动到 docker-compose 部署(Django、DRF、AngularJS)。

Docker 现在看起来不错,一切进展顺利。

我想:

我已经设法使用环境变量和 docker-compose 从 Django settings.py 文件中读取的秘密并且它有效。缺点是环境变量仅限于简单的字符串,在发送 Python 列表、字典等时可能会带来一些转义挑战。我们还必须定义和维护很多环境变量,因为我们的 Web 应用程序安装在很多地方而且它是高度可配置的。

在前端 (AngularJS) 我们有两个 constants.js 文件和 nginx conf. 我在 Docker 文件中使用了 CMD ["/start.sh"] 并且有一些 sed 命令。 但这看起来真的很 hackish,这也意味着我们必须定义和维护相当多的环境变量。

  1. Docker 卷是用于这些配置文件的好主意吗?

  2. "volume file" 这样的东西是否真的存在 () 或者它实际上是一个绑定安装?绑定挂载不太值得推荐,因为它们取决于主机上的文件系统和文件路径。

Volumes documentation 简要提到了文件:"path where the file or directory are mounted in the container",但没有详细介绍。

我们的网络应用现在有简单的配置文件:

和:

  1. 我想避免将这些文件移动到可以挂载的专用目录。

  2. 你能给我一个示例 docker-compose.yml 的单个文件卷(不是绑定安装).

谢谢

如果您不能使用环境变量,那么您应该使用绑定安装。如果您使用命名卷,则无法访问单个文件,也无法直接编辑配置文件。

命名卷始终是整个目录,不能直接从主机访问。没有 "volume file" 这样的东西(你的 linked 问题完全是关于绑定挂载的,有些使用命名卷语法)并且没有办法从命名卷挂载单个文件。

较新的 Docker 有几种不同的绑定安装语法(在 Compose 中,short and long volumes: 服务配置,或创建 type: bind 命名卷)。这些基本上都是等价的,你 link 的问题中的许多答案都涉及使命名卷模拟绑定安装。

Docker Compose 支持相对路径,因此对于绑定挂载的主机路径不可跨系统移植的问题要少得多。 docker-compose.yml 文件的基本片段可能包括:

services:
  app:
    build: django
    volumes:
      - ./config/django-settings.py:/app/settings.py

在此示例中,我建议使用包含配置文件的(部署时)config 目录,但这是一个任意选择;如果你想从应用程序源代码树中绑定挂载 ./django/settings.py 到图像中的内容上以便能够直接编辑它,那也是一个有效的选择。您可以将此树签入源代码管理,无论签出到哪里,它仍然有效。

如果您使用带有完整 GNU 工具集(Ubuntu,而不是 Alpine)的基础镜像,那么您的容器入口点脚本也可以使用 envsubst 作为一个非常轻量级的模板工具(它用等效的环境变量替换 $VARIABLE 引用),这将帮助您支持 "many options" 情况但不支持 "dict-type options" 情况。

一般来说,我建议在两种情况下绑定挂载,也许还有第三种情况:配置文件(操作员需要直接编辑它们),日志文件(操作员需要直接读取它们),也许用于持久数据存储(您现有的备份解决方案将在不经修改的情况下工作;但不适用于速度非常慢的 MacOS)。命名卷可以很好地匹配持久数据的情况,并且更好地匹配您在集群环境(Swarm、Kubernetes)中使用但不能直接访问的内容。