这是我关于这个特定问题的第二篇文章。我已经删除了那个问题,因为我找到了一种更好的方法来解释我到底想做什么。
本质上,我想将命令行参数传递给 docker-compose up
并将它们设置为我的 Vue.js Web 应用程序中的环境变量。目标是能够更改环境变量而无需每次都重建容器。
我遇到了几个问题。这是我的 docker 文件:
用于 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
SSH 进入客户端容器时,VUE_APP_BAR 变量的值是“BAR”。但是变量没有存储在process.env
中我的 Vue 应用程序中的对象。 Node 和它的环境变量似乎发生了一些奇怪的事情。这就像它忽略了容器环境。无论如何,我是否可以访问我的 Vue.js 应用程序中 docker-compose.yml 中设置的容器级变量?此外,无论如何将这些变量作为参数传递给
docker-compose up
?如果您需要任何说明/更多信息,请告诉我。
最佳答案
所以我想出了如何以一种非常适合我的用例的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 脚本。打开它,这就是我的:entrypoint.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 启动之前运行我们刚刚创建的入口点脚本。所以就在
CMD ["nginx", "-g", "daemon off;"]
之前在您的 Dockerfile 行中,添加以下行:VueJS Dockerfile
# 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
, serverURL
我们一开始在 JS 文件中设置的常量将被替换为您在 docker-compose 命令中提供的任何内容。最终开始工作很痛苦,但我希望这有助于任何面临类似问题的人。最棒的是,您可以根据需要添加任意数量的环境变量,只需在 entrypoint.sh 文件中添加更多行并在 Vue.js 应用程序和 docker-compose 文件中定义它们即可。我使用的一些方法是根据您是在本地运行还是托管在云中为 USPS API 提供不同的端点,根据实例是在生产中运行还是在开发中运行提供不同的 Maps API key 等。等等。我真的希望这对某人有所帮助,如果有人有任何问题,请告诉我,我希望能有所帮助。
关于docker - 使用 docker-compose 在运行时将环境变量传递给 Vue.js 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59722631/