Dockerode Integration#
Homepage uses dockerode (^5.0.0) as its Docker API client to connect to the Docker daemon β primarily via the Unix socket /var/run/docker.sock on Linux . All Docker-related features (container status, stats, and service discovery from labels) go through this single library.
Architecture#
Connection arguments are built centrally in src/utils/config/docker.js. Key behavior:
- Default (Linux):
{ socketPath: "/var/run/docker.sock" } - Default (Windows/macOS):
{ host: "127.0.0.1" } - Named servers (via
docker.yaml): Supportssocket,host,port,protocol,headers, and TLS options (ca,cert,key) - Swarm mode is toggled per server via the
swarmflag indocker.yaml
Dockerode is instantiated with new Docker(getDockerArguments(server).conn) in three places:
| File | Purpose |
|---|---|
src/utils/docker/status.js | Container status and health queries |
src/utils/docker/stats.js | CPU, memory, and network stats |
src/utils/config/service-helpers.js | Service discovery from Docker labels |
A new dockerode connection is opened on each request β there is no persistent connection pool.
v4 β v5 Migration (June 2026)#
PR #6736 (merged 2026-06-03) bumped dockerode from 4.0.10 to 5.0.0. Changes in the upstream release:
- Dropped the
uuidpackage dependency - Bumped minimum Node.js version requirement
- Upgraded
protobufjsfrom 7.3.2 to 7.5.5 (used internally for gRPC-style features)
No Homepage application code was modified β only package.json changed .
Known Issue: Synology EACCES on /var/run/docker.sock#
Symptom: Error: connect EACCES /var/run/docker.sock on every dashboard load, first appearing around v2.3.0, on Synology NAS hosts running Container Manager .
What was ruled out:
- Socket permissions are normal (
srw-rw---- 1 root root) - The Homepage container runs as root (
uid=0) β confirmed viadocker exec homepage id - Other containers (e.g., Uptime Kuma) access the same socket without issue
- The
docker.yamlconfig and compose file are valid
Root cause hypothesis: dockerode v5 changed docker-modem internals that alter how the Unix socket connect() syscall is issued. This appears to interact with Synology Container Manager's per-image confinement profiles (AppArmor/seccomp) differently from v4 .
Why v2.3.0 surfaced it more visibly: v2.3.0 replaced per-service endpoints (/api/docker/status/[...service], /api/docker/stats/[...service]) with bulk endpoints (/api/docker/statuses, /api/docker/stats) that query Docker on every dashboard load, making the failure impossible to miss .
Workarounds#
-
Use a Docker socket proxy (recommended) β avoids direct socket access entirely. See the Homepage docs on socket proxies.
-
Try a pre-v5 image β a v2.1.x image (released before the June 2026 dockerode bump) can help confirm whether the failure is v5-specific in your environment . Note: running old images is not a long-term solution.
-
Check for Synology socket path changes β Some DSM versions relocate the socket (e.g., to
/var/packages/ContainerManager/var/docker.sock), leaving a stale mount behind. Verify withls -l /var/run/docker.sockon the host .
Key Source References#
| Resource | Link |
|---|---|
| Docker connection config | src/utils/config/docker.js |
dockerode version in package.json | |
| v4βv5 PR | PR #6736 |
| Synology EACCES discussion | Discussion #7140 |
| Homepage Docker docs | https://gethomepage.dev/configs/docker/ |