1 前言
上一周的工作中,有这样一个需求,在不同的环境下(dev, test, beta, release)传入不同的值,首先是以业务为首要目标,因此,博主最初的做法是通过判断不同的hostname来传入不同的值,这种做法简单快捷,但是存在以下两个缺点: 1)hostname更改时需要修改代码,当多个服务均存在这种需求时,工作量就出来了 2)服务不解耦,需要手动调整 3)略显low,并且代码看着感觉很不舒服 因此,博主今天决定做优化改善,通过获取 docker 的环境变量来获取当前的运行环境,一劳永逸,博主以下的最小示例采用的Vue,也同样适用于React Angular JQ
因为其中原理需要在项目实现完成才更好说明,因此,博主首先将实现的过程讲解出来,也许会有很多不明白的地方,所以,实现完成后,博主会逐一解释。
2 最小完整实现
2.1 创建最小vue项目
既然要最小最快捷,因此直接使用vue脚手架拉去一个项目即可
mkdir Get_Docker_ENV
# 创建Get_Docker_ENV文件夹
cd Get_Docker_ENV
# 进入Get_Docker_ENV文件夹
vue create vue_app
# 利用vue脚手架创建vue_app项目
等待脚手架自动拉取项目,拉取完成即可,取完成的项目目录如下。
拉在 main.js 中添加如下代码,具体为什么要添加这些代码,项目实践完成博主会详解的。
const ENV_NOW = document.querySelector("html").getAttribute("env_now");
// 获取html标签的env_now属性值
if (ENV_NOW) {
Vue.prototype.$ENV_NOW = `${ENV_NOW}`;
// 将$ENV_NOW设置为vue全局变量
}
在app.vue中的export default添加如下代码
created() {
console.log(this.$ENV_NOW);
}
// 打印出 this.$ENV_NOW ,主要是为测试能否获取到这个变量
修改完成后打包构建项目
yarn run build
# 构建项目
此时会生成一个 dist 文件,也就是项目构建完成后的文件
2.2 利用dockerfile构建镜像和运行容器
在当前目录下进行
vim dockerfile
# 创建并打开dockerfile
此时编辑dockerfile文件
FROM nginx
# 以nginx为基础镜像
COPY ./vue_app/dist/ /usr/share/nginx/html/
# 复制 ./vue_app/dist/ 到 /usr/share/nginx/html/
# /usr/share/nginx/html/为 nginx 默认的启动文件夹
CMD ["/bin/bash", "-c", "sed -i \"s@<html@<html env_now=\"$ENV\"@\" /usr/share/nginx/html/index.html; nginx -g \"daemon off;\""]
# 启动命令
# "sed -i \"s@<html@<html env_now=\"$ENV\"@\" /usr/share/nginx/html/index.html;"
# 这行代码是指将/usr/share/nginx/html/index.html中的<html 替换成 <html env_now=\"$ENV\"
# 也就是说,当docker run 时,index.html中的html标签就添加了这样一个属性
运行时,只要在docker run时将ENV这个变量传进便可
2.3 创建镜像和运行容器
Docker build -t nginx_vue .
docker build -t nginx_vue .
# 根据dockerfile来创建nginx_vue镜像
docker run -p 6090:80 -e ENV=’now_env’ -d -t nginx_vue
# 以nginx_vue为镜像运行容器并传入环境变量ENV=’now_env’
2.4 运行测试
此时便可以在本地访问 localhost:6090 就可以看到运行的项目 ,并且可以在控制台看到打印出 now_env 了,也就是项目拿到这个变量了; 同时,检查 Elements 会看到,此时的 html 中动态地添加了这样一个属性。
3 详解
其实相信看到这里,大部分同学已经理解实践的过程了,博主在这里梳理一下,
- 最终的实现是在构建好的 index.html 的 html 标签中添加了一个属性,通过动态地给这个属性传值,实现获取docker的环境变量
- 在 html 中提前获取这个值并复制到vue全局中,这样 vue 项目中便可以拿到了
因此,这种实现方式不局限于框架,Vue React Angular 均可以使用。
4 总结
博主实现后实际测试过,完全没有问题,但是,但是博主晚上一直在思考,这样做虽然比判断 hotsname 好很多,完全解决了hostname带来的缺陷,但是,修改 html, 获取 html 的属性值,始终有种不是很正式的样子,如果能够动态的直接传一个变量到项目中,那就好了,但是这种方式博主始终未能实现,主要原因如下:
- docker 镜像是项目已经构建好了,也就是说此时的项目已经是构建好了的,动态传值难
写着写着,博主似乎有了思路,就是把项目不构建,在构建镜像时再启动项目构建然后传值。先这样试试,有了新进展再记录
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!