Skip to content

SSL certificates

Keep your panel on HTTPS, and fix it when the certificate does not renew.

The installer sets this up for you. This page covers what it did, and what to do later.

What the installer does

During the installation, the installer asks how HTTPS is handled:

  • Let's Encrypt (Automatic Renewal). The installer installs certbot and requests a certificate for your one panel domain. The challenge is HTTP-01 on port 80.
  • External Certificate / Proxy / No Certificate. The installer requests nothing, and the panel answers on port 80. Put your own certificate in docker/nginx/ssl/ to have the panel serve HTTPS itself, or leave the panel on port 80 to put your own proxy in front of it. See Your own certificate.

On the Let's Encrypt path the installer then:

  1. Copies the certificate to docker/nginx/ssl/badgerpanel.crt in your installation directory.
  2. Copies the private key to docker/nginx/ssl/badgerpanel.key in the same directory.
  3. Switches the panel to HTTPS, and sends port 80 to port 443.
  4. Adds a renewal job to the root crontab. It runs certbot renew every day at 03:00.
  5. Installs the renewal steps that free port 80, put the new files in place, and reload the web server.

TIP

The certificate covers one domain. BadgerPanel does not request a wildcard certificate, and it does not use the Let's Encrypt staging environment.

Automatic renewal

A Let's Encrypt certificate is valid for 90 days. When less than 30 days remain, the daily job renews it.

A renewal runs in this order:

  1. The job frees port 80 for the HTTP-01 challenge.
  2. Certbot gets the new certificate from Let's Encrypt.
  3. The job copies the new certificate and key into docker/nginx/ssl/.
  4. The web server starts again with the new files.

The panel is unreachable for a few seconds during each renewal. The job runs at 03:00 to keep that pause outside your busy hours.

Certificate warnings in the panel

The panel reads the certificate file every 6 hours. A banner appears across the top of the admin area when the certificate needs attention:

  • An amber banner reads "TLS certificate expires in N days". It appears when less than 14 days remain.
  • A red banner reads "TLS certificate has expired".

Both banners have a Renew now button. This button runs certbot renew at once. The panel also attempts a renewal on its own when the certificate enters the 14-day window.

The panel allows one renewal attempt per hour. If you click Renew now again inside that hour, the panel refuses and shows the remaining time. When a renewal fails, the banner shows the certbot error under "Last renew error".

You can dismiss the amber banner. The red banner comes back until the certificate is valid again.

Manual renewal

The daily job keeps the certificate valid. If you want the new certificate at once, renew it by hand:

bash
sudo certbot renew

It does the same as the daily job: frees port 80, puts the new files in place, and starts the web server again.

Certbot keeps a certificate that has more than 30 days left. To replace such a certificate, add --force-renewal.

To see the expiry date of the certificate that certbot holds, run:

bash
sudo certbot certificates

Your own certificate

To use a certificate from somebody else, replace the two files the panel reads.

  1. Copy your certificate chain to docker/nginx/ssl/badgerpanel.crt in your installation directory.
  2. Copy your private key to docker/nginx/ssl/badgerpanel.key in the same directory.
  3. Restart the web server.
bash
cd ~/badgerpanel
docker compose restart nginx

The file names must be exactly badgerpanel.crt and badgerpanel.key. The certificate must cover the domain in your APP_URL value. The .crt file must hold the full chain, not the leaf certificate on its own.

Common errors

The certificate request fails during installation

CauseWhat to do
DNS does not point to this serverRun dig panel.example.com. The A record must hold the public IP of your server.
Port 80 is blocked or in useLet's Encrypt needs port 80 for the HTTP-01 challenge. Open it, and stop any other web server.
Rate limit reachedLet's Encrypt limits how many certificates one domain can get. Wait one hour, then try again.

The browser shows a certificate warning

  • The certificate is expired. Run sudo certbot certificates to read the expiry date, then renew.
  • The address in the browser is not the domain of the certificate. Open the panel with the exact domain.
  • Your own certificate holds only the leaf. Put the full chain in badgerpanel.crt.

The browser reports mixed content

Open the .env file in your installation directory. Make sure that APP_URL, APP_BASE_URL, API_URL, and NEXT_PUBLIC_API_URL all start with https://. Then restart the panel.

BadgerPanel Documentation