如何向Dockerfile传入动态变量适配Angular/Express应用K8s部署?
实现动态环境的Angular/Express应用构建与部署流程
下面分步骤实现你要的需求:通过带参数的脚本动态切换dev/prod环境,完成镜像构建、推送ECR并更新K8s部署。
1. 修改Dockerfile支持动态运行命令
把原来固定的CMD npm run prod改成支持动态指定环境的方式,推荐两种方案:
方案A:环境变量控制(灵活度更高)
这种方式允许你在构建或运行时指定环境变量,默认用prod:
# 设置默认运行环境为prod ENV APP_ENV=prod # 用shell格式解析环境变量,执行对应npm脚本 CMD npm run $APP_ENV
方案B:ENTRYPOINT+CMD组合
固定npm run命令,通过CMD指定默认脚本,运行时可覆盖:
ENTRYPOINT ["npm", "run"] # 默认执行prod脚本,启动容器时可传参数替换 CMD ["prod"]
2. 编写构建部署脚本
创建build_and_deploy_app.sh,把所有流程自动化,脚本会校验输入参数,只接受dev或prod:
#!/bin/bash set -euo pipefail # 校验参数合法性 if [[ $# -ne 1 || ($1 != "dev" && $1 != "prod") ]]; then echo "用法: $0 [dev|prod]" exit 1 fi ENV=$1 # 替换为你的ECR仓库完整URI(比如123456789012.dkr.ecr.us-east-1.amazonaws.com/your-app) ECR_REPO="你的ECR仓库URI" IMAGE_TAG="${ECR_REPO}:${ENV}" # 替换为你的K8s部署名称和容器名称 K8S_DEPLOY="your-app-deployment" K8S_CONTAINER="your-app" # 替换为你的AWS区域 AWS_REGION="us-east-1" # 1. 构建镜像 echo "开始构建镜像: $IMAGE_TAG" # 如果用方案A,需要传递build-arg(可选,也可以在K8s里设置环境变量) docker build --build-arg APP_ENV=$ENV -t $IMAGE_TAG . # 用方案B的话不需要build-arg,注释上面一行,打开下面一行 # docker build -t $IMAGE_TAG . # 2. 登录ECR(需要提前配置好AWS CLI权限) echo "登录ECR仓库..." aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ECR_REPO # 3. 推送镜像到ECR echo "推送镜像到ECR..." docker push $IMAGE_TAG # 4. 更新K8s部署 echo "更新K8s部署..." # 直接更新镜像,快速生效 kubectl set image deployment/$K8S_DEPLOY $K8S_CONTAINER=$IMAGE_TAG # 如果你用的是模板化的部署文件,也可以用sed替换后apply # sed "s/{{ENV}}/$ENV/g" k8s-deployment.yaml | kubectl apply -f -
给脚本添加执行权限:
chmod +x build_and_deploy_app.sh
3. 调整K8s部署配置
根据你选的Dockerfile方案,修改K8s部署文件:
对应方案A(环境变量)
在容器配置中添加环境变量(如果需要在K8s层覆盖镜像默认值):
apiVersion: apps/v1 kind: Deployment metadata: name: your-app-deployment spec: replicas: 3 selector: matchLabels: app: your-app template: metadata: labels: app: your-app spec: containers: - name: your-app image: 你的ECR仓库URI:dev # 脚本会自动替换这个标签 env: - name: APP_ENV value: "dev" # 与脚本参数对应,也可通过脚本动态替换 ports: - containerPort: 3000
对应方案B(ENTRYPOINT+CMD)
在容器配置中添加args字段,覆盖Dockerfile的默认CMD:
apiVersion: apps/v1 kind: Deployment metadata: name: your-app-deployment spec: replicas: 3 selector: matchLabels: app: your-app template: metadata: labels: app: your-app spec: containers: - name: your-app image: 你的ECR仓库URI:dev # 脚本会自动替换这个标签 args: ["dev"] # 传递给ENTRYPOINT,执行npm run dev ports: - containerPort: 3000
4. 执行部署
直接运行脚本传入环境参数即可:
# 部署dev环境 ./build_and_deploy_app.sh dev # 部署prod环境 ./build_and_deploy_app.sh prod
内容的提问来源于stack exchange,提问作者Alphie
相关产品推荐
相关产品推荐

