Nginx Reverse Proxy for Cockpit With Let's Encrypt

Table of Contents

Part of my setup includes installing cockpit on my remote servers, below is a screenshot of the Cockpit features. By default Cockpit runs on localhost port 9090 this post will go over setting up a nginx reverse proxy with a subdomain for cockpit.


Obtaining an SSL Certificate

If you already have Nginx running on port 80, for the time being please stop it using systemctl stop nginx.servioe.

We’ll be obtaining our certificates from Let’s Encrypt in the standalone mode and manually configuring Nginx. I think I may be able to use the default --nginx install flag but for now, this will have t do.

Installing Certbot

Everyone has their opinion on Snaps. If you’re opposed to snap’s you’ll have to manually install Certbot yourself. To simplfy things we’ll be using the snap version of certbot - accordingly the commands below presume snapd is already installed.

sudo snap install core; sudo snap refresh core

sudo snap install --classic certbot

sudo ln -s /snap/bin/certbot /usr/bin/certbot

Requesting The Cert

sudo certbot certonly --standalone --agree-tos --email YOUR-EMAIL-ADDRESS -d COCKPIT.YOUR-DOMAIN.COM

Now that we have the certificate, we need to install the certificates into cockpit.

install -m 644 /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/cockpit/ws-certs.d/1-letsencrypt.cert

install -m 640 -g cockpit-ws /etc/letsencrypt/live/$DOMAIN/privkey.pem /etc/cockpit/ws-certs.d/1-letsencrypt.key

sudo systemctl restart cockpit.service

Enable Proxy-Aware Cockpit

Creating an Nginx Server Config

server {

    location / {
        # Required to proxy the connection to Cockpit
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Required for web sockets to function
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Pass ETag header from Cockpit to clients.
        # See:
        gzip off;
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Redirect http requests. Cockpit states it will but I've had issues, this ensures https.
server {
    if ($host = {
        return 301 https://$host$request_uri;

    listen         80;
    return 404;


In some situations you may be missing the ssh-dhparams or the options-ssl-nginx files.

If this is the case, remove the second server block. Delete listen 443ssl from the first block and have it listen on 80.

Then run sudo cerbot --nginx and have it overwrite and install the missing files.

Posts in this series