Search code examples
linuxdockernetwork-programmingdocker-composehomebridge

Cannot reach port of container running in host mode


I've been trying to run homebridge in a container on a raspberry pi, here is the docker-compose.yaml definition:

services:
  homebridge:
    image: homebridge/homebridge:latest
    container_name: homebridge
    restart: always
    network_mode: host
    environment:
      - PGID=1099
      - PUID=1099
      - HOMEBRIDGE_CONFIG_UI=1
      - HOMEBRIDGE_CONFIG_UI_PORT=8581
    volumes:
      - /raid/config/homebridge:/homebridge

The application starts successfully and I can see in the logs that the HTTP server is up and running:

[10/3/2024, 10:30:14 PM] [Homebridge UI] Homebridge UI v4.59.0 is listening on :: port 8581

Now if I curl the port I get a connection refused:

$ curl localhost:8581
curl: (7) Failed to connect to localhost port 8581: Connection refused

What doesn't make sense to me is that if I exec into the container and do the exact same thing, the call goes through:

$ docker exec -it 3783843255f7 /bin/bash
Note: This is a restricted shell, sudo cannot be used here.

Homebridge Terminal

Node.js Version: v20.17.0
Node.js Path: /opt/homebridge/bin/node
Plugin Path: /var/lib/homebridge/node_modules

Update Node.js: hb-service update-node

Install Plugin: hb-service add homebridge-plugin-name
Remove Plugin: hb-service remove homebridge-plugin-name

root@tardis:/homebridge $ curl localhost:8581
<!doctype html>
<html lang="en">
...

Why isn't the 8581 port accessible from the outside even though the container is running in host network mode?


Solution

  • It's running rootless

    That's a different network namespace:

    Host network (docker run --net=host) is also namespaced inside RootlessKit.

    https://docs.docker.com/engine/security/rootless/#known-limitations

    When docker is running rootless, inside of a container (docker-in-docker, snap), inside a VM (docker desktop, or accessing a remote docker engine), then localhost for the docker engine is not the same as localhost of the user executing the CLI.