问题原因
Vue.js应用程序依赖 .env
文件来指定应用程序的设置。在我们打包的时候,类似于hardcode方式,把这些环境变量给替换掉。
一旦应用程序被打包并分发到容器(如Docker)中,就没有办法在容器启动时动态设置应用程序的设置。原因是Vue.js应用程序实际上是在客户端运行的,只是通过Web服务器分发。如果每个环境有不同的应用设置,就需要为每个环境提供一个特定的容器。不同环境下的应用设置可能是应用的后端API端点的URL,或根据环境变量进行适当的逻辑调整
常见的解决办法
-
根据域名去做判断
-
初始化的时候,先请求后端的接口,让其返回环境变量
以上两种是市面上比较常见的做法。
方法一并不适用于我们,从我入职到现在不足一年,域名已经换了2次,每个项目都有6-7个环境,一旦换域名少说得花上2个小时去完成重新构建部署,很是麻烦
方法二在团队内有点不好推动,具体原因就不说了。
因此我只能是找新的方式来解决
特别的解决办法
在容器的启动过程中生成config.js
文件。在容器启动过程中,会执行一个小的shell脚本,检查所需的系统环境变量是否存在,如果存在,就把它们写到config.js文件中。
大致逻辑如下:
image.png操作
- 在你的Vue.js应用程序中/public文件夹下创建一个新文件config.js,在这里定义你的环境变量
// will be overwritten during container startup
window.APPLICATION_SETTING_API_ENDPOINT_URL = null;
window.APPLICATION_SETTING_2 = null;
window.APPLICATION_SETTING_N = null;
- 在 public/index.html 中引入 config.js 文件
<!DOCTYPE html>
<html lang="">
<head>
<!-- ... -->
<script src="config.js" type="text/javascript"></script>
</head>
<body>
<!-- ... -->
</html>
- 创建一个
create_config_js.sh
文件,在Dockerfile
同级目录
#!/bin/bash
SRC=${1:-}
if [ -z $SRC ] || [ ! -e "$SRC" ]; then
echo "Source file '$SRC' does not exist"
exit 1
fi
OUTPUT="// generated"
while IFS="" read -r line || [ -n "$line" ]; do
use_line=$line
if [[ $line =~ "window." ]]; then
ENVIRONMENT_VARIABLE_NAME=`echo $line | sed -re 's/window\.(.*)\s+\=(.*);/\1/g'`
value=${!ENVIRONMENT_VARIABLE_NAME}
if [[ ${value} && ${value-x} ]]; then
use_line="window.$ENVIRONMENT_VARIABLE_NAME = '$value';"
fi
fi
OUTPUT="$OUTPUT\n$use_line"
done <$SRC
echo -en $"$OUTPUT"
- 修改你的dockerfile
WORKDIR /
COPY create_config_js.sh .
RUN chmod +x create_config_js.sh
COPY docker_entrypoint.sh .
RUN chmod +x docker_entrypoint.sh
EXPOSE 80
CMD ["/bin/sh", "docker_entrypoint.sh"]
- 更新 docker_entrypoint.sh 以执行配置生成
SRC=/usr/share/nginx/html/public/config.js
# quoting is required to keep line breaks
NEW_CONFIG="$(./create_config_js.sh $SRC)"
echo "$NEW_CONFIG" > $SRC
# start webserver, e.g. apache or nginx
nginx -g "daemon off;"
网友评论