この記事が役立つかもしれない人
- タイトル通りの状況にある人
-
docker-compose stop
とdocker-compose down
の違いに不安がある人 - Supabase CLI のソースコードに興味がある人
状況
次のような Makefile で起動・停止を行なっていました。
ここで重要なのは自前の Docker 環境を docker compose up
で起動して docker compose stop
で停止を行なっている点です。
.PHONY: start supabase-start services-start stop services-stop supabase-stop
# 起動
start: supabase-start
make services-start
supabase-start:
supabase start
services-start:
docker compose up -d
# 停止
stop: services-stop
make supabase-stop
services-stop:
docker compose stop
supabase-stop:
supabase stop
すると二度目以降の make start
(docker compose up
) でエラーが現れます。
Error response from daemon: network (ここに NETWORK ID が入る) not found
解決方法
docker compose stop
を docker compose down
に直す!
.PHONY: start supabase-start services-start stop services-stop supabase-stop
# 起動
start: supabase-start
make services-start
supabase-start:
supabase start
services-start:
docker compose up -d
# 停止
stop: services-stop
make supabase-stop
services-stop:
- docker compose stop
+ docker compose down
supabase-stop:
supabase stop
なぜ docker compose stop
だとエラーが起きるのか?
Docker Compose の stop
と down
の違い
docker compose stop
は 実行中のコンテナを削除せずに停止 します。名前の通りですね。
停止したコンテナは再起動可能な状態で維持されます。そのため次回 docker compose up
を実行した際はネットワークとコンテナが再利用されます。
一方で docker compose down
はコンテナを停止して docker compose up
によって作成された コンテナとネットワークを削除 します。オプションを付ければボリュームとイメージも消せます。
Docker Compose 全体のざっくりとした流れとしては以下の通りです。
-
docker compose up
で実行: コンテナがなければイメージがビルドされてコンテナが作成・起動され、停止・削除されるまで稼働 -
docker compose down
で削除: 再びdocker compose up
された時は上記と同じように処理が走る
では 、docker compose stop
された後に docker compose up
を行うとどうなるでしょうか?
これは compose.yml が変更されたかどうかによって変わります。
変更されていた場合、docker compose up
はコンテナを停止して再作成することで変更を拾います。このときボリュームだけは残るため docker compose down
とは少々動きが異なります。
supabase stop
のコード内容
オープンソースなので Supabase CLI のソースコードを見てみましょう!
かいつまんで中身を見てみると supabase stop
は cli/internal/utils /docker.go
にある DockerRemoveAll
関数を呼び出しているみたいです。
コードを見てみると down
ではなく stop
していそうです……
Docker.ContainerStop(ctx, id, container.StopOptions{});
……が、読み進めてみるとネットワークを消しとる!!!
// Remove networks.
if report, err := Docker.NetworksPrune(ctx, args); err != nil {
return errors.Errorf("failed to prune networks: %w", err)
} else if viper.GetBool("DEBUG") {
fmt.Fprintln(os.Stderr, "Pruned network:", report.NetworksDeleted)
}
改めて docker network ls
を叩いてみても分かります。
% docker network ls
NETWORK ID NAME DRIVER SCOPE
acabacebaf48 supabase_network_test bridge local
% docker network ls
NETWORK ID NAME DRIVER SCOPE
3dcc14f257fa supabase_network_test bridge local
NETWORK ID がころころ変わっとる!!!
具体的なエラー発生のメカニズム
-
supabase start
実行時: Supabase のコンテナが多数立ち上がりネットワークが作成される - 初回の
docker compose up
実行時: コンテナが作成されてsupabase start
によって作成されたネットワーク内で起動 -
docker compose stop
実行時: コンテナは停止されますが、ネットワークはそのまま残る -
supabase stop
実行時: Supabase CLI によってネットワークが削除されます - 再度
docker compose up
を実行: Docker Compose は前回使用したネットワークを再利用しようとするが、そのネットワークは既に削除されているため network not found エラーが発生する
まとめ
というわけで supabase stop
という名前に騙され、同じように docker compose stop
を設定してしまった私ですが、supabase stop
がネットワークを消しているなら docker compose stop
ではいけませんね。
なぜならば docker compose stop
は docker compose up
で作られたときのまま。Supabase CLI によってネットワークが削除されて新しく作られていることを知らない状態で停止しているからです。そのため docker compose stop
を docker compose down
に変える必要があったわけです。
名前や雰囲気で中身を決めつけてはいけないですね。反省です。
この記事が役に立ったら 🩷 を頂けると嬉しいです!