現象
GCP の Cloud SQL に接続する際の選択肢の一つとして多用される Cloud SQL Auth Proxy は、公式の Docker イメージが配布されておりどんな環境でも簡単に実行することができます。
version: '3'
services:
cloud-sql-proxy:
image: gcr.io/cloudsql-docker/gce-proxy:latest
volumes:
- ./cloudsql:/cloudsql
restart: always
command: "/cloud_sql_proxy -instances=project-id:region-name:instance-name -dir=/cloudsql"
ただ、同じ docker-compose を走らせているはずでも、一部の環境でのみ以下のようなエラーが発生することがあります。
listen unix /cloudsql/project-id:region-name:instance-name/.s.PGSQL.5432: bind: invalid argument
原因
bind: invalid argument
エラーは、UNIXドメインソケットのパスが「長すぎる」場合に起こります。
一般に、UNIXソケットのパス文字列の長さは104chars
までと決まっているようです。
ここで気をつけなければならないのは、「ホスト側のUNIXドメインソケットのフルパスもこの制約を受ける」ということです。
つまり、
/cloudsql/project-id:region-name:instance-name/.s.PGSQL.5432
仮にこのパスの長さが104chars
を超えていなくても、
/Users/taro-yamada/Documents/dev/my-awesome-company/my-awesome-project/cloudsql/project-id:region-name:instance-name/.s.PGSQL.5432
ルートからの絶対パス、長くないですか?これを短くすればエラーは解決します。
解決
この問題を解決する方法は主に二つ(思いつく限り)です。
① プロジェクトの階層を浅くして、ディレクトリ名を短く
力技ですがw、デバッグ時はこれで無理やり動作検証しました。
② ソケット名をカスタマイズ
後から気づいたのですが、./cloud_sql_proxy -help
に以下のような記述がありました。
To set a custom socket name, you can specify it as part of the instance
string. The following example opens a unix socket in the directory
specified by -dir, which will be proxied to connect to the instance
'my-instance' in project 'my-project':
-instances=my-project:my-region:my-instance=unix:custom-socket-name
というわけで、インスタンス名の後ろに =unix:hogefuga
を付加してあげれば、長いソケット名を使わずに済むようですね。
うーんなんかどっちも対処療法的な気がしますが、UNIXソケットをプロジェクトフォルダ内に収めておきたいのであれば、対処法はこれくらいでしょうか。
初出時に半日ほど溶かしてしまったので、備忘録としてメモしておきます。