运行 app 处于 swarm mode 时应该在哪里定义 ENV 变量?

Where should ENV variables be defined when running app in a swarm mode?

在前端的 Dockerfile:

中定义了一个环境变量
ENV APP_BACKEND_URL=http://localhost/

并在 Docker 构建前端图像时读取,并且在 app.yml 中定义了相同的变量:

services:
  backend:
    [...]

  frontend:
    [...]
    environment:
      APP_BACKEND_URL: 'backend'

上面的配置文件作为 docker stack deploy -c app.yml appli.

的参数给出

我想知道哪个值最终被设置为最后一个值:来自 Dockerfile(图像中内置)的值,或来自 app.yml 文件的另一个值被读取最后的。在使用 Docker Compose 操作的情况下,Dockerfiledocker-compose.yml 中出现的所有变量都从 Dockerfile 中获得值; docker-compose.yml 值被忽略。它在 Docker Swarm 的情况下是否同样有效?

我问这个问题是因为最后我的前端没有读取变量的任何值(控制台日志说 undefined 值)我想知道如何提供该值accessible/readable 由应用程序。

如果在 Docker 文件中使用变量,则只有 Docker 文件定义有任何作用。

FROM busybox
ENV FOO=bar
RUN echo "$FOO" > /a-file.txt
CMD cat /a-file.txt
docker build -t an-image .
docker run -e FOO=quux --rm an-image
# prints "bar" from the Dockerfile definition

但是,当应用程序 运行s 时,Compose 定义将优先。

FROM busybox
ENV FOO=bar
CMD echo FOO is "$FOO"
docker build -t another-image .
docker run --rm -e FOO=quux another-image
# prints "FOO is quux" from the runtime definition

我不希望这在 Swarm 中有不同的工作方式。

my frontend doesn't read any value of the variable (console logs say about undefined value)

对于许多前端应用程序,您可以 运行 容器中的节点服务器,但它实际上将 Javascript 代码提供给浏览器 运行,并且应用程序实际上 运行s 在浏览器中。浏览器不在 Docker 中(甚至不一定在同一主机上),因此它不能使用 Docker 网络、仅在服务器上定义的环境变量等。

如果您使用 webpack 构建应用程序,它的 EnvironmentPlugin 会导致定义 process.env 个变量,但这通常是 运行 当您构建应用程序的图像时而不是在你上菜的时候。