Using your own SSL certificate with Portainer
By default, Portainer’s web interface and API is exposed over HTTPS with a self-signed certificate generated by the installation. This can be replaced with your own SSL certificate either after installation via the Portainer UI or during installation, as explained in this article.
When using your own externally-issued certificate, ensure that you include the full certificate chain (including any intermediate certificates) in the file you provide via
--sslcert
. Without this you may face certificate validation issues. Your certificate chain can be obtained either from your certificate issuer or the What's My Chain Cert? website.Portainer expects certificates in PEM format.
Use the
--sslcert
and --sslkey
flags during installation.If you are using certificates signed by your own CA, you may need to supply your CA certificate as well with the
--sslcacert
flag.Upload your certificate (including the chain) and key to the server running Portainer, then start Portainer referencing them. The following command assumes your certificates are stored in
/path/to/your/certs
with the filenames portainer.crt
and portainer.key
, and bind-mounts the directory to /certs
in the Portainer container:Business Edition
Community Edition
docker run -d -p 9443:9443 -p 8000:8000 \
--name portainer --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
-v /path/to/your/certs:/certs \
portainer/portainer-ee:latest \
--sslcert /certs/portainer.crt \
--sslkey /certs/portainer.key
docker run -d -p 9443:9443 -p 8000:8000 \
--name portainer --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
-v /path/to/your/certs:/certs \
portainer/portainer-ce:latest \
--sslcert /certs/portainer.crt \
--sslkey /certs/portainer.key
Alternatively, Certbot can be used to generate a certificate and a key. Because Docker has issues with symlinks, if you use Certbot you will need to pass both the 'live' and 'archive' directories as volumes, as well as use the full chain certificate. For example:
Business Edition
Community Edition
docker run -d -p 9443:9443 -p 8000:8000 \
--name portainer --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
-v /etc/letsencrypt/live/yourdomain:/certs/live/yourdomain:ro \
-v /etc/letsencrypt/archive/yourdomain:/certs/archive/yourdomain:ro \
portainer/portainer-ee:latest \
--sslcert /certs/live/yourdomain/fullchain.pem \
--sslkey /certs/live/yourdomain/privkey.pem
docker run -d -p 9443:9443 -p 8000:8000 \
--name portainer --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
-v /etc/letsencrypt/live/yourdomain:/certs/live/yourdomain:ro \
-v /etc/letsencrypt/archive/yourdomain:/certs/archive/yourdomain:ro \
portainer/portainer-ce:latest \
--sslcert /certs/live/yourdomain/fullchain.pem \
--sslkey /certs/live/yourdomain/privkey.pem
When you're finished, you can navigate to
https://$ip-docker-host:9443
.To provide your own SSL certificate for Docker Swarm, simply define the
portainer.sslcert
and portainer.sslkey
secrets, and the installation manifest will automatically detect and use them:docker secret create portainer.sslcert /path/to/your/certificate.crt
docker secret create portainer.sslkey /path/to/your/certificate.key
If you are using certificates signed by your own CA, you may need to supply your CA certificate as well via a
portainer.sslcacert
secret and modifying the below YAML files to include the --sslcacert
flag.Next, retrieve the stack YML manifest:
Linux and Windows with Docker Desktop
Windows Container Services
Business Edition:
curl -L https://downloads.portainer.io/ee2-18/portainer-agent-stack-ssl.yml -o portainer-agent-stack.yml
Community Edition:
curl -L https://downloads.portainer.io/ce2-18/portainer-agent-stack-ssl.yml -o portainer-agent-stack.yml
Business Edition:
curl https://downloads.portainer.io/ee2-18/portainer-windows-stack-ssl.yml -o portainer-agent-stack.yml
Community Edition:
curl https://downloads.portainer.io/ce2-18/portainer-windows-stack-ssl.yml -o portainer-agent-stack.yml
Finally, use the downloaded YML manifest to deploy your stack:
docker stack deploy -c portainer-agent-stack.yml portainer
If it doesn't already exist, create the
portainer
namespace:kubectl create namespace portainer
Next, create a TLS secret containing the full certificate chain and matching private key:
kubectl create secret tls portainer-tls-secret -n portainer \
--cert=/path/to/cert/file \
--key=/path/to/key/file
Install via helm with the
tls.existingSecret
parameter set to the name of the secret you just created:NodePort
Load Balancer
Business Edition:
helm install -n portainer portainer portainer/portainer \
--set tls.existingSecret=portainer-tls-secret \
--set enterpriseEdition.enabled=true
Community Edition:
helm install -n portainer portainer portainer/portainer \
--set tls.existingSecret=portainer-tls-secret
Business Edition:
helm install -n portainer portainer portainer/portainer \
--set tls.existingSecret=portainer-tls-secret \
--set service.type=LoadBalancer \
--set enterpriseEdition.enabled=true
Community Edition:
helm install -n portainer portainer portainer/portainer \
--set tls.existingSecret=portainer-tls-secret \
--set service.type=LoadBalancer