Skip to content

Docker Swarm Watcher ignores default Docker socket and standard environment variables #567

Description

@SCBionicle

Description

When running in Docker Swarm mode (-in-docker-swarm), the application fails to auto-discover the Docker daemon socket or respect standard Docker environment variables (such as DOCKER_HOST), requiring the user to explicitly specify the socket path via flags or manual configuration.

This differs from the standard Docker integration (-in-docker), which falls back gracefully to standard defaults.

Root Cause

The bug resides in docker_swarm.go during Docker client initialization inside Start():

  1. Missing client.FromEnv:
    Unlike docker.go, the Swarm watcher implementation does not include the client.FromEnv option when creating the client. This prevents the Docker SDK from loading configuration parameters from environment variables.

  2. Unconditional client.WithHost(""):
    The client initialization calls client.WithHost(w.config.socket) unconditionally:

    opts := []client.Opt{
        client.WithHost(w.config.socket),
        client.WithTimeout(w.config.timeout),
        client.WithHTTPHeaders(map[string]string{
            "User-Agent": "mc-router ",
        }),
        client.WithAPIVersionNegotiation(),
    }

    If the -docker-socket flag is not specified, w.config.socket defaults to "". This forces client.WithHost("") which overrides the standard SDK defaults (e.g. unix:///var/run/docker.sock on Unix or npipe:////./pipe/docker_engine on Windows) to an empty string.

Proposed Fix

Align the Swarm watcher initialization with the standard Docker watcher implementation in docker.go:

  1. Add client.FromEnv to the opts slice.
  2. Only append client.WithHost(w.config.socket) if w.config.socket is non-empty.
-	opts := []client.Opt{
-		client.WithHost(w.config.socket),
-		client.WithTimeout(w.config.timeout),
-		client.WithHTTPHeaders(map[string]string{
-			"User-Agent": "mc-router ",
-		}),
-		client.WithAPIVersionNegotiation(),
-	}
+	opts := []client.Opt{
+		client.FromEnv,
+		client.WithTimeout(w.config.timeout),
+		client.WithHTTPHeaders(map[string]string{
+			"User-Agent": "mc-router ",
+		}),
+		client.WithAPIVersionNegotiation(),
+	}
+
+	if w.config.socket != "" {
+		opts = append(opts, client.WithHost(w.config.socket))
+	}

AI Disclosure: The above was investigated and drafted with AI.

Context: I run a multinode Docker Swarm cluster in my homelab. I ran into this issue when setting up my Minecraft server behind MC-Router. I couldn't find any documentation on why the Router was crashing, so I tasked an agent to find out why and suggest a fix both for my Swarm configuration and this issue.
My Current Work Around: Set the following in MC-Router's environment configuration DOCKER_SOCKET: "unix:///var/run/docker.sock"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions