前端容器化实践( 三 )

我们选择适用于国内环境的方案的命令进行创建,可以看到多了name为 mybuilder-cn 的实例
docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:masterdocker buildx lsNAME/NODEDRIVER/ENDPOINTSTATUSBUILDKITPLATFORMSmybuilder-cn *docker-containermybuilder-cn0 desktop-linuxinactivedefaultdockerdefaultdefaultrunningv0.11.7-0.20230525183624-798ad6b0ce9f linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6desktop-linuxdockerdesktop-linux desktop-linuxrunningv0.11.7-0.20230525183624-798ad6b0ce9f linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6$ docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t myusername/hello . --push# 查看镜像信息$ docker buildx imagetools inspect myusername/hello在不同架构运行该镜像,可以得到该架构的信息 。
$ docker run -it --rm myusername/hello5.如何利用容器化做前端环境变量注入

  • 前端虽然对环境变量的需求场景不多,但是基本的api baseURL, appName, env这些是需要的
  • 如果是微前端的场景,那么需要的其他网站url都是环境变量,还挺多的
  • 依稀记得刚入行时,前端区分测试环境,线上环境就是直接通过域名进行判断,例如: inlcudes(url, ".com")?, 然后得到isProd去获取项目中配置的不同环境的变量,这样显得很low
  • 后面出了vue, react这种框架,可以在npm run dev时候指明--prod,然后通过process拿到isProd,去获取对应配置
  • 现在可以直接通过容器化注入环境变量,然后使用nginx将容器中的环境变量注入前端项目html的meta标签content中, 然后从meta标签获取变量
  • 如果是monorepo项目,npm run build的时候,Dockerfile里面也需要通过容器中的环境变量获取打包哪个项目
  • 测试环境通过ts文件配置环境变量,然后项目启动时组合这些环境变量信息,生成config default.yml, ci/cd时k8s自动将default.yml中配置的环境变量写入容器中
  • 线上环境直接提供UI页面配置环境变量,然后调用api,后端api通过k8s将变量写入容器中
  • 如何通过k8s读取配置的环境变量并写入容器中且听下回分解
下面贴一段生产场景下的Dockerfile示例代码(公司应该不会砍我吧!),这里省略k8s如何往容器中注入环境变量,只考虑如何从容器中读取环境变量(假设环境变量已经注入容器中)
FROM --platform=${BUILDPLATFORM} hub-dev.rockontrol.com/rk-infrav2/docker.io/library/node:17-bullseye as builderWORKDIR /srcCOPY ./ ./ARG APPARG ENVARG PROJECT_GROUPARG PROJECT_NAMEARG PROJECT_VERSIONARG YARN_NPM_REGISTRY_SERVERRUN npm install -g --registry=${YARN_NPM_REGISTRY_SERVER} pnpmRUN pnpm --registry=${YARN_NPM_REGISTRY_SERVER} installRUN PROJECT_GROUP=${PROJECT_GROUP} PROJECT_VERSION=${PROJECT_VERSION}npx devkit build --prod ${APP} ${ENV}FROM hub-dev.rockontrol.com/rk-infrav2/ghcr.io/zboyco/webrunner:0.0.7ARG PROJECT_NAMECOPY --from=builder /src/public/${PROJECT_NAME} /app下面贴一段nginx如何将环境变量写入html中
#!/bin/sh# This script is used to start the application# 初始化一个字符串,用于存储拼接后的值app_config="${APP_CONFIG}"ext_config=""# 遍历所有环境变量for var in $(env | cut -d= -f1); do# 检查变量是否以 "APP_CONFIG__" 开头if [ "$(echo "$var" | grep '^APP_CONFIG__')" ]; then# 去除变量名前缀 "APP_CONFIG__"trimmed_var=$(echo "$var" | sed 's/^APP_CONFIG__//')# 使用 eval 来获取变量值并拼接到字符串中value=https://www.isolves.com/it/cxkf/rongqi/2023-09-08/$(eval echo "$$var")app_config="${app_config},${trimmed_var}=${value}"fidone# 去掉起始的逗号export app_config=$(echo "$app_config" | sed 's/^,//')# 解析app_config变量# 以,分割 app_configIFS=","set -- $app_config# 遍历数组for config in "$@"; do# 以等号分剥数组IFS="="set -- $config# 将单个环境变量单独注入ext_config="${ext_config}sub_filter '__$1__' '$2';n"echo "$1: $2"done# Install envsubstecho "Installing envsubst"# 将扩展变量替换到 conf.template 中sed "s@__EXTENT_CONFIG__@${ext_config}@g" /etc/nginx/conf.d/conf-base.template > /etc/nginx/conf.d/conf.template envsubst '${PROJECT_VERSION} ${ENV} ${app_config}' < /etc/nginx/conf.d/conf.template > /etc/nginx/conf.d/default.conf# Start nginxecho "Starting nginx"nginx -g 'daemon off;'


推荐阅读