Rails迁移不会在谷歌应用程序引擎部署上运行

时间:2021-08-27 23:11:39

How do you run Rails migrations upon deploy to Google App Engine (gcloud app deploy)?

如何在部署到谷歌应用程序引擎(gcloud应用程序部署)时运行Rails迁移?

I'm trying to deploy a Rails 5 (Ruby 2.3.1) app to Google App Engine using Cloud SQL. I followed the steps outlined in Google's Bookshelf tutorial and their GitHub repo for Cloud SQL to set up app.yaml and database.yml.

我正在尝试使用云SQL将Rails 5 (Ruby 2.3.1)应用程序部署到谷歌应用程序引擎。我按照谷歌的书架教程和它们的GitHub repo中的步骤为云SQL设置app.yaml和database.yml。

The deploy completes successfully and I'm able to view the landing page of my app, but when I go to the Sign In or Sign Up pages, I get a 500 error because the Users table hasn't been created.

部署成功完成,我可以查看应用程序的登录页面,但当我进入登录页面或注册页面时,我得到了500个错误,因为用户表还没有创建。

Step 8 of the deploy log seems to mention asset precompile

部署日志的第8步似乎提到了资产预编译。

Step 8 : RUN if test -d app/assets -a -f config/application.rb; then       bundle exec rake assets:precompile || true;     fi

But I don't see anything like db:create and db:migrate, which I need to run when I deploy.

但是我没有看到任何像db:create和db:迁移,我需要在部署时运行。

FYI, I have run rake db:migrate and everything is working as expected on local.

我已经运行了rake db: migration and everything is working on local。

Thanks!

谢谢!

3 个解决方案

#1


2  

You're correct that it isn't run after running gcloud app deploy. We also probably wouldn't want to run it from the containers, because there are several of them, and if we ran it on all of them then there would be a race condition in which sometimes some of the migrations would run twice, or perhaps one would run before another is finished. Therefore it makes sense to run them on the machine from which you are deploying. Fortunately, that's easy using the Google Cloud SQL Proxy (this assumes you're using Cloud SQL of course). See this link for documentation: https://cloud.google.com/sql/docs/mysql/connect-external-app#proxy

您是正确的,在运行gcloud应用程序部署后它不会运行。我们也可能不会想要运行的容器,因为有几个人,然后如果我们跑在他们所有人会有竞争条件,有时一些迁移会跑两次,或者之前运行另一个一个完成。因此,在正在部署的机器上运行它们是有意义的。幸运的是,使用谷歌云SQL代理很容易(当然,这假定您使用的是云SQL)。有关文档,请参见此链接:https://cloud.google.com/sql/docs/mysql/connect-external-app#proxy

First, we set up the cloud SQL proxy itself (these are for Linux):

首先,我们设置了云SQL代理(这些是针对Linux的):

wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 chmod +x cloud_sql_proxy.linux.amd64 sudo mv cloud_sql_proxy.linux.amd64 /usr/local/bin/cloud-sql-proxy

wget https://dl.google.com/cloudsql/cloudsql_proxy .linux.amd64 chmod +x cloud_sql_proxy.linux。amd64 sudo mv cloud_sql_proxy.linux。amd64 /usr/local/bin/cloud-sql-proxy

Then using gcloud, login and set the default project to the one you're currently working with (because the cloud SQL proxy uses the gcloud configuration to figure out how to connect):

然后使用gcloud,登录并将默认项目设置为当前正在使用的项目(因为云SQL代理使用gcloud配置来计算如何连接):

gcloud config set project <your project name> # we don't want to deploy or connect to the wrong project! gcloud auth list # make sure you're dealing with the account you should be gcloud auth application-default login

gcloud配置设置项目 <您的项目名称> #我们不想部署或连接到错误的项目!请确保您正在处理的帐户应该是gcloud auth应用程序默认登录

The last step was necessary because I'm deploying from a Google Compute Engine VM, which already was logged in with a service account which didn't have the right credentials.

最后一步是必要的,因为我正在部署一个谷歌计算引擎VM,它已经登录到一个没有正确凭据的服务帐户。

Then set up the cloud sql proxy socket directory. This works with Postgres as well. Just make sure that it's the same directory that your production config expects:

然后设置云sql代理套接字目录。这也适用于Postgres。只要确保它与您的产品配置期望的目录相同:

sudo mkdir /cloudsql sudo chown $USER /cloudsql

sudo mkdir /cloudsql sudo chown $USER /cloudsql

Then start the cloud sql proxy in another window or in the background:

然后在另一个窗口或背景中启动云sql代理:

cloud-sql-proxy -dir /cloudsql

cloud-sql-proxy dir / cloudsql

Then run your deploy task and migration:

然后运行部署任务和迁移:

gcloud app deploy RAILS_ENV=production rake db:migrate

gcloud应用程序部署RAILS_ENV=production rake db:migrate

When I just set this up, I was frustrated by the fact that if you run the migration before your deployment (which takes a long time!), your site will be down. And if you run the migration after, then depending on how health checks are set up, it may detect that the new version is unhealthy. Since config.active_record.migration_error isn't set on production by default, I think the best option is to run the migration after the deploy unless you want to set up health checks in such a way that a health check endpoint will raise an exception if there are pending migrations. Then you could have your application move to the new version at the exact time when migrations are finished. However because of the nature of health checks running periodically, you'll still have a few seconds of downtime. The two-line script above (running the migrations after the deploy) is probably the best you can get without a whole lot more effort.

当我刚刚设置这个时,我对以下事实感到沮丧:如果您在部署之前运行迁移(这需要很长时间!),您的站点将会宕机。如果您在之后运行迁移,那么根据健康检查的设置,它可能会检测到新版本是不健康的。因为config.active_record。默认情况下,在生产环境中不会设置migration_error,我认为最好的选择是在部署之后运行迁移,除非您希望设置健康检查,以便在存在等待迁移的情况下,健康检查端点会引发异常。然后,您可以让您的应用程序在迁移完成的确切时间迁移到新版本。然而,由于定期运行的健康检查的性质,您仍然会有几秒钟的停机时间。上面的两行脚本(在部署之后运行迁移)可能是最好的,而不需要付出很多努力。

#2


0  

I am not familiar with Google App Engine, but a common approach is to run rake db:migrate comment as a part of deploy script.

我不熟悉谷歌应用程序引擎,但是一种常见的方法是运行rake db:将注释作为部署脚本的一部分进行迁移。

I can see here that db:setup is executed as a part of setup script, did you commit/push to the Google App Engine updated version of db/schema.rb file? Based on it db:setup task should prepare an up-to-date version of the database.

我可以看到,db:setup作为setup脚本的一部分执行,您是否提交/推送到谷歌App Engine更新的db/schema版本。rb文件?根据它,设置任务应该准备一个最新版本的数据库。

#3


0  

I'm trying to do the same thing. So far, all I can find is this page. You can also install the MySQL proxy on your local machine and then run your normal rake tasks (rake db:setup, which also runs db:seed), but this is much slower from my initial tests. Hopefully someone else has a better solution!

我也在做同样的事情。到目前为止,我只能找到这一页。您还可以在本地机器上安装MySQL代理,然后运行常规的rake任务(rake db:setup,它也运行db:seed),但这比我最初的测试要慢得多。希望其他人有更好的解决方案!

#1


2  

You're correct that it isn't run after running gcloud app deploy. We also probably wouldn't want to run it from the containers, because there are several of them, and if we ran it on all of them then there would be a race condition in which sometimes some of the migrations would run twice, or perhaps one would run before another is finished. Therefore it makes sense to run them on the machine from which you are deploying. Fortunately, that's easy using the Google Cloud SQL Proxy (this assumes you're using Cloud SQL of course). See this link for documentation: https://cloud.google.com/sql/docs/mysql/connect-external-app#proxy

您是正确的,在运行gcloud应用程序部署后它不会运行。我们也可能不会想要运行的容器,因为有几个人,然后如果我们跑在他们所有人会有竞争条件,有时一些迁移会跑两次,或者之前运行另一个一个完成。因此,在正在部署的机器上运行它们是有意义的。幸运的是,使用谷歌云SQL代理很容易(当然,这假定您使用的是云SQL)。有关文档,请参见此链接:https://cloud.google.com/sql/docs/mysql/connect-external-app#proxy

First, we set up the cloud SQL proxy itself (these are for Linux):

首先,我们设置了云SQL代理(这些是针对Linux的):

wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 chmod +x cloud_sql_proxy.linux.amd64 sudo mv cloud_sql_proxy.linux.amd64 /usr/local/bin/cloud-sql-proxy

wget https://dl.google.com/cloudsql/cloudsql_proxy .linux.amd64 chmod +x cloud_sql_proxy.linux。amd64 sudo mv cloud_sql_proxy.linux。amd64 /usr/local/bin/cloud-sql-proxy

Then using gcloud, login and set the default project to the one you're currently working with (because the cloud SQL proxy uses the gcloud configuration to figure out how to connect):

然后使用gcloud,登录并将默认项目设置为当前正在使用的项目(因为云SQL代理使用gcloud配置来计算如何连接):

gcloud config set project <your project name> # we don't want to deploy or connect to the wrong project! gcloud auth list # make sure you're dealing with the account you should be gcloud auth application-default login

gcloud配置设置项目 <您的项目名称> #我们不想部署或连接到错误的项目!请确保您正在处理的帐户应该是gcloud auth应用程序默认登录

The last step was necessary because I'm deploying from a Google Compute Engine VM, which already was logged in with a service account which didn't have the right credentials.

最后一步是必要的,因为我正在部署一个谷歌计算引擎VM,它已经登录到一个没有正确凭据的服务帐户。

Then set up the cloud sql proxy socket directory. This works with Postgres as well. Just make sure that it's the same directory that your production config expects:

然后设置云sql代理套接字目录。这也适用于Postgres。只要确保它与您的产品配置期望的目录相同:

sudo mkdir /cloudsql sudo chown $USER /cloudsql

sudo mkdir /cloudsql sudo chown $USER /cloudsql

Then start the cloud sql proxy in another window or in the background:

然后在另一个窗口或背景中启动云sql代理:

cloud-sql-proxy -dir /cloudsql

cloud-sql-proxy dir / cloudsql

Then run your deploy task and migration:

然后运行部署任务和迁移:

gcloud app deploy RAILS_ENV=production rake db:migrate

gcloud应用程序部署RAILS_ENV=production rake db:migrate

When I just set this up, I was frustrated by the fact that if you run the migration before your deployment (which takes a long time!), your site will be down. And if you run the migration after, then depending on how health checks are set up, it may detect that the new version is unhealthy. Since config.active_record.migration_error isn't set on production by default, I think the best option is to run the migration after the deploy unless you want to set up health checks in such a way that a health check endpoint will raise an exception if there are pending migrations. Then you could have your application move to the new version at the exact time when migrations are finished. However because of the nature of health checks running periodically, you'll still have a few seconds of downtime. The two-line script above (running the migrations after the deploy) is probably the best you can get without a whole lot more effort.

当我刚刚设置这个时,我对以下事实感到沮丧:如果您在部署之前运行迁移(这需要很长时间!),您的站点将会宕机。如果您在之后运行迁移,那么根据健康检查的设置,它可能会检测到新版本是不健康的。因为config.active_record。默认情况下,在生产环境中不会设置migration_error,我认为最好的选择是在部署之后运行迁移,除非您希望设置健康检查,以便在存在等待迁移的情况下,健康检查端点会引发异常。然后,您可以让您的应用程序在迁移完成的确切时间迁移到新版本。然而,由于定期运行的健康检查的性质,您仍然会有几秒钟的停机时间。上面的两行脚本(在部署之后运行迁移)可能是最好的,而不需要付出很多努力。

#2


0  

I am not familiar with Google App Engine, but a common approach is to run rake db:migrate comment as a part of deploy script.

我不熟悉谷歌应用程序引擎,但是一种常见的方法是运行rake db:将注释作为部署脚本的一部分进行迁移。

I can see here that db:setup is executed as a part of setup script, did you commit/push to the Google App Engine updated version of db/schema.rb file? Based on it db:setup task should prepare an up-to-date version of the database.

我可以看到,db:setup作为setup脚本的一部分执行,您是否提交/推送到谷歌App Engine更新的db/schema版本。rb文件?根据它,设置任务应该准备一个最新版本的数据库。

#3


0  

I'm trying to do the same thing. So far, all I can find is this page. You can also install the MySQL proxy on your local machine and then run your normal rake tasks (rake db:setup, which also runs db:seed), but this is much slower from my initial tests. Hopefully someone else has a better solution!

我也在做同样的事情。到目前为止,我只能找到这一页。您还可以在本地机器上安装MySQL代理,然后运行常规的rake任务(rake db:setup,它也运行db:seed),但这比我最初的测试要慢得多。希望其他人有更好的解决方案!