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

上次更新时间:2020 年 8 月 21 日

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

简短描述

Elastic Beanstalk 环境变量在 Elastic Beanstalk Docker 平台中设置,并可供 Dockerfile 中的最终容器访问。这适用于涉及多个容器的场景(即多阶段构建)。您只能在构建阶段设置 Dockerfile 中的硬编码变量/静态变量。例如,您可以使用“ENV”键来设置静态变量。由于 Dockerfile 中处于早期构建阶段的其他容器无法访问 Elastic Beanstalk 变量,您可以按照在构建阶段设置动态环境变量的解决方法步骤进行操作。

要在构建阶段设置动态环境变量,请使用 SSM 参数 或 Elastic Beanstalk 变量。建议使用 SSM 参数,因为您只需设置一次变量。此外,您可以按照使用 SSM 参数部分描述的步骤来创建和更新 Elastic Beanstalk 变量。

解决方法

注意:以下解决方法假设使用在 Alpine Linux 上安装的 React 应用程序。当然,您可以使用任何其他发行版的软件包管理器来构建容器并安装所需的软件包。

使用 SSM 参数

重要提示:要允许实例检索 SSM 参数,请确认您的实例配置文件具有 ssm:GetParameters 权限。

1.    创建 SSM 参数。例如,您可以使用 AWS 命令行界面 (AWS CLI) 创建 SSM 参数:

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 export REGION=$(curl -s 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 变量

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 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 . ./
## 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

这篇文章对您有帮助吗?


您是否需要账单或技术支持?