运行 node.js Google Cloud SQL 上的数据库迁移 Google Cloud Build
Run node.js database migrations on Google Cloud SQL during Google Cloud Build
我想在 Cloud Build 过程中 运行 在 node.js 中编写数据库迁移。
目前正在执行数据库迁移命令,但 Cloud Build 进程似乎无权通过 username/password.[=15= 的 IP 地址连接到 Cloud SQL ]
Cloud Build 使用服务帐户运行,您似乎需要为此帐户授予对 Cloud SQL 的访问权限。
您可以找到有关设置服务帐户权限的其他信息 here。
在 Cloud SQL 和 Node.js 的情况下,它看起来像这样:
steps:
# Install Node.js dependencies
- id: yarn-install
name: gcr.io/cloud-builders/yarn
waitFor: ["-"]
# Install Cloud SQL proxy
- id: proxy-install
name: gcr.io/cloud-builders/yarn
entrypoint: sh
args:
- "-c"
- "wget https://storage.googleapis.com/cloudsql-proxy/v1.20.1/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy && chmod +x cloud_sql_proxy"
waitFor: ["-"]
# Migrate database schema to the latest version
# https://knexjs.org/#Migrations-CLI
- id: migrate
name: gcr.io/cloud-builders/yarn
entrypoint: sh
args:
- "-c"
- "(./cloud_sql_proxy -dir=/cloudsql -instances=<CLOUD_SQL_CONNECTION> & sleep 2) && yarn run knex migrate:latest"
timeout: "1200s"
waitFor: ["yarn-install", "proxy-install"]
timeout: "1200s"
您将同时启动 yarn install
和下载 Cloud SQL Proxy。完成这两个步骤后,您 运行 启动代理,等待 2 秒,最后 运行 yarn run knex migrate:latest
.
为此,您需要在 GCP 项目中启用 Cloud SQL Admin API。
其中 <CLOUD_SQL_INSTANCE>
是您的 Cloud SQL 实例连接名称,可以找到 here。您的 SQL 连接设置中将使用相同的名称,例如host=/cloudsql/example:us-central1:pg13
.
此外,请确保 Cloud Build 服务帐户在数据库实例所在的 GCP 项目中具有“Cloud SQL Client”角色。
自 gcr.io/cloudsql-docker/gce-proxy
的标签 1.16
起,当前接受的答案不再有效。这是一种不同的方法,可以使代理与需要它的命令保持在同一步骤:
- id: cmd-with-proxy
name: [YOUR-CONTAINER-HERE]
timeout: 100s
entrypoint: sh
args:
- -c
- '(/workspace/cloud_sql_proxy -dir=/workspace -instances=[INSTANCE_CONNECTION_NAME] & sleep 2) && [YOUR-COMMAND-HERE]'
代理会在主进程退出后自动退出。此外,如果代理或给定的命令失败,它会将步骤标记为 "ERROR"。
这确实需要二进制文件位于 /workspace
卷中,但这可以手动提供或通过如下先决条件步骤提供:
- id: proxy-install
name: alpine:3.10
entrypoint: sh
args:
- -c
- 'wget -O /workspace/cloud_sql_proxy https://storage.googleapis.com/cloudsql-proxy/v1.16/cloud_sql_proxy.linux.386 && chmod +x /workspace/cloud_sql_proxy'
此外,这应该适用于 TCP,因为代理将与命令位于同一容器中。
以下是结合 Cloud Build + Cloud SQL Proxy + Docker.
的方法
如果您 运行 您的数据库 migrations/operations 在 Cloud Build 的 Docker 容器中,它将无法直接访问您的代理,因为 Docker容器与主机隔离。
这是我设法起床的结果运行:
- id: build
# Build your application
waitFor: ['-']
- id: install-proxy
name: gcr.io/cloud-builders/wget
entrypoint: bash
args:
- -c
- wget -O /workspace/cloud_sql_proxy https://storage.googleapis.com/cloudsql-proxy/v1.15/cloud_sql_proxy.linux.386 && chmod +x /workspace/cloud_sql_proxy
waitFor: ['-']
- id: migrate
name: gcr.io/cloud-builders/docker
entrypoint: bash
args:
- -c
- |
/workspace/cloud_sql_proxy -dir=/workspace -instances=projectid:region:instanceid & sleep 2 && \
docker run -v /workspace:/root \
--env DATABASE_HOST=/root/projectid:region:instanceid \
# Pass other necessary env variables like db username/password, etc.
$_IMAGE_URL:$COMMIT_SHA
timeout: '1200s'
waitFor: [build, install-proxy]
因为我们的数据库操作发生在 Docker 容器内,我找到了通过指定 Unix 套接字 -dir/workspace
而不是公开来提供对云 SQL 的访问的最佳方法TCP 端口 5432.
注意:对于 Cloud Build,我建议使用目录 /workspace
而不是 /cloudsql
。
然后我们将 /workspace
目录挂载到 Docker 容器的 /root
目录,这是您的应用程序代码所在的默认目录。当我尝试将它挂载到 /root
以外的其他地方时,似乎什么也没有发生(可能是没有错误输出的权限问题)。
另外:我注意到代理版本 1.15 运行良好。我遇到了较新版本的问题。您的里程可能会有所不同。
使用google-appengine/exec-wrapper。正是这样做的图像。用法(参见 link 中的 README):
steps:
- name: "gcr.io/google-appengine/exec-wrapper"
args: ["-i", "gcr.io/my-project/appengine/some-long-name",
"-e", "ENV_VARIABLE_1=value1", "-e", "ENV_2=value2",
"-s", "my-project:us-central1:my_cloudsql_instance",
"--", "bundle", "exec", "rake", "db:migrate"]
-s
设置代理目标。
我想在 Cloud Build 过程中 运行 在 node.js 中编写数据库迁移。
目前正在执行数据库迁移命令,但 Cloud Build 进程似乎无权通过 username/password.[=15= 的 IP 地址连接到 Cloud SQL ]
Cloud Build 使用服务帐户运行,您似乎需要为此帐户授予对 Cloud SQL 的访问权限。 您可以找到有关设置服务帐户权限的其他信息 here。
在 Cloud SQL 和 Node.js 的情况下,它看起来像这样:
steps:
# Install Node.js dependencies
- id: yarn-install
name: gcr.io/cloud-builders/yarn
waitFor: ["-"]
# Install Cloud SQL proxy
- id: proxy-install
name: gcr.io/cloud-builders/yarn
entrypoint: sh
args:
- "-c"
- "wget https://storage.googleapis.com/cloudsql-proxy/v1.20.1/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy && chmod +x cloud_sql_proxy"
waitFor: ["-"]
# Migrate database schema to the latest version
# https://knexjs.org/#Migrations-CLI
- id: migrate
name: gcr.io/cloud-builders/yarn
entrypoint: sh
args:
- "-c"
- "(./cloud_sql_proxy -dir=/cloudsql -instances=<CLOUD_SQL_CONNECTION> & sleep 2) && yarn run knex migrate:latest"
timeout: "1200s"
waitFor: ["yarn-install", "proxy-install"]
timeout: "1200s"
您将同时启动 yarn install
和下载 Cloud SQL Proxy。完成这两个步骤后,您 运行 启动代理,等待 2 秒,最后 运行 yarn run knex migrate:latest
.
为此,您需要在 GCP 项目中启用 Cloud SQL Admin API。
其中 <CLOUD_SQL_INSTANCE>
是您的 Cloud SQL 实例连接名称,可以找到 here。您的 SQL 连接设置中将使用相同的名称,例如host=/cloudsql/example:us-central1:pg13
.
此外,请确保 Cloud Build 服务帐户在数据库实例所在的 GCP 项目中具有“Cloud SQL Client”角色。
自 gcr.io/cloudsql-docker/gce-proxy
的标签 1.16
起,当前接受的答案不再有效。这是一种不同的方法,可以使代理与需要它的命令保持在同一步骤:
- id: cmd-with-proxy
name: [YOUR-CONTAINER-HERE]
timeout: 100s
entrypoint: sh
args:
- -c
- '(/workspace/cloud_sql_proxy -dir=/workspace -instances=[INSTANCE_CONNECTION_NAME] & sleep 2) && [YOUR-COMMAND-HERE]'
代理会在主进程退出后自动退出。此外,如果代理或给定的命令失败,它会将步骤标记为 "ERROR"。
这确实需要二进制文件位于 /workspace
卷中,但这可以手动提供或通过如下先决条件步骤提供:
- id: proxy-install
name: alpine:3.10
entrypoint: sh
args:
- -c
- 'wget -O /workspace/cloud_sql_proxy https://storage.googleapis.com/cloudsql-proxy/v1.16/cloud_sql_proxy.linux.386 && chmod +x /workspace/cloud_sql_proxy'
此外,这应该适用于 TCP,因为代理将与命令位于同一容器中。
以下是结合 Cloud Build + Cloud SQL Proxy + Docker.
的方法如果您 运行 您的数据库 migrations/operations 在 Cloud Build 的 Docker 容器中,它将无法直接访问您的代理,因为 Docker容器与主机隔离。
这是我设法起床的结果运行:
- id: build
# Build your application
waitFor: ['-']
- id: install-proxy
name: gcr.io/cloud-builders/wget
entrypoint: bash
args:
- -c
- wget -O /workspace/cloud_sql_proxy https://storage.googleapis.com/cloudsql-proxy/v1.15/cloud_sql_proxy.linux.386 && chmod +x /workspace/cloud_sql_proxy
waitFor: ['-']
- id: migrate
name: gcr.io/cloud-builders/docker
entrypoint: bash
args:
- -c
- |
/workspace/cloud_sql_proxy -dir=/workspace -instances=projectid:region:instanceid & sleep 2 && \
docker run -v /workspace:/root \
--env DATABASE_HOST=/root/projectid:region:instanceid \
# Pass other necessary env variables like db username/password, etc.
$_IMAGE_URL:$COMMIT_SHA
timeout: '1200s'
waitFor: [build, install-proxy]
因为我们的数据库操作发生在 Docker 容器内,我找到了通过指定 Unix 套接字 -dir/workspace
而不是公开来提供对云 SQL 的访问的最佳方法TCP 端口 5432.
注意:对于 Cloud Build,我建议使用目录 /workspace
而不是 /cloudsql
。
然后我们将 /workspace
目录挂载到 Docker 容器的 /root
目录,这是您的应用程序代码所在的默认目录。当我尝试将它挂载到 /root
以外的其他地方时,似乎什么也没有发生(可能是没有错误输出的权限问题)。
另外:我注意到代理版本 1.15 运行良好。我遇到了较新版本的问题。您的里程可能会有所不同。
使用google-appengine/exec-wrapper。正是这样做的图像。用法(参见 link 中的 README):
steps:
- name: "gcr.io/google-appengine/exec-wrapper"
args: ["-i", "gcr.io/my-project/appengine/some-long-name",
"-e", "ENV_VARIABLE_1=value1", "-e", "ENV_2=value2",
"-s", "my-project:us-central1:my_cloudsql_instance",
"--", "bundle", "exec", "rake", "db:migrate"]
-s
设置代理目标。