部署Nest.Js至GAE(四):連接cloud sql

前言

使用Nest.Js開發,通常都會相應使用typeOrm連接資料庫
開發時期連接本機資料庫都有相當多的教學,單純、簡單
若是內部系統,有自己的Server,大至上都跟開發時期差不多
但部署到GCP就不一樣了
雖然Cloud SQL也有提供靜態IP,但直接使用他提供的名稱更優

解法其實網路上就有,但要下對關鍵字…
我一開始都用Nest.Js connect cloud sql 等關鍵字來找,就是沒有答案
還想到這到底是多困難
最後想到Nest.Js本質是typeOrm,才找到解法= =…

連線方式

在GCP設定好Cloud SQL後
到其主頁面的連線名稱可以看到project:region:instance

如下範例調整

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "default",
"type": "mysql",
"extra": {
"socketPath": "/cloudsql/{project:region:instance}"
},
"username": "root",
"password": "xxxx",
"database": "yyy",
"synchronize": true,
"logging": false,
"entities": [
"dist/**/*.entity.js"
]
}

參數寫法

Nest.Js/configuration的寫法其實滿少資訊的
分享自己的寫法供參考
開發模式時連接本地DB、部署到GCP時連接Cloud SQL

共會有3個檔案:database.config.tsdatabase.development.yamldatabase.production.yaml
主要是將dev、prod會不同的參數拉至yaml檔
共同且不太會異動的參數寫在ts裡

database.development.yaml

1
2
3
4
5
6
7
host: 'localhost'
port: 5432
username: 'dev'
password: 'dev'
database: 'demo'
logging: true
synchronize: true

database.production.yaml

1
2
3
4
5
6
7
8
host: /cloudsql/{project:region:instance}
extra:
socketPath: /cloudsql/{project:region:instance}
username: 'app'
password: 'pwd'
database: 'prod_db'
logging: false
synchronize: false

database.config.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { registerAs } from "@nestjs/config";
import { readFileSync } from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';

const YAML_CONFIG_FILENAME = `database.${process.env.NODE_ENV}.yaml`;

export default registerAs('database', () => {
const yamlConfig = yaml.load(
readFileSync(join(process.cwd(), 'environment', YAML_CONFIG_FILENAME), 'utf8'),
) as Record<string, any>;

return {
retryAttempts: 10,
retryDelay: process.env.NODE_ENV === 'development' ? 5 * 1000 : 30 * 1000,
type: 'postgres',
entities: [`dist/**/*.entity.js`],
logger: 'file',
autLoadEntities: true,
...yamlConfig
};
});

後記

我當初照著輸入時仍一直連線失敗,gcloud部署一次又要2~3分鐘
重新部署了N次才發現,我yaml寫錯了….

因為我有使用官方的configuration模組,並將參數yaml化
而找到的網路資訊都是jsonts物件

且當初只想快速測試,extra參數很直覺地貼上:

1
2
3
4
host: /cloudsql/{project:region:instance},
extra: {
socketPath: /cloudsql/{project:region:instance}
}

而當初又尚未連接 cloud logging,故當時完全不知錯誤原因
Nest.Js一執行,parse yaml時就直接噴錯了,根本執行不了
而且還很白痴的host連最後面的,一起複製上去= =

明明是件很簡單的事情,卻也卡了我2、3小時-.-

參考資料

stack overflow / Typical ormconfig.json file for Google Cloud SQL?

系列文章

部署Nest.Js至GAE系列文章