💡
Cloud Functions + Cloud SQL をローカルで立ち上げようとしてSocket Pathでハマった
概要
- Cloud Functions内でCloud SQLにアクセスしたかった
- Cloud Functionsをローカルでテストしたかった(DB自体はリモート)
実装
Cloud FunctionsのローカルテストにはFunctions Frameworkを使います。
また、Cloud SQLにローカルから接続するにはCloud SQL Auth Proxyを使います。
実装
.
├── functions/
│ ├── build/
│ ├── cloudsql/
│ ├── src/
│ │ └── index.ts
│ ├── cloud_sql_proxy
│ ├── package.json
│ ├── package-lock.json
│ ├── tsconfig.dev.json
│ ├── tsconfig.json
├── .firebaserc
└── firebase.json
Cloud SQL Auth Proxyを立ち上げます。
$ ./cloud_sql_proxy -dir=cloudsql -instances=myproject:myregion:myinstance
functions/cloudsql/
内にmyproject:myregion:myinstance
と同名のファイルができるはずです。
その状態で、別コンソールからfunctionのemulatorを立ち上げます。
$ firebase emulators:start --only functions:myfunction
ハマった
至る所でこれが出まくるのに悩まされました。
$ Error: connect ENOENT /cloudsql/myproject:myregion:myinstance
env.DB_SOCKET_PATH
デプロイ時はprocess.env.DB_SOCKET_PATH
にソケットが立つようです。(ちゃんと確かめてないですが多分"cloudsql"
とかだと思います)
ローカルでの実行ではその環境変数がないので、/cloudsql
を指定しておきます。
TypeORMを使っているのでentities
とかありますが、他のサービスでも基本同じ感じです。socketPath
が大事。
datasource.ts
const dbSocketPath = process.env.DB_SOCKET_PATH || "/cloudsql";
export const AppDataSource = new DataSource({
type: "mysql",
socketPath: `${dbSocketPath}/myproject:myregion:myinstance`,
username: *******, // ここら辺も
password: *******, // 適宜
database: *******, // 変えてください
entities: [
"./build/entity/**/*.js"
],
})
まとめ
- デプロイ時のルートは
functions
直下 - デプロイ時は
process.env.DB_SOCKET_PATH
にソケットが立つ
Discussion