Docker无法读取.env文件中的API密钥,Flask应用部署遇阻
解决Flask部署Cloud Run时Docker无法读取.env密钥的问题
核心问题梳理
你当前的配置混淆了本地docker-compose开发和Cloud Run生产部署的逻辑:Cloud Run不使用docker-compose,直接把.env打包进镜像存在安全风险,同时代码可能没正确加载环境变量。
分步解决方案
一、本地开发(用docker-compose)的调整
- 统一Docker文件名:你的docker-compose里指定了
Dockerfile.action,但实际文件是Dockerfile,要么把Dockerfile重命名为Dockerfile.action,要么修改docker-compose.yml的dockerfile字段为Dockerfile。 - 确保Flask代码加载.env:在
main.py开头添加代码,用python-dotenv读取本地.env文件:from dotenv import load_dotenv import os # 加载根目录的.env文件 load_dotenv() # 获取API密钥 API_KEY = os.getenv("API_KEY") - 确认.env在项目根目录:docker-compose会自动读取当前目录的.env文件,无需额外配置,此时启动容器就能读到API_KEY。
二、Cloud Run生产部署(推荐方案,安全优先)
Cloud Run不依赖docker-compose,直接通过平台设置环境变量,无需打包.env进镜像:
- 修改Dockerfile,移除冗余依赖安装:如果
requirements.txt已经包含Flask、gunicorn、python-dotenv,删掉单独安装的命令,简化后的Dockerfile:FROM python:3.11-slim ENV PYTHONUNBUFFERED True ENV APP_HOME /app WORKDIR $APP_HOME COPY . ./ RUN pip install --no-cache-dir --upgrade pip RUN pip install --no-cache-dir -r requirements.txt CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app - 代码兼容本地和生产:保持
load_dotenv()的代码,本地开发时加载.env,Cloud Run部署时自动读取平台设置的环境变量(os.getenv("API_KEY")优先取系统环境变量,不受本地.env影响)。 - 部署时设置Cloud Run环境变量:
- 控制台方式:部署Cloud Run服务时,进入「容器、变量和秘密」→「环境变量」,添加键
API_KEY,值填你的密钥。 - gcloud命令方式:
gcloud run deploy <你的服务名> --image gcr.io/<你的项目ID>/<镜像名> --set-env-vars API_KEY=<你的密钥>
- 控制台方式:部署Cloud Run服务时,进入「容器、变量和秘密」→「环境变量」,添加键
三、不推荐的方案:把.env打包进镜像
如果一定要在镜像里包含.env(不建议,密钥会随镜像泄露),需要:
- 确保
COPY . ./把.env复制进镜像(当前Dockerfile已实现)。 - 代码里必须调用
load_dotenv()加载.env文件。 - 绝对不要把.env提交到Git仓库,在
.gitignore里添加.env。
关键注意事项
- 生产环境永远不要把敏感密钥打包进Docker镜像,用Cloud Run的环境变量或秘密管理器更安全。
- 检查
requirements.txt是否包含所有依赖,避免重复安装。
内容的提问来源于stack exchange,提问作者loupdaniel
相关产品推荐
相关产品推荐

