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
部分中的两个链接db1
和db2
。 分号后的部分是别名。 你不必使用它。
另外,当你使用链接时,不需要添加depends_on
部分,链接包含它隐含。 此外,该condition
从文件格式的版本3中删除。
至于你的问题,这是我通常在连接容器时所做的。
首先,在您的应用程序中,根据您的环境variables设置连接string参数。 根据你的编程语言/工具,这可能是简单的或不是。 为了简单起见,想象一下,您可以参数化连接string(例如Play Framework):
connectionString=jdbc:postgresql://${DB_HOST}:${DB_PORT}/{DB_NAME}
在Play Framework中,这意味着应该从环境variables中读取DB_HOST
, DB_PORT
和DB_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
您可以对多个数据库使用相同的方法。