使用 docker-compose 在运行时将环境变量传递给 Vue.js 应用程序

新手上路,请多包涵

这是我关于这个特定问题的第二篇文章。我已经删除了那个问题,因为我找到了一种更好的方式来解释我到底想做什么。

本质上,我想将命令行参数传递给 docker-compose up 并将它们设置为我的 Vue.js Web 应用程序中的环境变量。目标是能够更改环境变量而无需每次都重建容器。

我遇到了几个问题。这是我的泊坞窗文件:

Vue.js 应用程序的 Dockerfile。

 FROM node:latest as build-stage
WORKDIR /app

# Environment variable.
ENV VUE_APP_FOO=FOO

COPY package*.json ./
RUN npm install
COPY ./ .
RUN npm run build

FROM nginx as production-stage
RUN mkdir /app
COPY --from=build-stage /app/dist /app
COPY nginx.conf /etc/nginx/nginx.conf

VUE_APP_FOO 存储并可通过 Node 的 process.env 反对并似乎在构建时传入。

还有我的 docker-compose.yml:

 version: '3.5'

services:
    ms-sql-server:
        image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu
        ports:
            - "1430:1433"
    api:
        image: # omitted (pulled from url)
        restart: always
        depends_on:
            - ms-sql-server
        environment:
            DBServer: "ms-sql-server"
        ports:
            - "50726:80"
    client:
        image: # omitted(pulled from url)
        restart: always
        environment:
            - VUE_APP_BAR="BAR"
        depends_on:
            - api
        ports:
            - "8080:80"

当我使用 docker exec -it <container_name> /bin/bash 进入客户端容器时,VUE_APP_BAR 变量的值是“BAR”。但是变量没有存储在我的 Vue 应用程序中的 process.env 对象中。 Node 和它的环境变量似乎发生了一些奇怪的事情。这就像它忽略了容器环境。

无论如何,我是否可以访问我的 Vue.js 应用程序中 docker-compose.yml 中设置的容器级变量?此外,无论如何要将这些变量作为参数传递给 docker-compose up 吗?如果您需要任何说明/更多信息,请告诉我。

原文由 jrend 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.1k
2 个回答

所以我想出了如何以一种非常适合我的用例的 hacky 方式来做到这一点。快速回顾一下我想做的事情:能够通过 docker-compose 文件将环境变量传递给 Vue.js 应用程序,以允许不同的团队成员根据他们的分配测试不同的开发 API(如果在本地运行服务器,则为 localhost 、api-dev、api-staging、api-prod)。

第一步是在 VueJS 项目内的 JS 文件中声明变量(它可以在任何地方定义),格式如下:

export const serverURL = 'VUE_APP_SERVER_URL'

关于这个字符串的值的快速说明: 它必须对你的整个项目是完全唯一的。 如果您的应用程序中有任何其他匹配它的字符串或变量名称,它将被替换为我们使用此方法传递的 docker 环境变量。

接下来我们必须转到我们的 docker-compose.yml 并在那里声明我们的环境变量:

docker-compose.yml

 your_vuejs_client:
    build: /path/to/vuejs-app
    restart: always
    environment:
        VUE_APP_SERVER_URL: ${SERVER_URL}
    ports:
        - "8080:80"

现在,当您在终端中运行 docker-compose up 时,您应该看到如下内容: WARNING: The SERVER_URL variable is not set. Defaulting to a blank string.

正确设置 docker-compose 后,我们需要在 VueJS 应用程序中创建一个入口点脚本,以便在通过 nginx 启动应用程序之前运行。为此,导航回您的 VueJS 目录并运行 touch entrypoint.sh 以创建一个空白的 bash 脚本。打开它,这就是我的:

入口点.sh

 #!/bin/sh

ROOT_DIR=/usr/share/nginx/html

echo "Replacing env constants in JS"
for file in $ROOT_DIR/js/app.*.js* $ROOT_DIR/index.html $ROOT_DIR/precache-manifest*.js;
do
  echo "Processing $file ...";

  sed -i 's|VUE_APP_SERVER_URL|'${VUE_APP_SERVER_URL}'|g' $file

done

sed -i 's|VUE_APP_SERVER_URL|'${VUE_APP_SERVER_URL}'|g' $file 此行遍历字符串 ‘VUE_APP_SERVER_URL’ 的整个应用程序,并将其替换为来自 docker-compose.yml 的环境变量。

最后,我们需要向我们的 VueJS 应用程序 Dockerfile 添加一些行,以告诉它运行我们刚刚在 nginx 启动之前创建的入口点脚本。因此,就在 Dockerfile 中的 CMD ["nginx", "-g", "daemon off;"] 行之前,添加以下行:

VueJS 文件

# Copy entrypoint script as /entrypoint.sh
COPY ./entrypoint.sh /entrypoint.sh

# Grant Linux permissions and run entrypoint script
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

之后,运行 docker-compose run -e SERVER_URL=yourserverapi.com/api ,我们一开始在 JS 文件中设置的 serverURL 常量将替换为您在 docker-compose 命令中提供的内容。终于开始工作是一件痛苦的事,但我希望这能帮助任何面临类似麻烦的人。很棒的是,您可以根据需要添加任意数量的环境变量,只需将更多行添加到 entrypoint.sh 文件并在 Vue.js 应用程序和 docker-compose 文件中定义它们。我使用的一些方法为 USPS API 提供不同的端点,具体取决于您是在本地运行还是托管在云中,根据实例是在生产还是开发中运行等提供不同的 Maps API 密钥。等等

我真的希望这可以帮助别人,如果有人有任何问题,请告诉我,希望我能提供一些帮助。

原文由 jrend 发布,翻译遵循 CC BY-SA 4.0 许可协议

客户端应用程序在网络浏览器上运行,但环境变量在服务器上。客户端需要一种从服务器获取环境变量值的方法。

为此,您有多种选择,包括:

  1. 利用 Nginx 为环境变量本身提供服务,使用如下方法之一: nginx:使用环境变量。根据您的需要,这种方法可能更快、更动态或更静态,可能不那么正式和优雅。或者

  2. 实现一个服务器 API(Node.js?)读取环境变量并通过 AJAX 调用将其返回给客户端。这种方法优雅、动态、以 API 为中心。或者

  3. 最后,如果每个部署的每个 nginx 实例的环境变量都是静态的,您可以在部署期间构建 Vue 应用程序的静态资产,并在静态资产中对环境变量进行硬编码。这种方法有点优雅,但确实会用服务器详细信息污染客户端代码,并且有点静态(只能在部署时更改)。

原文由 Will 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题