When troubleshooting Docker API connectivity issues, first check the active configuration:
sudo systemctl status docker
ps aux | grep dockerd
If you see -H fd://
as the only socket configuration, this explains why TCP connections fail. Modern Docker installations often default to Unix socket-only configuration.
For most modern Linux distributions using systemd, modify the service configuration:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/override.conf
Add these contents:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock
Then reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart docker
For systems using SysVinit, edit /etc/default/docker
:
DOCKER_OPTS="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock"
Restart with:
sudo service docker restart
Never expose Docker API publicly without protection. For production environments:
# Create certs directory
sudo mkdir -p /etc/docker/certs
sudo chmod 700 /etc/docker/certs
# Generate certificates
openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout /etc/docker/certs/domain.key \
-x509 -days 365 -out /etc/docker/certs/domain.crt
Configure TLS in docker.service:
ExecStart=/usr/bin/dockerd \
-H fd:// \
-H tcp://0.0.0.0:2376 \
--tlsverify \
--tlscacert=/etc/docker/certs/ca.pem \
--tlscert=/etc/docker/certs/server-cert.pem \
--tlskey=/etc/docker/certs/server-key.pem
Verify from another machine:
docker -H tcp://your_server_ip:2375 version
# With TLS:
docker --tlsverify \
--tlscacert=ca.pem \
--tlscert=cert.pem \
--tlskey=key.pem \
-H=tcp://your_server_ip:2376 version
Ensure the port is accessible:
sudo ufw allow 2375/tcp # For non-TLS
sudo ufw allow 2376/tcp # For TLS
sudo ufw reload
For CentOS/RHEL:
sudo firewall-cmd --permanent --add-port=2375/tcp
sudo firewall-cmd --reload
When adding the endpoint in Portainer:
1. Use http://your_server_ip:2375
for non-TLS
2. Use https://your_server_ip:2376
for TLS
3. Upload client certificates when prompted for secure connections
When attempting to configure Docker for remote management via TCP (particularly for Portainer integration), many users encounter connectivity issues despite seemingly correct configurations. The fundamental challenge lies in properly exposing the Docker daemon's API endpoint while maintaining security.
Recent Docker versions (17.04+) have moved away from modifying /etc/default/docker
or init scripts. The preferred approach now uses systemd drop-in files:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/override.conf
Add these contents:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock
After making changes, always verify with:
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo netstat -tulnp | grep 2375
Exposing Docker's API unsecured is dangerous. Always implement:
- TLS encryption (create certs with
openssl
) - Firewall rules limiting access
- Network segmentation
Sample TLS configuration:
ExecStart=/usr/bin/dockerd \
--tlsverify \
--tlscacert=/etc/docker/ca.pem \
--tlscert=/etc/docker/server-cert.pem \
--tlskey=/etc/docker/server-key.pem \
-H tcp://0.0.0.0:2376 \
-H unix:///var/run/docker.sock
When connections fail:
# Check daemon status
sudo systemctl status docker
# Test local connection
curl http://localhost:2375/version
# Check firewall rules
sudo ufw status
sudo iptables -L -n
For Portainer to work with remote endpoints:
docker run -d -p 9000:9000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer \
-H tcp://:2375
A more secure alternative to direct TCP exposure:
ssh -NL localhost:2375:/var/run/docker.sock user@remote-host
Then connect to localhost:2375
from your local machine.