将config/加入.gitignore后Docker找不到文件,如何保留忽略并解决部署报错?
问题背景
为保护私钥文件privateKey.json,我将config/目录加入.gitignore,但使用gcloud run deploy部署项目时出现错误:
FileNotFoundError: [Errno 2] No such file or directory: config/privateKey.json
若从.gitignore移除config/,错误会消失,但私钥文件会被提交到Git仓库,存在安全风险。
项目目录结构:
- project_folder - WebServer.py - DockerFile - config - privateKey.json
Dockerfile内容:
# Use the official lightweight Python image. FROM python:3.10-slim # Allow statements and log messages to immediately appear in the Knative logs ENV PYTHONUNBUFFERED True # Copy local code to the container image. ENV APP_HOME /app WORKDIR $APP_HOME COPY . ./ # Install production dependencies. RUN pip install --no-cache-dir -r requirements.txt # Run the web service on container startup. CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 "WebServer:create_app()"
.dockerignore内容:
Dockerfile README.md *.pyc *.pyo *.pyd __pycache__ .pytest_cache weight_upload_workflow.py .git .gitignore
解决方案(保留.gitignore中config/的前提下)
方法1:使用Cloud Secret Manager存储私钥(推荐)
这是Google Cloud官方推荐的敏感信息管理方案,彻底避免私钥暴露在Git或镜像中:
上传私钥到Secret Manager
在本地终端执行命令,将config/privateKey.json内容上传为Secret:gcloud secrets create private-key-secret --data-file=config/privateKey.json部署时挂载密钥到容器指定路径
部署Cloud Run服务时,通过--set-secrets参数将Secret挂载到容器内代码读取的路径:gcloud run deploy [你的服务名] \ --source . \ --set-secrets=/app/config/privateKey.json=private-key-secret:latest \ --region [你的部署区域]容器启动后,
config/privateKey.json会自动生成,代码无需修改,同时私钥全程不会出现在Git或镜像文件中。
方法2:本地构建镜像后推送部署(适合小团队/个人项目)
如果不想用Secret Manager,可以本地构建镜像(利用本地存在的config/目录),再推送到容器注册表部署:
本地构建镜像
替换[项目ID]和[镜像名]后执行:docker build -t gcr.io/[项目ID]/[镜像名]:latest .推送镜像到Google容器注册表
docker push gcr.io/[项目ID]/[镜像名]:latest用镜像部署Cloud Run
gcloud run deploy [你的服务名] \ --image gcr.io/[项目ID]/[镜像名]:latest \ --region [你的部署区域]注意:本地需保留
config/目录和私钥文件,且.gitignore保持忽略状态。但该方案不适合Cloud Build自动构建场景,因为Cloud Build拉取的Git仓库中没有config/目录。
方法3:修改代码从环境变量读取私钥(轻量方案)
将私钥内容通过环境变量传递给Cloud Run服务,代码直接读取环境变量而非文件:
部署时设置环境变量
可以直接传递转义后的私钥JSON(注意转义引号):gcloud run deploy [你的服务名] \ --source . \ --set-env-vars PRIVATE_KEY='{"type": "service_account", ...}' \ --region [你的部署区域]更安全的方式是关联Secret Manager:
gcloud run deploy [你的服务名] \ --source . \ --set-env-vars PRIVATE_KEY=projects/[项目ID]/secrets/private-key-secret/versions/latest \ --region [你的部署区域]修改代码读取环境变量
在WebServer.py中替换原文件读取逻辑:import os import json private_key = json.loads(os.environ.get('PRIVATE_KEY'))
内容的提问来源于stack exchange,提问作者FYY

