Is it possible to connect Docker daemon running on remote host from local Docker client? Yes, this tutorial will take you through how to configure Docker daemon for remote connections. Docker daemon listens on Unix socket on a localhost by default. It can as well be configured to listen on an IP address and port to allow remote clients to connect to it.
Configuring Docker Daemon for Remote Connections
As already mentioned, Docker daemon can listens on non-networked unix socket by default. It can however be configured to listen on both an IP and port as well as on usual unix socket.
There are two ways in which you can configure Docker daemon to allow remote connections (You can only use one method and not both at the same time on the same system).
Use Systemd Service Unit File to enable Docker Daemon Remote Connections
For systems that uses systemd and have Docker engine installed, then you can edit the Docker daemon service unit file, docker.service
, and configure it to listen on an IP and port.
Create a systemd drop-in directory for the docker
service:
sudo mkdir -p /etc/systemd/system/docker.service.d
Configure the overide file to look like;
sudo tee /etc/systemd/system/docker.service.d/override.conf << 'EOL'
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://192.168.59.48:2375
EOL
Port 2375/TCP is the default port used for the Docker daemon to listen on for API requests.
Above configures Docker daemon to listen on specific IP address only. You can use 0.0.0.0 to listen on all interfaces.
You might be wondering why an extra ExecStart line without a value? Well, ExecStart=
with no value is typically used to clear any previously defined ExecStart
commands from the original service file. It ensures that the original ExecStart
command is cleared before adding your new command with ExecStart=/new/value
.
Reload the systemctl
configuration.
sudo systemctl daemon-reload
Restart Docker.
sudo systemctl restart docker
Verify that it is now listening on both Unix socket and IP/port;
ss -altnp | grep :2375
LISTEN 0 4096 192.168.59.48:2375 0.0.0.0:* users:(("dockerd",pid=3344,fd=3))
Enable Docker Remote Connections via daemon.json file
daemon.json
is a configuration file for the Docker daemon used to set various options and settings for the Docker daemon, such as network settings, storage drivers, logging options, and more.
You can edit this file, if it is already existing and configure it as follows to enable Docker daemon for remote connections;
sudo vim /etc/docker/daemon.json
{
"hosts": ["unix:///var/run/docker.sock", "tcp://192.168.59.48:2375"]
}
If the file already exists, add that line and ensure that the file remains a valid json file.
Save and exit the file.
Restart Docker daemon;
sudo systemctl restart docker
If docker service fails with the error;
unable to configure the Docker daemon with file /etc/docker/daemon.json: the following directives are specified both as a flag and in the configuration file: hosts: (from flag: [fd://], from file: [unix:///var/run/docker.sock tcp://192.168.59.48:2375])
Then solve by removing the -H fd://
option from the systemd unit file it as follows;
[[ -d /etc/systemd/system/docker.service.d ]] || sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/override.conf << 'EOL'
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
EOL
Restart Docker again;
sudo systemctl restart docker
Control Docker Daemon Remote Access on Firewall
Allowing remote access to Docker daemon is a security risk. Ensure that you implement firewall rules to allow access from specific systems only.
For example, the command below can be used to allow access to Docker daemon from specific host;
sudo ufw allow from 192.168.59.46 to any port 2375 proto tcp comment "Allow access from johndoes system"
If using iptables;
sudo iptables -A INPUT -p tcp --dport 2375 -s 192.168.59.100/32 -m comment --comment "Allow from johndoes system" -j ACCEPT
sudo cp /etc/iptables/rules.v4{,.bak}
iptables-save > /etc/iptables/rules.v4
Configure Secured Access to Remote Docker Daemon
There are also two methods in which you can configure secured access to remote Docker deamon;
Access Docker Daemon via SSH
To begin with, on the Docker host, where you have configured Docker daemon for remote access, create a user and add the user to Docker group. The name can be anything!
sudo useradd -m -G docker -s /bin/bash kifarunix
Set the user password;
sudo passwd kifarunix
If the user already exists, add it to Docker group;
sudo usermod -aG docker kifarunix
On the client host that you want to use to connect to remote Docker daemon, generate SSH keys from your user account;
ssh-keygen
Next, update the remote Docker daemon DNS details on your hosts file if there is no local DNS;
sudo tee -a "192.168.59.48 docker01.kifarunix.com docker01" >> /etc/hosts
Copy the SSH keys into the Docker server, replace connection details appropriately;
ssh-copy-id kifarunix@docker01
You can now access remote Docker daemon as follows;
docker -H ssh://username@remote-docker-hostname <docker command options>
For example, to get info about remote Docker daemon;
docker -H ssh://kifarunix@docker01 info
You can also update the DOCKER_HOST environment variable with SSH connection command;
export DOCKER_HOST=ssh://username@remote-docker-hostname
e.g;
export DOCKER_HOST=ssh://kifarunix@docker01
With this done, then you can ran your docker commands against the remote host as you would when logged in to that server;
docker ps
If you are running Docker engine on the client node you are using to access remote Docker daemon, you can create Docker contexts that enables you to switch between the local and remote Docker daemon.
By default, the local Docker context that defines the local Docker daemon socket, unix:///var/run/docker.sock
, is created;
docker context ls
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm
You can create another Docker context to define remote Docker daemon endpoint;
docker context create \
--docker host=ssh://docker-user@hostname \
--description="Description" \
context-name
E.g to create a Docker context for our remote Docker daemon;
docker context create \
--docker host=ssh://kifarunix@docker01 \
--description="Remote DOCKER_HOST docker01 configuration" \
docker01
You can list contexts again;
docker context ls
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm
docker01 Remote DOCKER_HOST docker01 configuration ssh://kifarunix@docker01
To connect to a remote Docker daemon using Docker contexts, simply use the specific Docker context. e.g;
docker context use docker01
If you list contexts again, you will see that current context is the remote context;
docker context ls
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm
docker01 * Remote DOCKER_HOST docker01 configuration ssh://kifarunix@docker01
You can then run Docker commands against remote Docker host as usual;
e.g
docker ps
This list Docker containers running on the remote Docker node;
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
950a8a3f3bb6 grafana/grafana-oss "/run.sh" 2 weeks ago Up 2 hours 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp grafana
ce3eb465e820 prom/prometheus "/bin/prometheus --c…" 2 weeks ago Up 2 hours 0.0.0.0:9090->9090/tcp, :::9090->9090/tcp prometheus
567d549c4768 gcr.io/cadvisor/cadvisor "/usr/bin/cadvisor -…" 2 weeks ago Up 2 hours (healthy) 0.0.0.0:9080->8080/tcp, :::9080->8080/tcp cadvisor
8d2a1aac1384 mariadb "docker-entrypoint.s…" 4 weeks ago Up 2 hours 3306/tcp wp-mariadb
b46dce1fc33c amir20/dozzle:latest "/dozzle" 6 weeks ago Up 3 hours 0.0.0.0:8888->8080/tcp, :::8888->8080/tcp dozzle
1421e6e27733 nagios-core:4.4.9 "/start.sh" 6 weeks ago Up 2 hours 0.0.0.0:80->80/tcp, :::80->80/tcp nagios-core-4.4.9
And that is on how you can use SSH to connect to remote Docker daemon.
Connect to Docker Daemon using via TLS (HTTPS)
Docker over TLS should run on TCP port 2376.
Thus, similarly, you can enable HTTPS connection to your remote Docker daemon. To be able to use HTTPS connection to remote Docker container, you need SSL/TLS certificates.
To make this process easy and cost effective, you can setup your own CA server that enables you to generate and sign your own SSL/TLS certificates;
How to Setup a Local CA Server on Ubuntu
Thus, on your CA server, generate SSL/TLS certificates to be installed on the remote Docker server node and clients connecting to it to develop trust among them.
Generate Docker SSL/TLS certificates and keys (you can follow the guide above to generate and sign your own ssl certificates);
Put the certificates and keys on a single directory for easy access.
For example, we have the following;
ls /etc/ssl/docker/
cacert.pem
docker01.crt
docker01.key
You will need to copy these same files into Docker client.
Configure Daemon for Remote SSL/TLS connection;
For this, you can use either daemon.json
file or systemd unit file
for Docker daemon.
To use daemon.json, update it such that it may look like in below, ensuring that the file remains a valid JSON file.
sudo vim /etc/docker/daemon.json
{
"hosts": ["unix:///var/run/docker.sock", "tcp://192.168.59.48:2376"],
"tlsverify": true,
"tlscacert": "/etc/ssl/docker/cacert.pem",
"tlscert": "/etc/ssl/docker/docker01.crt",
"tlskey": "/etc/ssl/docker/docker01.key"
}
Restart Docker daemon;
sudo systemctl restart docker
Check the port;
ss -altnp | grep 2376
Also check logs if need be;
journalctl -xeu docker.service
Open port 2376/tcp on firewall;
iptables -A INPUT -p tcp --dport 2376 -s 192.168.59.100/32 -m comment --comment "Allow from johndoes system" -j ACCEPT
To configure Docker daemon for SSL/TLS connection using systemd unit file;
sudo tee /etc/systemd/system/docker.service.d/override.conf << 'EOL'
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://192.168.59.48:2376 \
--tlsverify --tlscacert=/etc/ssl/docker/cacert.pem \
--tlscert=/etc/ssl/docker/docker01.crt \
--tlskey=/etc/ssl/docker/docker01.key
EOL
Reload the systemctl
configuration.
sudo systemctl daemon-reload
Restart Docker.
sudo systemctl restart docker
Next, copy the CA, CRT and KEY files into the client into your users Docker directory, ~/.docker
and rename them as ca.pem, key.pem, cert.pem
.
On Docker Client, we have already copied the files;
ls -1 ~/.docker/
ca.pem
config.json
contexts
cert.pem
key.pem
You can now connect to remote Docker node using the command;
export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1
e.g
export DOCKER_HOST=tcp://docker01.kifarunix.com:2376 DOCKER_TLS_VERIFY=1
We used FQDN since we generated a wildcard SSL/TLS certificate.
You can now access remote Docker host as usual;
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
950a8a3f3bb6 grafana/grafana-oss "/run.sh" 2 weeks ago Up 16 minutes 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp grafana
ce3eb465e820 prom/prometheus "/bin/prometheus --c…" 2 weeks ago Up 16 minutes 0.0.0.0:9090->9090/tcp, :::9090->9090/tcp prometheus
8d2a1aac1384 mariadb "docker-entrypoint.s…" 4 weeks ago Up 16 minutes 3306/tcp wp-mariadb
b46dce1fc33c amir20/dozzle:latest "/dozzle" 6 weeks ago Up 16 minutes 0.0.0.0:8888->8080/tcp, :::8888->8080/tcp dozzle
1421e6e27733 nagios-core:4.4.9 "/start.sh" 6 weeks ago Up 16 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp nagios-core-4.4.9
And that is all on how to configure Docker daemon for remote connections.
Reference
Remote access for Docker daemon