前置き
Docker Desktop for Macの代替として、昨年秋頃よりDocker+limaの環境を新たに構築し使用しています。Dockerのコンテナエンジンをlimaに乗り換えてからは時折詰まることもある一方、概ね良好に使えており魅力を感じています。
さて、limaの環境に乗り換えてから初めてDjango+MySQLでWebアプリケーション制作を試みていました。しかし、ホスト (Mac) からコンテナ内で動いているWebアプリケーションにアクセスしようとしても、Connection Refused
となり、解決に苦労しました。
問題を解決した際の備忘録です。
何が起きたか
# Host (Mac) 側でWebアプリケーションにアクセス不可
$ curl localhost:8080
curl: (7) Failed to connect to localhost port 8080: Connection refused
# Docker Containerは正常に稼働
$ docker logs [Djangoのコンテナ]
...(略)...
Starting development server at http://0.0.0.0:8080/
Quit the server with CONTROL-C.
...(略)...
$ docker logs [MySQLのコンテナ]
...(略)...
2023-01-08 06:17:56+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.40-1.el7 started.
...(略)...
# limaのVM内からは正常にアクセス可能
$ export LIMA_INSTANCE=docker
$ lima
(lima-docker)$ curl localhost:8080
<!doctype html>
<html lang="en-us" dir="ltr">
...(略)...
前提ですが、Djangoが異常終了していたりしてもConnection Refusedになります。 下記の手法はあくまで、limaのVM内でのアクセスが確認できたにもかかわらず、ホストから疎通が取れない場合に解決した手順になります。
解決
環境構築の際、limaのVMインスタンスdefault
とdocker
を作成していました。前者default
はlimaのお試しで、デフォルトのコンフィグを使用して作成したものです。すでに使用しておらず、放置していました。
$ limactl list
NAME STATUS SSH VMTYPE ARCH CPUS MEMORY DISK DIR
default Stopped 127.0.0.1:0 qemu x86_64 4 4GiB 100GiB ~/.lima/default
docker Running 127.0.0.1:50738 qemu x86_64 4 4GiB 100GiB ~/.lima/docker
VMのインスタンスが二つあることでポートフォワーディングがうまくいっていないのではないか、ということを思い立ちました。以下の手順を試みたところ解決ができました。
# defaultインスタンス削除
$ limactl delete default
# `docker`インスタンスのlima.yaml (~/.lima/docker/lima.yaml) に明示的にポートフォワーディングを指定 (不要かもしれません)
$ vim lima.yaml
...(略)...
portForwards:
- guestSocket: "/run/user/{{.UID}}/docker.sock"
hostSocket: "{{.Dir}}/sock/docker.sock"
# 以下を追記
- guestIP: "127.0.0.1"
guestPortRange: [1024, 65535]
hostIP: "127.0.0.1"
hostPortRange: [1024, 65535]
# dockerインスタンス再起動
$ limactl stop docker
$ limactl start docker
...(略)...
To run `docker` on the host (assumes docker-cli is installed), run the following commands:
------
docker context create lima-docker --docker "host=unix:///Users/[ユーザ名]/.lima/docker/sock/docker.sock"
docker context use lima-docker
docker run hello-world
------
# dockerコンテキスト再指定 (色々と環境をいじっていたので、これの再設定が大事だった可能性があります。)
$ docker context create lima-docker --docker "host=unix:///Users/[ユーザ名]/.lima/docker/sock/docker.sock"
$ docker context use lima-docker
# コンテナ再起動
$ docker compose down
$ docker compose up -d
# ホストからも無事アクセスを確認
$ curl localhost:8080
<!doctype html>
<html lang="en-us" dir="ltr">
...(略)...
上記の手順の中のどれが有効打だったのかわかりませんが、おそらくこの中のどれかだと思われます。
- 使用していないVMインスタンスの削除
- ポートフォワーディングの明示
- dockerコンテキスト再指定
ここで、2. についてはconfigの例にも下記の記述があるので、正直不要な気がしています。
# # Lima internally appends this fallback rule at the end:
# - guestIP: "127.0.0.1"
# guestPortRange: [1, 65535]
# hostIP: "127.0.0.1"
# hostPortRange: [1, 65535]
# # Any port still not matched by a rule will not be forwarded (ignored)
以上、同じ現象で困っている方の助けになれれば幸いです。