简体   繁体   English

在 Google Cloud Build 期间在 Google Cloud SQL 上运行 node.js 数据库迁移

[英]Run node.js database migrations on Google Cloud SQL during Google Cloud Build

I would like to run database migrations written in node.js during the Cloud Build process.我想在 Cloud Build 过程中运行用 node.js 编写的数据库迁移。

Currently, the database migration command is being executed but it seems that the Cloud Build process does not have access to connect to Cloud SQL via an IP address with username/password.当前,正在执行数据库迁移命令,但似乎 Cloud Build 进程无权通过具有用户名/密码的 IP 地址连接到 Cloud SQL。

In the case with Cloud SQL and Node.js it would look something like this:在使用Cloud SQLNode.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"

You would launch yarn install and download Cloud SQL Proxy in parallel.您将并行启动yarn install和下载Cloud SQL 代理 Once these two steps are complete, you run launch the proxy, wait 2 seconds and finally run yarn run knex migrate:latest .完成这两个步骤后,运行启动代理,等待 2 秒钟,最后运行yarn run knex migrate:latest

For this to work you would need Cloud SQL Admin API enabled in your GCP project.为此,您需要在 GCP 项目中启用Cloud SQL Admin API

Where <CLOUD_SQL_INSTANCE> is your Cloud SQL instance connection name that can be found here .其中<CLOUD_SQL_INSTANCE>是您的 Cloud SQL 实例连接名称,可在此处找到。 The same name will be used in your SQL connection settings, eg host=/cloudsql/example:us-central1:pg13 .在您的 SQL 连接设置中将使用相同的名称,例如host=/cloudsql/example:us-central1:pg13

Also, make sure that the Cloud Build service account has "Cloud SQL Client" role in the GCP project, where the db instance is located.此外,请确保 Cloud Build 服务帐号在 db 实例所在的 GCP 项目中具有“Cloud SQL Client”角色。

As of tag 1.16 of gcr.io/cloudsql-docker/gce-proxy , the currently accepted answer no longer works.gcr.io/cloudsql-docker/gce-proxy的标签1.16 gcr.io/cloudsql-docker/gce-proxy ,当前接受的答案不再有效。 Here is a different approach that keeps the proxy in the same step as the commands that need it:这是一种不同的方法,它使代理与需要它的命令保持在同一步骤:

  - 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]'

The proxy will automatically exit once the main process exits.一旦主进程退出,代理将自动退出。 Additionally, it'll mark the step as "ERROR" if either the proxy or the command given fails.此外,如果代理或给定的命令失败,它会将步骤标记为“错误”。

This does require the binary is in the /workspace volume, but this can be provided either manually or via a prereq step like this:这确实需要二进制文件位于/workspace卷中,但这可以手动或通过这样的 prereq 步骤提供:

  - 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'

Additionally, this should work with TCP since the proxy will be in the same container as the command.此外,这应该与 TCP 一起使用,因为代理将与命令位于同一容器中。

Use google-appengine/exec-wrapper .使用google-appengine/exec-wrapper It is an image to do exactly this.这是一个图像来做到这一点。 Usage (see README in link):用法(请参阅链接中的自述文件):

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"]

The -s sets the proxy target. -s设置代理目标。

Cloud Build runs using a service account and it looks like you need to grant access to Cloud SQL for this account. Cloud Build 使用服务帐号运行,您似乎需要为此帐号授予对 Cloud SQL 的访问权限。 You can find additional info about setting service account permissions here .您可以在此处找到有关设置服务帐户权限的其他信息。

Here's how to combine Cloud Build + Cloud SQL Proxy + Docker.下面介绍如何组合 Cloud Build + Cloud SQL Proxy + Docker。

If you're running your database migrations/operations within a Docker container in Cloud Build, it won't be able to directly access your proxy, because Docker containers are isolated from the host machine.如果您在 Cloud Build 的 Docker 容器内运行数据库迁移/操作,它将无法直接访问您的代理,因为 Docker 容器与主机是隔离的。

Here's what I managed to get up and running:这是我设法启动和运行的内容:

  - 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]

Because our db operations are taking place within the Docker container, I found the best way to provide the access to Cloud SQL by specifying the Unix socket -dir/workspace instead of exposing a TCP port 5432.因为我们的数据库操作是在 Docker 容器中进行的,所以我找到了通过指定 Unix socket -dir/workspace而不是暴露 TCP 端口 5432 来提供对 Cloud SQL 的访问的最佳方法。

Note: I recommend using the directory /workspace instead of /cloudsql for Cloud Build.注意:对于 Cloud Build,我建议使用目录/workspace而不是/cloudsql

Then we mounted the /workspace directory to Docker container's /root directory, which is the default directory where your application code resides.然后我们将/workspace目录挂载到 Docker 容器的/root目录,这是您的应用程序代码所在的默认目录。 When I tried to mount it to other than /root , nothing seemed to happen (perhaps a permission issue with no error output).当我尝试将它挂载到/root ,似乎什么也没发生(可能是权限问题,没有错误输出)。

Also: I noticed the proxy version 1.15 works well.另外:我注意到代理版本 1.15 运行良好。 I had issues with newer versions.我在使用较新版本时遇到了问题。 Your mileage may vary.你的旅费可能会改变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM