Docker撰写共享环境变量

时间:2017-04-16 18:58:52

标签: docker environment-variables containers docker-compose

搬运工-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失败了,因为它正在从数据库中查找环境变量,

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

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

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

2 个答案:

答案 0 :(得分:3)

关于这一点的一些想法:

  • 相对弃用链接,支持基于DNS的服务发现。您仍然希望使用depends_on来维护启动顺序。

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

  • 由于我建议不要进行链接,因此在网络上以相同名称输入的两个数据库的良好替代是网络别名。

  • 我假设您定义了两个这样的数据库来映射到单独的卷/文件系统或约束到单独的主机等。否则,扩展实例将允许您进行单一定义。

结果如下:

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

答案 1 :(得分:0)

我认为你理解docker-compose.yml文件的工作原理是错误的。

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

此外,当您使用链接时,无需添加depends_on部分,链接会隐式包含它。此外,condition已从文件格式的第3版中删除。

关于你的问题,这是我在链接容器时通常做的事情。

首先,在您的应用程序中,根据您的环境变量对连接字符串进行参数化。根据您的编程语言/工具,这可能很简单。为简单起见,假设您可以像这样参数化连接字符串(例如来自Play Framework):

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

在Play Framework中,这意味着应该从环境变量中读取DB_HOSTDB_PORTDB_NAME。您的框架可能具有相似或替代的构造。

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

version: '2.1'
services:
  db1:
    [...]
    healthcheck: ..

  service1:
    [...]
    links:
      - db1:database1

然而,这还不够。如果您编写了database1而不是DB_HOST并且在应用程序配置中硬编码了端口和数据库名称,那就是这样。这也是可以接受的,但我喜欢让我的应用程序配置尽可能独立于平台。这就是我设置部分配置以便从环境变量中读取的原因(更不用说,这种方法对Docker很有用:-)。

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

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

version: '2.1'
services:
  db1:
    [...]
    healthcheck: ..

  service1:
    [...]
    links:
      - db1:database1
    environment:
      - DB_HOST: database1
      - DB_PORT: 5432
      - DB_NAME: accounting

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