Skip to content

Instantly share code, notes, and snippets.

@rafaelfess
Forked from woudsma/portainer-dokku.md
Created February 29, 2020 13:02
Show Gist options
  • Save rafaelfess/4b652b4b469cfe6373f5b0d60fc31340 to your computer and use it in GitHub Desktop.
Save rafaelfess/4b652b4b469cfe6373f5b0d60fc31340 to your computer and use it in GitHub Desktop.
TLS secured TCP exposed Docker daemon on Dokku host - setup

TLS secured TCP exposed Docker daemon on Dokku host - setup

  1. Create certificates
  2. Edit Docker options
  3. Restart Docker
  4. Copy client certificates from host
  5. (optional) Add remote endpoint in Portainer

Tested on a standard $5/mo DigitalOcean VPS running Ubuntu 16.04.


Create certificates:

Log into Dokku host as root and create server/client certificates:

export HOST=my.domain
mkdir .docker && cd .docker

openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
openssl genrsa -out server-key.pem 4096
openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
echo subjectAltName = DNS:$HOST,IP:127.0.0.1 >> extfile.cnf
echo extendedKeyUsage = serverAuth >> extfile.cnf
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
openssl genrsa -out key.pem 4096
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
echo extendedKeyUsage = clientAuth >> extfile.cnf
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
rm client.csr server.csr
chmod 0400 ca-key.pem key.pem server-key.pem
chmod 0444 ca.pem server-cert.pem cert.pem

(please comment if you know how this can be done easier 😭)
For more details refer to the documentation

Edit Docker options:

systemctl edit docker

Add:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 --tlsverify --tlscacert /root/.docker/ca.pem --tlscert /root/.docker/server-cert.pem --tlskey /root/.docker/server-key.pem -H unix:///var/run/docker.sock

(note: -H unix:///var/run/docker.sock as last argument!)
Creates /etc/systemd/system/docker.service.d/.#override.conf3aa8ba90533acd64
For more details refer to the documentation

Restart Docker:

systemctl restart docker

Copy certificates from host:

Exit host: exit
SFTP into host: sftp root@host

cd .docker
get ca.pem
get cert.pem
get key.pem

Guard these keys like root passwords, malicious users can severely damage your server with access to the Docker daemon.

Add endpoint in Portainer

Provide my.domain:2376, enable TLS and add ca.pem, cert.pem and key.pem

If Portainer can't connect to the endpoint, most likely something went wrong while creating the certificates. Check out the documentation and re-generate the certificates.

# Check if the Docker daemon is running
docker -H my.domain:2376 info

# Check if the DNS settings are correct
dig +short my.domain

Run Portainer on Dokku host

Running Portainer as a container management tool for other Dokku hosts.
Host:

dokku apps:create portainer
dokku domains:add portainer portainer.my.domain

Create persistent storage folder: mkdir -p /var/lib/dokku/data/storage/portainer
Edit app docker-options:

dokku docker-options:add portainer deploy,run "-v /var/lib/dokku/data/storage/portainer:/data -v /var/run/docker.sock:/var/run/docker.sock"

Local

mkdir portainer && cd portainer
git init
git remote add dokku dokku@<host>:portainer
curl https://www.gitignore.io/api/macos%2Cwindows > .gitignore
touch Dockerfile

Edit Dockerfile:

FROM portainer/portainer
EXPOSE 9000

Push to Dokku host:

git add .
git commit -m 'initial'
git push dokku master

Host
Map ports and add SSL using dokku-letsencrypt:

# Map ports
dokku ps:stop portainer
dokku config:set portainer DOKKU_PROXY_PORT_MAP="http:80:9000"

# Add SSL
dokku config:set --no-restart portainer [email protected]
dokku letsencrypt portainer

# Check if ports are mapped correctly
dokku config:get portainer DOKKU_PROXY_PORT_MAP

# Should output: "http:80:9000 https:443:9000"

To re-deploy Portainer, first stop the Portainer container (it's using the Docker socket) dokku ps:stop portainer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment