portainer-docs/advanced/ssl.md

6.4 KiB
Raw Permalink Blame History

Using your own SSL certificate with Portainer

By default, Portainers 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.

{% hint style="info" %} 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. {% endhint %}

Using your own SSL certificate on Docker Standalone

{% hint style="info" %} Portainer expects certificates in PEM format. {% endhint %}

Use the --sslcert and --sslkey flags during installation.

{% hint style="info" %} If you are using certificates signed by your own CA, you may need to supply your CA certificate as well with the --sslcacert flag. {% endhint %}

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:

{% tabs %} {% tab title="Business 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

{% endtab %}

{% tab title="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-ce:latest \
    --sslcert /certs/portainer.crt \
    --sslkey /certs/portainer.key

{% endtab %} {% endtabs %}

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:

{% tabs %} {% tab title="Business 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

{% endtab %}

{% tab title="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-ce:latest \
    --sslcert /certs/live/yourdomain/fullchain.pem \
    --sslkey /certs/live/yourdomain/privkey.pem

{% endtab %} {% endtabs %}

When you're finished, you can navigate to https://$ip-docker-host:9443.

Using your own SSL certificate on Docker Swarm

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

{% hint style="info" %} 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. {% endhint %}

Next, retrieve the stack YML manifest:

{% tabs %} {% tab title="Linux and Windows with Docker Desktop" %} Business Edition:

curl -L https://downloads.portainer.io/ee2-19/portainer-agent-stack-ssl.yml -o portainer-agent-stack.yml

Community Edition:

curl -L https://downloads.portainer.io/ce2-19/portainer-agent-stack-ssl.yml -o portainer-agent-stack.yml

{% endtab %}

{% tab title="Windows Container Services" %} Business Edition:

curl https://downloads.portainer.io/ee2-19/portainer-windows-stack-ssl.yml -o portainer-agent-stack.yml

Community Edition:

curl https://downloads.portainer.io/ce2-19/portainer-windows-stack-ssl.yml -o portainer-agent-stack.yml

{% endtab %} {% endtabs %}

Finally, use the downloaded YML manifest to deploy your stack:

docker stack deploy -c portainer-agent-stack.yml portainer

For more information about secrets, read Docker's own documentation.

Using your own SSL certificate on Kubernetes (via Helm)

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:

{% tabs %} {% tab title="NodePort" %} 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

{% endtab %}

{% tab title="Load Balancer" %} 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

{% endtab %} {% endtabs %}