Docker组合共享环境variables

泊坞窗,compose.yml

version: '2.1' services: db1: [...] healthcheck: .. db2: [...] healthcheck: .. service1: [...] links: - db1:dbname - db2:dbname depends_on: db1: condition: service_healthy db2: condition: service_healthy 

但是,主服务service1因为正在从数据库中查找环境variables而失败,

 ${env.DBNAME_PORT_3306_TCP_ADDR} ${env.DBNAME_PORT_3306_TCP_PORT} ${env.DBNAME_ENV_MYSQL_DATABASE} 

我知道撰写文档状态“环境variables不再是连接到链接服务的推荐方法,只有在使用旧版本1撰写文件格式时才会填充环境variables。 但如果没有他们,我可以在这里做很多事情。

这里最好的做法是什么? 谢谢!

关于这一点的一些想法:

  • 链接相对不赞成使用基于DNS的服务发现。 您仍然需要使用depends_on来维护启动顺序。

  • docker stack deploy环境variables只能在有限的方面消失。 由于您使用的是2.1版本,因此很明显您使用的是docker-compose 。 即使如此, docker stack deploy的部分环境variables也是能够将环境variables从主机扩展到yml文件,而不是从yml文件扩展到容器。 即使没有扩展,你可以使用docker-compose config作为预处理器来生成一个可以与docker stack deploy一起使用的yml。 这是一个很长的说法,不要因为这个限制而改变你的devise。

  • 由于我build议不要链接,所以在networking上同名的两个数据库的替代是一个networking别名。

  • 我假设你定义了两个这样的数据库映射到单独的卷/文件系统或限制为单独的主机等。否则,缩放实例将让你做一个单一的定义。

结果如下所示:

 version: '2.1' services: db1: [...] healthcheck: .. networks: default: aliases: - dbname db2: [...] healthcheck: .. networks: default: aliases: - dbname service1: [...] environment: - DBNAME_PORT_3306_TCP_ADDR: dbname - DBNAME_PORT_3306_TCP_PORT: 3306 - DBNAME_ENV_MYSQL_DATABASE: yourdb depends_on: db1: condition: service_healthy db2: condition: service_healthy 

我想你对理解docker-compose.yml文件是如何工作有些问题。

我看到的第一个问题是,您已经将相同的别名dbname添加到service1服务的links部分中的两个链接db1db2 。 分号后的部分是别名。 你不必使用它。

另外,当你使用链接时,不需要添加depends_on部分,链接包含它隐含。 此外,该condition从文件格式的版本3中删除。

至于你的问题,这是我通常在连接容器时所做的。

首先,在您的应用程序中,根据您的环境variables设置连接string参数。 根据你的编程语言/工具,这可能是简单的或不是。 为了简单起见,想象一下,您可以参数化连接string(例如Play Framework):

connectionString=jdbc:postgresql://${DB_HOST}:${DB_PORT}/{DB_NAME}

在Play Framework中,这意味着应该从环境variables中读取DB_HOSTDB_PORTDB_NAME 。 你的框架可能有相似或可选的结构。

现在,正确地链接docker-compose文件中的服务

 version: '2.1' services: db1: [...] healthcheck: .. service1: [...] links: - db1:database1 

但是,这还不够。 这将是如果您已经写入database1而不是DB_HOST ,并在应用程序configuration中硬编码端口和数据库名称。 这也是可以接受的,但我喜欢使我的应用程序configuration尽可能独立于平台。 这就是为什么我设置configuration的一部分从环境variables读取(更不用说,这种方法与Docker :-)很好。

一些环境variables采用链接别名或链接本身的值,如DB_HOST: database1 。 这可能看起来多余,但保持应用程序与部署分离,恕我直言。

最后,我的服务看起来像这样:

 version: '2.1' services: db1: [...] healthcheck: .. service1: [...] links: - db1:database1 environment: - DB_HOST: database1 - DB_PORT: 5432 - DB_NAME: accounting 

您可以对多个数据库使用相同的方法。