0

I'm following the 'Running Rails on the Cloud Run environment' instructions and have hit a snag. I used their provided github repo and the google cloud shell and I had success in launching the working application.

Now, I am trying to integrate Cloud Run into my rails template. While 'Deploying the app to Cloud Run' using the cloudbuild.yaml file provided, the build crashes during database migration. I am using postgreSQL. Here are the error details:

The error

"bundle exec rails db:migrate" ->

"ActiveRecord::ConnectionNotEstablished: could not connect to server: No such file or directory"

I think I've traced it to database.yml file where Google recommends this host:

production:
  <<: *default
  database: <%= ENV["PRODUCTION_DB_NAME"] %>
  username: <%= ENV["PRODUCTION_DB_USERNAME"] %>
  password: <%= Rails.application.credentials.gcp[:db_password] %>
  host: "<%= ENV.fetch("DB_SOCKET_DIR") { '/cloudsql' } %>/<%= ENV["CLOUD_SQL_CONNECTION_NAME"] %>"

It is unclear where this ENV.fetch("DB_SOCKET_DIR") comes from [at least to me, I'm new]. Their git repo holds a folder where I found templates for another build that included an app.standard.yaml and a config/database_unix.yml that I've tried integrating.

app.standard.yaml:

entrypoint: bundle exec rackup --port $PORT
runtime: ruby27

env_variables:
  SECRET_KEY_BASE: <SECRET_KEY>
  RAILS_ENV: production
  INSTANCE_UNIX_SOCKET: /cloudsql/<PROJECT-ID>:<INSTANCE-REGION>:<INSTANCE-NAME>
  DB_USER: <YOUR_DB_USER_NAME>
  DB_PASS: <YOUR_DB_PASSWORD>
  DB_NAME: <YOUR_DB_NAME>

beta_settings:
  cloud_sql_instances: <PROJECT-ID>:<INSTANCE-REGION>:<INSTANCE-NAME>

database_unix.yml:

# [START cloud_sql_postgres_activerecord_connect_unix]
unix: &unix
  adapter: postgresql
  # Configure additional properties here.
  # [END cloud_sql_postgres_activerecord_connect_unix]
  pool: 5
  timeout: 5000

  # [START cloud_sql_postgres_activerecord_connect_unix]
  # Note: Saving credentials in environment variables is convenient, but not
  # secure - consider a more secure solution such as
  # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  # keep secrets safe.
  username: <%= ENV["DB_USER"] %>  # e.g. "my-database-user"
  password: <%= ENV["DB_PASS"] %> # e.g. "my-database-password"
  database: <%= ENV.fetch("DB_NAME") { "vote_development" } %>
  # Specify the Unix socket path as host
  host: "<%= ENV["INSTANCE_UNIX_SOCKET"] %>"
  # [END cloud_sql_postgres_activerecord_connect_unix]

development:
  <<: *unix

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *unix
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 1 } %>
  database: <%= ENV.fetch("DB_NAME") { "vote_test" } %>

production:
  <<: *unix
  database: <%= ENV.fetch("DB_NAME") { "vote_production" } %>

Some other solutions I've seen mention this instead of host:

socket: “/cloudsql/project_id:us-central1:photo-album-production”

I tried this with no luck. I cloned the repo to my machine and re-tried the Cloud Run instructions. No success this time as it's getting the same migration error. Am I thinking about this wrong?

Brian
  • 11
  • 1
  • Did you find a solution to this? I'm struggling with the same problem. – Jerry Zhang Mar 22 '23 at 03:14
  • @JerryZhang I took a break from the problem lol, but I think I just found the solution while building with Go. It's because of the disallowed ports from localhost server to postgres. Since you need to dockerize to deploy to cloud run, the docker host needs to be allowed to connect when in development. All I did was change this DB_HOST=host.docker.internal from DB_HOST=localhost in my connection request and it connected to my docker container. Answered here: https://stackoverflow.com/questions/31249112/allow-docker-container-to-connect-to-a-local-host-postgres-database – Brian May 27 '23 at 20:51

1 Answers1

0

Check this out: https://cloud.google.com/sql/docs/postgres/connect-build.

In short, you'll need to run the Cloud SQL Auth Proxy to create a Unix socket in Cloud Build so your app can connect.

If you're using a private IP instance, you'll need to make sure you're using private pools.

enocom
  • 1,496
  • 1
  • 15
  • 22