如何在Cloud Build中通过Cloud SQL Proxy执行数据库迁移?
我在Dockerfile里定义了数据库迁移流程:
... ARG DATABASE_URL ENV DATABASE_URL RUN npx prisma migrate deploy --schema ./prisma/schema.prisma ...
我的Cloud Build触发器YAML配置如下:
steps: - name: gcr.io/cloud-builders/docker args: - '-c' - >- docker build --build-arg DATABASE_URL=$$DATABASE_URL --no-cache -t $_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA . -f Dockerfile id: Build entrypoint: bash secretEnv: - DATABASE_URL # Rest of the steps images: - '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA' options: substitutionOption: ALLOW_LOOSE dynamicSubstitutions: true substitutions: # My substitutions tags: # My tags availableSecrets: secretManager: - versionName: projects/my-project-id/secrets/DATABASE_URL/versions/1 env: DATABASE_URL
DATABASE_URL格式为postgresql://postgres:mysecretpassword@my.ip.is.here:5432/postgres。
当前配置无法正常运行,原因应该是Cloud Build的IP无法加入数据库白名单(我也不想添加)。我知道需要用数据库的连接名(比如project-123456:us-central1:my-database)连接,尝试用Cloud SQL Proxy但未成功。之前添加了一个Proxy步骤作为第一步,把DATABASE_URL改成postgresql://postgres:mysecretpassword@127.0.01:5432/postgres,结果这个Proxy步骤无限运行,后续步骤无法启动:
- name: 'gcr.io/cloud-sql-connectors/cloud-sql-proxy' id: Proxy args: - 'project-123456:us-central1:my-database'
请问如何让依赖DATABASE_URL的Prisma命令正常连接数据库并执行迁移?
核心问题是Cloud Build默认串行执行步骤,单独启动Proxy会一直挂起,无法与构建步骤同时运行。需要让Proxy和构建步骤并行,且在同一网络内互通,具体操作如下:
1. 调整Cloud Build YAML配置
修改触发器配置,让Proxy后台运行,同时与构建步骤处于同一网络:
steps: # 启动Cloud SQL Proxy,后台运行避免阻塞 - name: 'gcr.io/cloud-sql-connectors/cloud-sql-proxy' id: Proxy entrypoint: bash args: - '-c' - 'cloud-sql-proxy --port=5432 project-123456:us-central1:my-database &' waitFor: ['-'] # 不等待任何前置步骤,直接启动 # 执行Docker构建,等待Proxy就绪后运行 - name: gcr.io/cloud-builders/docker id: Build entrypoint: bash args: - '-c' - >- docker build --network=cloudbuild --build-arg DATABASE_URL=postgresql://postgres:mysecretpassword@proxy:5432/postgres --no-cache -t $_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA . -f Dockerfile waitFor: ['Proxy'] # 等待Proxy启动完成后执行 # 无需再从Secret Manager获取原DATABASE_URL,直接使用代理地址
2. 修正Dockerfile的ENV赋值
原Dockerfile中ENV DATABASE_URL未赋值,会导致环境变量为空,补上赋值逻辑:
... ARG DATABASE_URL ENV DATABASE_URL=$DATABASE_URL RUN npx prisma migrate deploy --schema ./prisma/schema.prisma ...
3. 关键配置细节
--network=cloudbuild:Docker构建时指定该参数,让构建容器与Proxy容器处于Cloud Build专属网络,可直接用Proxy步骤的ID(proxy)作为主机名访问代理服务。- Proxy后台运行:通过
&让Proxy在后台启动,避免步骤一直挂起不结束。 waitFor规则:让Build步骤等待Proxy启动,确保代理服务就绪后再执行迁移。- DATABASE_URL修改:将主机部分替换为
proxy,端口保持5432,Prisma会通过Proxy转发请求到Cloud SQL实例,无需开放数据库白名单。
4. 权限配置
确保Cloud Build的服务账号拥有Cloud SQL Client角色,否则Proxy无法访问Cloud SQL:
- 打开Cloud IAM控制台,找到Cloud Build服务账号(格式:
[你的项目编号]@cloudbuild.gserviceaccount.com) - 为该账号添加
Cloud SQL Client角色
调整完成后,构建时Prisma即可通过Cloud SQL Proxy正常连接数据库执行迁移,无需开放数据库白名单。
内容的提问来源于stack exchange,提问作者mdmb

