Skip to content

Instantly share code, notes, and snippets.

@buzztaiki
Last active June 20, 2025 23:55
Show Gist options
  • Save buzztaiki/9191a4c13f9894527ea83bd6f2dbe6aa to your computer and use it in GitHub Desktop.
Save buzztaiki/9191a4c13f9894527ea83bd6f2dbe6aa to your computer and use it in GitHub Desktop.
rootless docker

rootless docker

とりあえずは https://wiki.archlinux.org/title/Docker#Rootless_Docker_daemon に従えばインストールできて普通に動く。コンテナ側で root ユーザーが作ったファイルのオーナーが自分になってくれるのがとても助かる。

/etc/subuid, /etc/subgid は両方とも以下としている。自分で決めたのか、docker-rootless-extras が設定してくれたのかは覚えてない。

taiki:100000:65536

ベストプラクティス

https://docs.docker.com/engine/security/rootless/#best-practices

設定ファイルの場所

~/.config/docker/daemon.json

コンテナで 443 をリッスンできるようにする

何もしないとこんなエラーが出る

Error response from daemon: driver failed programming external connectivity on endpoint xxxx (d822ea73671d589020b511af00be5764d13004b4de9b6f838c4615c51e53bbcd): failed to bind port 0.0.0.0:443/tcp: Error starting userland proxy: error while calling PortManager.AddPort(): cannot expose privileged port 443, you can add 'net.ipv4.ip_unprivileged_port_start=443' to /etc/sysctl.conf (currently 1024), or set CAP_NET_BIND_SERVICE on rootlesskit binary, or choose a larger port number (>= 1024): listen tcp4 0.0.0.0:443: bind: permission denied
error: Recipe `up` failed on line 103 with exit code 1

sysctl で 443 を unprivilege にするのは怖いから setcap する。

❯❯ getcap /usr/sbin/rootlesskit

❯❯ sudo setcap cap_net_bind_service+ep /usr/sbin/rootlesskit

❯❯ getcap /usr/sbin/rootlesskit
/usr/sbin/rootlesskit cap_net_bind_service=ep

/var/run/docker.sock が使いたい

ユーザー権限で動いてるから $XDG_RUNTIME_DIR/docker.sock にある。compose.yaml は大体固定でパスが書かれてたりするから、そのへんは何とかする。

host.docker.internal:host-gateway を使えるようにする

何もしないと connection refused になる。

この辺を参考にする

以下のどっちかになるっぽい

  • DOCKERD_ROOTLESS_ROOTLESSKIT_DISABLE_HOST_LOOPBACK=false を設定する
    • セキュリティ上の理由で無効になってるみたいポートが限定できればいいのにね。
  • nsenter と socat でコンテナからの通信を sock ファイル経由でホストのポートに転送する

セキュリティ的によろしくはないけど面倒だから host loopback を有効にする方向で

host loopback を有効にする

dockerd-rootless.sh には以下のように書いてある。slirp4netns の場合は 10.0.2.2 に接続できるようになるのだそう。

# * DOCKERD_ROOTLESS_ROOTLESSKIT_DISABLE_HOST_LOOPBACK=(true|false): prohibit connections to 127.0.0.1 on the host (including via 10.0.2.2, in the case of slirp4netns). Defaults to "true".

このアドレスについての slirp4netns のドキュメントは以下:
https://github.com/rootless-containers/slirp4netns/blob/master/slirp4netns.1.md

まず host loopback を有効にする

❯❯ cat ~/.config/systemd/user/docker.service.d/override.conf
[Service]
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_DISABLE_HOST_LOOPBACK=false"

これだけだと、host-gateway は 172.17.0.1 (docker network の gateway address) のまま。

❯❯ docker run -it --add-host host.docker.internal:host-gateway busybox cat /etc/hosts | grep -e 'host.docker.internal'
172.17.0.1      host.docker.internal

~/.config/docker/daemon.jsonhost-gateway-ips を設定する。

❯❯ cat ~/.config/docker/daemon.json
{
  "host-gateway-ips": ["10.0.2.2"]
}

そうすると 10.0.2.2 になる。

❯❯ docker run -it --add-host host.docker.internal:host-gateway busybox cat /etc/hosts | grep -e 'host.docker.internal'
10.0.2.2        host.docker.internal

これでホスト側に繋がるようになる。

❯❯ busybox httpd -p 9999 -h ~/tmp/

❯❯ docker run -it --add-host host.docker.internal:host-gateway busybox wget -O- http://host.docker.internal:9999/a.md | wc -l
804
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment