docker-composeでソケットを共有する
- 共通ボリュームを作成
- 参照したいソケットのあるコンテナのソケット位置を共通ボリュームに接続
- 参照する側のコンテナに共通ボリュームをマウント
でOKです。
以下、とあるAPIサーバからMySQLに繋ぐときの例です。
version: "3.7"
services:
api:
build:
context: .
dockerfile: ./Dockerfile
ports:
- "8080:8080"
environment:
# (Optional) アプリから参照するときは環境変数からソケット位置を取る
- DB_SOCKET: /var/run/mysqld/mysqld.sock
depends_on:
- db
volumes:
- dbsocket:/var/run/mysqld # ↓で共有しているソケットファイルディレクトリを任意の位置にマウント
db:
image: mysql:5.7.26
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test
MYSQL_USER: test
MYSQL_PASSWORD: test
ports:
- "3306:3306"
volumes:
- dbsocket:/var/run/mysqld # mysqldソケットファイルディレクトリを共有
volumes:
dbsocket: # 共通ボリュームを作成
参照する側にも同じディレクトリがあるとぶつかって予期せぬことが起こりそうなので、
ソケット共有したいディレクトリが参照側のコンテナにも既に存在するのであれば
別の位置にしたほうが良いと思います。
例では参照する側(APIコンテナ)の/var/run/mysqld
は存在しないので、
わかりやすくmysqlコンテナと同じ位置にマウントしています。
コンテナ間ソケット通信が必要になった背景
主にCloud Runのせいです←
GCPのCloud RunからCloud SQLに繋ぐとき、GoogleはCloud SQL Proxyを介して
ソケット通信する方法を推奨しています。そうなると、本番環境はソケット通信ですが
通常のdocker-compose方式の開発であればローカルDBへは普通にTCP接続するので、
組み立てるコネクションストリング形式をローカル環境と本番環境で分岐する必要があります。
が、個人的には余計なトラブルを防ぐため環境差異をできるだけ無くし
ローカルもソケット接続にして同じコネクションストリングを使用したく、
やり方を模索していたところ案外あっさり行けたので記事起こししました。