如何在 Elastic Beanstalk 中为 Docker 多阶段构建设置动态环境变量?

3 分钟阅读
0

我想在 AWS Elastic Beanstalk 中为 Docker 多阶段构建设置动态环境变量。

简述

您只能在构建阶段在 Dockerfile 中设置硬编码变量或静态变量。例如,使用 ENV 键设置静态变量。您在早期阶段构建的 Dockerfile 中的其他容器无法访问 Elastic Beanstalk 变量。要在多阶段构建期间设置动态环境变量,请使用 AWS Systems Manager AWS::SSM::Parameter 资源或 Elastic Beanstalk 变量。由于只需要设置一次变量,因此最佳实践是使用 SSM 参数。

**注意:**如果您在运行 AWS 命令行界面(AWS CLI)命令时收到错误,请参阅排查 AWS CLI 错误。此外,请确保您使用的是最新的 AWS CLI 版本

解决方案

**注意:**在以下示例中,在 Alpine Linux 上安装了一个 React 应用程序。您可以使用任何分发程序包管理器来构建容器并安装所需的软件包。

使用 SSM 参数

**注意:**要允许 Amazon Elastic Compute Cloud(Amazon EC2)Linux 实例获取 SSM 参数,您的 EC2 Linux 实例配置文件必须具有 ssm:GetParameters 权限。

1.使用 Systems Manager 控制台创建 SSM 参数。或者,运行 AWS CLI 命令 put-parameter

aws ssm put-parameter --name PRODURL_SSM --value http://myproddomain.com --type String

2.使用以下 Dockerfile 来部署您的应用程序。Dockerfile 获取临时容器或构建容器内的 SSM 参数值,然后在构建过程中导出该变量。

# Build environment
FROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm install react-scripts@3.4.1
COPY . ./
## Install the required packages for awscli, curl, and jq. ##
RUN apk -v --no-cache add \
        py-pip \
        curl \
        jq \
        && \
        pip install awscli --upgrade --user
## Export the region dynamically retrieving it from the instance metadata, and then retrieve the SSM parameter value using awscli. Then, place the parameter in a text file, and export the variable using the value from the text file. Finally, run the build. ##
RUN TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && export REGION=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region)&& /root/.local/bin/aws ssm get-parameters --names PRODURL_SSM --region $REGION | grep Value | cut -d '"' -f4 >> /tmp/SSMParameter.txt && export DYNAMIC_SSM_VAR=$(cat /tmp/SSMParameter.txt) && npm run build
# Production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
## Copy the text file that has the SSM parameter value from the build container to the production container to confirm the variable was retrieved successfully. ##COPY --from=build /tmp/SSMParameter.txt /tmp
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

3.要确认部署是否成功,请检查您复制的文件是否包含 SSM 参数变量的值。

示例:

# docker exec -it <Container-Id> sh# cat /tmp/SSMParameter.txt
http://myproddomain.com

使用 Elastic Beanstalk 变量

**注意:**要允许实例配置文件进入环境,您的实例配置文件必须具有 elasticbeanstalk:DescribeConfigurationSettings AWS Identity and Access Management(IAM)权限。

1.将 Elastic Beanstalk 命令行界面(EB CLI)使用的 config.yml 文件复制到项目根目录。

示例:

cp .elasticbeanstalk/config.yml .

2.要使用 EB CLI 设置 Elastic Beanstalk 变量,请运行以下命令更新现有环境或部署到现有环境:

eb setenv PRODURL_EB=http://myproddomain.com

3.要创建新的 Elastic Beanstalk 环境,请在项目根目录的 config.yml 文件中添加新的环境名称。然后,运行以下命令:

eb create --envvars PRODURL_EB=http://myproddomain.com

4.使用以下 Dockerfile 来部署您的应用程序。Dockerfile 获取构建容器内的 Elastic Beanstalk 变量的值,然后在构建过程中导出该变量。

# Build environmentFROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm install react-scripts@3.4.1
COPY . ./
## Create an .elasticbeanstalk directory to place the config.yml file in, so that the eb cli can interact with the Elastic Beanstalk environment. ##
RUN mkdir .elasticbeanstalk
## Copy config.yml to /app/.elasticbeanstalk inside the build container as it will be used by eb cli ##
COPY config.yml /app/.elasticbeanstalk
## Install required packages for awsebcli ##
RUN apk -v --no-cache add \
        gcc \
        musl-dev \
        openssl \
        openssl-dev \
        make \
        py-pip \
        libffi-dev \
        python \
        python-dev \
        && \
        pip install awsebcli --upgrade --user
## Retrieve the Elastic Beanstalk variable using awsebcli and place it in a text file. Then, export the desired variable using the value from the text file, then run the build. ##
RUN /root/.local/bin/eb printenv | grep PRODURL_EB | awk '{print $3}' >> /tmp/EBVar.txt && export DYNAMIC_EB_VAR=$(cat /tmp/EBVar.txt) && npm run build
# Production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
## Copy the text file that has the Elastic Beanstalk variable value from the build container to the production container to confirm the variable was retrieved successfully ##
COPY --from=build /tmp/EBVar.txt /tmp
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

5.要确认部署是否奏效,请检查您复制的文件是否包含 Elastic Beanstalk 变量的值。

# docker exec -it <Container-Id> sh# cat /tmp/EBVar.txt
http://myproddomain.com

相关信息

实例身份文档

get-parameters

AWS 官方
AWS 官方已更新 6 个月前