node.jsgoogle-cloud-platformgoogle-cloud-sqlknex.jsghost

Issue using Ghost with Google Cloud SQL


I'm following the instructions here to use Ghost as an NPM module, and attempting to setup Ghost for production.

I'm running Google cloud sql proxy locally. When I run NODE_ENV=production knex-migrator init --mgpath node_modules/ghost I get this error message:

NAME: RollbackError
CODE: ER_ACCESS_DENIED_ERROR
MESSAGE: ER_ACCESS_DENIED_ERROR: Access denied for user 'root'@'cloudsqlproxy~[SOME_IP_ADDRESS]' (using password: NO)

Running knex-migrator init --mgpath node_modules/ghost works just fine, and I can launch the app locally with no problems. It's only the I try to setup the app for production that I get problems.

EDIT: I can connect to the db via MySQL Workbench, using the same credentials I'm using in the config below

Here's my config.production.json (with private data removed):

{
    "production": {
        "url": "https://MY_PROJECT_ID.appspot.com",
        "fileStorage": false,
        "mail": {},
        "database": {
            "client": "mysql",
            "connection": {
                "socketPath": "/cloudsql/MY_INSTANCE_CONNECTION_NAME",
                "user": "USER",
                "password": "PASSWORD",
                "database": "DATABASE_NAME",
                "charset": "utf8"
            },
            "debug": false
        },
        "server": {
            "host": "0.0.0.0",
            "port": "2368"
        },
        "paths": {
            "contentPath": "content/"
        }
    }
}

And app.yaml:

runtime: nodejs
env: flex
manual_scaling:
  instances: 1
env_variables:
  MYSQL_USER: ******
  MYSQL_PASSWORD: ******
  MYSQL_DATABASE: ******
  # e.g. my-awesome-project:us-central1:my-cloud-sql-instance-name
  INSTANCE_CONNECTION_NAME: ******
beta_settings:
  # The connection name of your instance on its Overview page in the Google
  # Cloud Platform Console, or use `YOUR_PROJECT_ID:YOUR_REGION:YOUR_INSTANCE_NAME`
  cloud_sql_instances: ******

# Setting to keep gcloud from uploading not required files for deployment
skip_files:
  - ^(.*/)?#.*#$
  - ^(.*/)?.*~$
  - ^(.*/)?.*\.py[co]$
  - ^(.*/)?.*/RCS/.*$
  - ^(.*/)?\..*$
  - ^(.*/)?.*\.ts$
  - ^(.*/)?config\.development\.json$

Solution

  • I figured out the problem.

    My config file shouldn't have the "production" property. My config should look like this:

    {
            "url": "https://MY_PROJECT_ID.appspot.com",
            "fileStorage": false,
            "mail": {},
            "database": {
                "client": "mysql",
                "connection": {
                    "socketPath": "/cloudsql/MY_INSTANCE_CONNECTION_NAME",
                    "user": "USER",
                    "password": "PASSWORD",
                    "database": "DATABASE_NAME",
                    "charset": "utf8"
                },
                "debug": false
            },
            "server": {
                "host": "0.0.0.0",
                "port": "8080"
            },
            "paths": {
                "contentPath": "content/"
            }
    }
    

    It now overrides the default config.

    The only issue is that you can't use knex-migrator with the "socketPath" property set, but this is needed to run the app in the cloud.