Docker通过GitHub Actions设置环境变量失效问题排查
问题:环境变量无法传递到Python应用(返回None)
项目部署成功,但Python代码中调用os.getenv('OIDC_CLIENT_SECRET')和os.getenv('DB_PWD')返回None。已确认GitHub Secrets名称正确,Docker构建阶段的echo命令输出***(说明构建参数已传递到builder阶段)。
相关代码片段
Python应用代码
logger.info(f"OIDC SECRET: {os.getenv('OIDC_CLIENT_SECRET')}")
GitHub Actions构建步骤
name: Build and push image to harbor run: | IMAGE_VERSION=$GITHUB_RUN_NUMBER IMAGE_WITH_TAG="$IMAGE_NAME:develop.$IMAGE_VERSION" docker build \ -t $IMAGE_WITH_TAG --file "$DOCKERFILE_PATH" \ --build-arg OIDC_CLIENT_SECRET=${{ secrets.OIDC_CLIENT_SECRET }} \ --build-arg DB_PWD=${{ secrets.DB_PWD }} \ --build-arg APP_ENV="dev" . docker login TEST.com -u "$DEV_DEPLOY_USENAME" -p "$DEV_DEPLOY_PWD" docker push $IMAGE_WITH_TAG echo "IMAGE_VERSION=$IMAGE_VERSION" >> $GITHUB_ENV echo "PUSHED_IMAGE=$IMAGE_WITH_TAG" >> $GITHUB_ENV echo "develop branch" echo "NAMESPACE=$PROJECT-dev" >> $GITHUB_ENV env: DEV_DEPLOY_USENAME: ${{ secrets.DEV_DEPLOY_USENAME }} DEV_DEPLOY_PWD: ${{ secrets.DEV_DEPLOY_PWD }} PUSHED_IMAGE: ${{ env.PUSHED_IMAGE }} BRANCH: ${{ env.BRANCH }}
Dockerfile
FROM TEST.com/library/python:3.10-slim as builder RUN pip install poetry==1.6.1 ENV POETRY_NO_INTERACTION=1 \ POETRY_VIRTUALENVS_IN_PROJECT=1 \ POETRY_VIRTUALENVS_CREATE=1 \ POETRY_CACHE_DIR=/tmp/poetry_cache WORKDIR /usr/src ARG OIDC_CLIENT_SECRET ARG DB_PWD ARG APP_ENV ENV OIDC_CLIENT_SECRET=$OIDC_CLIENT_SECRET ENV DB_PWD=$DB_PWD ENV APP_ENV=$APP_ENV RUN echo $OIDC_CLIENT_SECRET RUN echo $DB_PWD RUN echo $APP_ENV COPY pyproject.toml ./ RUN poetry install --without dev --no-root && rm -rf $POETRY_CACHE_DIR # The runtime image, used to just run the code provided its virtual environment FROM TEST.com/library/python:3.10-slim as runtime ARG WORKER_COUNT=1 ENV WORKER_COUNT=${WORKER_COUNT} RUN mkdir -p /usr/src WORKDIR /usr/src ENV VIRTUAL_ENV=/usr/src/.venv \ PATH="/usr/src:/usr/src/.venv/bin:$PATH" ENV TZ=America/Chicago RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV} COPY ./src/ /usr/src/ RUN ls -R EXPOSE 5000 CMD uvicorn --workers $WORKER_COUNT --host 0.0.0.0 --port 5000 main:app
问题原因
你使用了Docker多阶段构建,builder阶段设置的环境变量不会自动传递到runtime阶段。两个阶段是完全独立的镜像,runtime阶段仅复制了builder中的虚拟环境目录,并未继承任何环境变量。
解决方案
方案一:在runtime阶段重新声明构建参数并设置环境变量
修改Dockerfile的runtime阶段,添加对应的ARG和ENV声明,让构建参数传递到运行时环境:
# The runtime image, used to just run the code provided its virtual environment FROM TEST.com/library/python:3.10-slim as runtime # 声明需要传递的构建参数 ARG OIDC_CLIENT_SECRET ARG DB_PWD ARG APP_ENV ARG WORKER_COUNT=1 # 将构建参数转为运行时环境变量 ENV OIDC_CLIENT_SECRET=$OIDC_CLIENT_SECRET ENV DB_PWD=$DB_PWD ENV APP_ENV=$APP_ENV ENV WORKER_COUNT=${WORKER_COUNT} RUN mkdir -p /usr/src WORKDIR /usr/src ENV VIRTUAL_ENV=/usr/src/.venv \ PATH="/usr/src:/usr/src/.venv/bin:$PATH" ENV TZ=America/Chicago RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV} COPY ./src/ /usr/src/ RUN ls -R EXPOSE 5000 CMD uvicorn --workers $WORKER_COUNT --host 0.0.0.0 --port 5000 main:app
注:GitHub Actions中的
docker build命令已经包含了所有需要的--build-arg参数,无需修改,Docker会自动将这些参数传递到所有声明了对应ARG的构建阶段。
方案二:通过.env文件传递环境变量
如果不想在runtime阶段重复声明参数,可以在builder阶段将环境变量写入.env文件,再复制到runtime阶段:
- 在builder阶段末尾添加:
# 创建.env文件存储环境变量 RUN echo "OIDC_CLIENT_SECRET=$OIDC_CLIENT_SECRET" > .env && \ echo "DB_PWD=$DB_PWD" >> .env && \ echo "APP_ENV=$APP_ENV" >> .env
- 在runtime阶段添加复制命令(放在
COPY ./src/之前):
COPY --from=builder /usr/src/.env /usr/src/.env
- 在Python应用中使用
python-dotenv库加载.env文件(需先安装该依赖):
from dotenv import load_dotenv load_dotenv() # 加载.env文件中的环境变量 logger.info(f"OIDC SECRET: {os.getenv('OIDC_CLIENT_SECRET')}")
验证方法
可以在runtime阶段临时添加echo命令验证环境变量是否生效(生产环境请删除该命令):
RUN echo "Runtime OIDC_SECRET: $OIDC_CLIENT_SECRET"
内容的提问来源于stack exchange,提问作者Masterstack8080
相关产品推荐
相关产品推荐

