2024/12/18 背景部分で勘違いをしていたことが分かったので修正いたしました。
はじめに
AWS EC2インスタンス内のDockerで立ち上げたWebアプリのcurlエラーの解決に苦戦したので備忘録を残します。
docker.socketの話だけ読みたい方は、背景を読み飛ばしてください。
背景
curl: (56) Recv failure: Connection reset by peer が1か月以上解決しなかった話
docker内のFlaskで実装したAPIをEC2のcurlで定時実行させようとしたところ上記エラーが発生しました。また、1度curlを実行した後、再度実行するとうまくcurlが実行されました。
当時の状況
EC2インスタンス起動時
docker.service:自動起動しない(preset; disabledになっている)

docker.socket:自動起動する(preset; enableになっている)

Flaskが反応しなかった理由
docker.service
→ 自動起動しない
→ docker composeのrestart alwaysが効かない
→ Flaskが起動しない
→ curlが失敗する
dockerコマンドを打った後に使えるようになった理由
docker.socket
→ 自動起動している
→ dockerコマンドを打つと、docker.socketに通信が飛んでいく
→ docker.socketは停止しているdocker.serviceを起動しようとする
→ dockerコマンド実行後は、docker.serviceが起動してrestart alwaysが動き出す
→ Flaskが起動する
→ curlが成功する
当時の対応
以下コマンドを実行して、docker.serviceを自動起動するように設定しました。
sudo systemctl enable docker
実行後、以下のようにdocker.serviceが自動起動する設定にすることができ、無事エラーを解決することができました。

余談
以下コマンドでステータス(現在の状態とプリセット)を一覧できます。
例はdocker関連の情報だけに絞って表示させています。
sudo systemctl list-unit-files | grep docker.s
docker.socketとはなんぞや?
一言でいうと…
docker デーモンと(docker CLIなどの)クライアント間の通信を管理するコンポーネント
そもそもDocker Engineの仕組みとは?
ドキュメントによると、Docker Engineは以下の3要素からなります。
- docker CLI
- REST API
- docker デーモン

(参照:Docker 概要 — Docker-docs-ja 1.12.RC2 ドキュメント)
docker CLIで(docker buildなどの)コマンドを実行すると、UNIXソケットやTCPソケットを介して、docker デーモンにアクセスします。(ソケットパス:/var/run/docker.sock)docker.socketはそのソケットの設定を管理しているようです。

(参照:Docker 概要 — Docker-docs-ja 1.12.RC2 ドキュメント)
-
ListenStream=/var/run/docker.sock- リッスンする場所を指定しています。
- docker CLIはこのソケット経由で通信が行われていそうです。
このように、ソケットに関する設定が記述されていることが分かりました。
さいごに
今回は、docker.socketに関するエラーでハマったので、その際調べたことなどを記録しました。今回のような状態になってしまった理由などはわからずじまいですが、Dockerの仕組みについて学びなおすいいきっかけにはなったかなと思います。

