はじめに
一つのDocker Composeの中であれば、はじめから各コンテナはお互いに通信可能です。
デフォルトで Compose はアプリに対して1つの ネットワーク を作成します。サービス用の各コンテナはデフォルトのネットワークに接続し、そのネットワーク上で他のコンテナと相互に「 接続可能reachable 」になります。
https://docs.docker.jp/compose/networking.html
しかし複数のDocker Compose間の通信はデフォルトの状態ではできません。
そこで、Docker Composeのネットワーク機能を使って複数のDocker Composeを通信可能にしよう、というのがこの記事の趣旨です。
環境
- M1 Mac macOS Monterey12.1
- Docker 20.10.20
- Docker Desktop 4.13.1
ネットワーク機能を使う
今回は例として「一つのDBコンテナを複数のDocker Compose間で共有する」というケースを考えてみます。
リポジトリhogeのDBコンテナをリポジトリfugaでも使いたい状況です。
まず最終的なディレクトリ・ファイル構成を載せておきます。
.
├── fuga
│ ├── Dockerfile
│ ├── docker-compose.yml
│ ├── go.mod
│ ├── go.sum
│ └── main.go
└── hoge
└── docker-compose.yml
version: '3'
services:
db:
image: postgres
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: password
volumes:
- db-store:/var/lib/postgresql/data
volumes:
db-store:
version: '3'
services:
go:
build: .
tty: true
networks:
default:
name: hoge_default
external: true
Dockerfile
FROM golang:1.19.4-bullseye
COPY . /go/src
WORKDIR /go/src
CMD ["/bin/bash"]
まずhogeのdockerコンテナを立ち上げます。
$ docker compose up -d
次にdbコンテナに入ります。
$ docker compose exec db /bin/bash
root@5498c9cec982:/#
postgresを操作して適当なデータを入れておきます。
root@5498c9cec982:/# psql -U postgres
> psql (15.1 (Debian 15.1-1.pgdg110+1))
> Type "help" for help.
postgres=#
postgres=# alter table postgres with encrypted password '1234';
postgres=# create table books (id serial, name varchar(255), author varchar(255));
> CREATE TABLE
postgres=# insert into books values (1, 'H✖️H', '冨樫');
> INSERT 0 1
postgres=# select * from books;
id | name | author
----+------+--------
1 | H✖️H | 冨樫
(1 row)
今度はfugaのDocker Composeを立ち上げます。
$ docker compose up -d
ここでmain.goのコードを覗きますが、ここでのミソはDBのホストにdbコンテナを指定している点です。
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
)
type BOOKS struct {
ID string
Name string
Author string
}
func main() {
// DBのホストにdbコンテナを指定している
db, err := sql.Open("postgres", "host=db port=5432 user=postgres password=1234 dbname=postgres sslmode=disable")
defer db.Close()
if err != nil {
fmt.Println(err)
}
rows, err := db.Query("SELECT * FROM books")
if err != nil {
fmt.Println(err)
}
var es []BOOKS
for rows.Next() {
var e BOOKS
rows.Scan(&e.ID, &e.Name, &e.Author)
es = append(es, e)
}
fmt.Println("%v", es)
}
goのコンテナに入ってコードを実行してみます。
$ docker compose exec go /bin/bash
root@e3a1ce68206a:/go/src#
root@e3a1ce68206a:/go/src# go run main.go
> %v [{1 H✖️H 冨樫}]
fugaのコンテナからhogeのdbコンテナにアクセスしてbooksテーブルのレコードを取得できました🎉
詳しく見る
fugaのdocker-compose.ymlでnetworksを指定しています。
この定義でネットワークを共有することで各コンテナ間の通信を可能にしています。
version: '3'
services:
go:
build: .
tty: true
networks:
default:
name: hoge_default
external: true
ここでnetworksの定義の意味は以下のとおりです。
- networks・・・ネットワークの定義
- default・・・fugaのDocker Compose環境のコンテナすべてに以下のネットワークを指定する
- name・・・定義したいネットワークの名前
- external・・・既存のネットワークを使用するにはtrueを指定する
冒頭で「一つのDocker Composeの中であれば、はじめから各コンテナはお互いに通信可能です。」という話をしました。
デフォルトで Compose はアプリに対して1つの ネットワーク を作成します。サービス用の各コンテナはデフォルトのネットワークに接続し、そのネットワーク上で他のコンテナと相互に「 接続可能reachable 」になります。
https://docs.docker.jp/compose/networking.html
このネットワークの「名前」は何も指定しなければ「ディレクトリ名 + _default」となります。
なのでhogeディレクトリのネットワーク名は「hoge_default」となり、このネットワーク名をnameに指定しているというわけです。
以下コマンドで現在作成されているネットワークの一覧を取得できます。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
5d0e5ea33cb1 bridge bridge local
1ceaf292e9bb hoge_default bridge local
8e686400f1a3 host host local
4c404bd7f6af none null local
bridge、host、noneはDockerのインストール時に自動で作成されているネットワークです。
また、docker inspectコマンドでネットワークが共有されていることを確認できます。
※ContainersにそれぞれのDocker Composeのコンテナ(hoge-db-1、fuga-go-1)が含まれていることが分かります。
$ docker network inspect 1ceaf292e9bb
[
{
"Name": "hoge_default",
"Id": "1ceaf292e9bb5580b79e11f8b6070085bc861a736457b1873c9fed994f682ab7",
"Created": "2022-12-08T00:52:35.359427213Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "********",
"Gateway": "********"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"5498c9cec982201befa9a2fe74e6165721c7077b556af3c4f55b3f2d7e410479": {
"Name": "hoge-db-1",
"EndpointID": "108308bbd26820b272630a7c846ebd702798317ace71aab11bebc385f728fe80",
"MacAddress": "********",
"IPv4Address": "********",
"IPv6Address": ""
},
"e3a1ce68206a554a2babc8b82cd631b9c9fb64f11b779034f9635ac94b4e8795": {
"Name": "fuga-go-1",
"EndpointID": "2ec20e292c07e9ec945553cf2b3c8d7ff4b74f056633a8797b07abcf98a2e3c3",
"MacAddress": "********",
"IPv4Address": "********",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "default",
"com.docker.compose.project": "hoge",
"com.docker.compose.version": "2.12.1"
}
}
]
以上になります。
Dockerネットワークで快適なDockerライフをお過ごしください。
最後に
GoQSystemでは一緒に働いてくれる仲間を募集中です!
ご興味がある方は以下リンクよりご確認ください。