{"id":609,"date":"2023-03-29T18:54:12","date_gmt":"2023-03-29T10:54:12","guid":{"rendered":"https:\/\/codestrian.com\/?p=609"},"modified":"2023-03-30T14:37:17","modified_gmt":"2023-03-30T06:37:17","slug":"expose-rootless-docker-api-socket-via-tcp-with-ssl","status":"publish","type":"post","link":"https:\/\/codestrian.com\/index.php\/2023\/03\/29\/expose-rootless-docker-api-socket-via-tcp-with-ssl\/","title":{"rendered":"Expose Rootless Docker API socket via TCP with SSL"},"content":{"rendered":"<p>In my previous write-ups, I explained how to set up rootless Docker, and I also mentioned that I prefer using Portainer to manage my containers. However, to enable Portainer to manage Docker daemons on multiple servers, I need to be able to connect to these daemons and add them as Portainer environments. Exposing the Docker API socket via TCP is one way to achieve this.<\/p>\n<p>By default, the Docker API socket is only accessible locally on the host machine. However, it is possible to expose the Docker API socket via TCP so that it can be accessed remotely.<\/p>\n<p>You can configure the Docker daemon to expose the API socket via TCP by adding the following configuration to the <code>daemon.json<\/code> file, which can be found in <code>~\/.config\/systemd\/docker\/daemon.json<\/code><\/p>\n<pre><code>{\n  &quot;hosts&quot;: [&quot;unix:\/\/\/run\/user\/1001\/docker.sock&quot;, &quot;tcp:\/\/0.0.0.0:2375&quot;],\n}<\/code><\/pre>\n<p>To enable the rootless docker daemon to listen to specific ports, you will need to add the following line to the <code>docker.service<\/code> configuration file located at <code>~\/.config\/systemd\/user<\/code><\/p>\n<pre><code>Environment=DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS=&quot;-p 0.0.0.0:2375:2375\/tcp&quot;<\/code><\/pre>\n<p>After making changes to the docker.service configuration file and the daemon.json configuration file, you'll need to reload the daemon and restart the docker service for the changes to take effect. Here are the steps to do so:<\/p>\n<ol>\n<li>Reload the daemon by running the command:\n<pre><code>systemctl --user daemon-reload<\/code><\/pre>\n<\/li>\n<li>Restart the docker service by running the command:\n<pre><code>systemctl --user restart docker<\/code><\/pre>\n<\/li>\n<\/ol>\n<p>However, it is a security risk to expose the Docker API socket via TCP as it allows remote access to the Docker API. Therefore, it is recommended to use TLS encryption and authentication to secure the connection.<\/p>\n<p>To enable SSL, you will need to have the CA certificate, server certificate and server key. You may find the instruction on how to generate these files on <a href=\"https:\/\/docs.docker.com\/engine\/security\/protect-access\/\" title=\"docker\">docker<\/a>.<\/p>\n<p>Together with the files above, you will need to update the <code>daemon.json<\/code> as shown below<\/p>\n<pre><code>{\n  &quot;hosts&quot;: [&quot;unix:\/\/\/run\/user\/1001\/docker.sock&quot;, &quot;tcp:\/\/0.0.0.0:2376&quot;],\n  &quot;tlsverify&quot;: true,\n  &quot;tlscacert&quot;: &quot;\/home\/docker\/.docker\/certs\/ca.crt&quot;,\n  &quot;tlscert&quot;: &quot;\/home\/docker\/.docker\/certs\/server.crt&quot;,\n  &quot;tlskey&quot;: &quot;\/home\/docker\/.docker\/certs\/server.key&quot;\n}<\/code><\/pre>\n<p>Lastly, change the port from <strong>2375<\/strong> to <strong>2376<\/strong> in <code>docker.service<\/code><\/p>\n<pre><code>Environment=DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS=&quot;-p 0.0.0.0:2376:2376\/tcp&quot;<\/code><\/pre>\n<pre><code>[Unit]\nDescription=Docker Application Container Engine (Rootless)\nDocumentation=https:\/\/docs.docker.com\/go\/rootless\/\n\n[Service]\nEnvironment=PATH=\/usr\/bin:\/sbin:\/usr\/sbin:\/usr\/local\/bin:\/usr\/bin:\/bin:\/usr\/local\/games:\/usr\/games\nEnvironment=DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS=&quot;-p 0.0.0.0:2376:2376\/tcp&quot;\nExecStart=\/usr\/bin\/dockerd-rootless.sh\nExecReload=\/bin\/kill -s HUP $MAINPID\nTimeoutSec=0\nRestartSec=2\nRestart=always\nStartLimitBurst=3\nStartLimitInterval=60s\nLimitNOFILE=infinity\nLimitNPROC=infinity\nLimitCORE=infinity\nTasksMax=infinity\nDelegate=yes\nType=notify\nNotifyAccess=all\nKillMode=mixed\n\n[Install]\nWantedBy=default.target<\/code><\/pre>\n<p>Just like before, reload the daemon and restart the docker to see the result.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my previous write-ups, I explained how to set up rootless Docker, and I also mentioned that I prefer using Portainer to manage my containers. However, to enable Portainer to manage Docker daemons on multiple servers, I need to be able to connect to these daemons and add them as [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[62],"tags":[73],"_links":{"self":[{"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/posts\/609"}],"collection":[{"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/comments?post=609"}],"version-history":[{"count":6,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/posts\/609\/revisions"}],"predecessor-version":[{"id":615,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/posts\/609\/revisions\/615"}],"wp:attachment":[{"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/media?parent=609"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/categories?post=609"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codestrian.com\/index.php\/wp-json\/wp\/v2\/tags?post=609"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}