← Integrations

Automated SSL certificate renewal for self-managed GitLab

GitLab won't reload a renewed certificate on its own. CertKit will.

A self-managed GitLab instance serves TLS through its bundled nginx, reading the certificate and key from /etc/gitlab/ssl. When the certificate renews, nothing happens until someone replaces those files and reloads. Every 47 days. And GitLab's certificate isn't just a browser concern: every git clone, every runner, and every registry pull validates it too.

CertKit centralizes certificate issuance and renewal, then writes the renewed certificate to your GitLab server via the CertKit Agent and reloads the bundled nginx with gitlab-ctl. No downtime, no reconfigure.

Start free trial Watch demo

Built for GitLab

The CertKit Agent discovers GitLab and its certificate paths on its own. No scripting required.

The CertKit Agent finds the GitLab instance in its certificate inventory, including where the bundled nginx reads its certificate and key. On every renewal it writes the new files and runs gitlab-ctl hup nginx, which reloads the bundled nginx in place. No full reconfigure, no dropped pipelines, no waiting for a maintenance window.

Point CertKit at the discovered GitLab config once. CertKit handles every renewal after that.

How to install an SSL certificate on self-managed GitLab

The manual process, if you want to do it yourself:

  1. Get a certificate for your GitLab hostname. The name in your external_url. If you serve the container registry or Pages on their own hostnames, they need coverage too. A wildcard certificate handles all of it.
  2. Place the files where Omnibus expects them. /etc/gitlab/ssl/<hostname>.crt and <hostname>.key, matching the external_url hostname exactly, or set explicit paths with nginx['ssl_certificate'] in gitlab.rb.
  3. Include the full chain. The certificate file needs the intermediates appended. A bare leaf works in a browser and fails in CI with "unable to get local issuer certificate".
  4. Reload. gitlab-ctl reconfigure if you changed gitlab.rb, or gitlab-ctl hup nginx to pick up replaced files without downtime.
  5. Verify beyond the browser. Test a git clone over HTTPS, a runner job, and a registry pull. Each validates the chain on its own, and each fails separately when the certificate is wrong. Then repeat on every instance and Geo node.

Every one of these steps is manual, and GitLab won't repeat any of them for you when the certificate renews. With lifetimes shrinking to 47 days, installation stops being an annual chore and becomes a recurring task: eight times a year, on every instance. Miss one and it isn't just the web UI. Every push, pipeline, and registry pull starts failing with certificate errors.

At 47 days, automation is the only sustainable way to run GitLab certificates. Here's how CertKit does it.

How it works

 Your GitLab server        CertKit                 ACME CA
┌───────────────────┐     ┌──────────────────┐    ┌─────────────┐
│                   │     │                  │    │             │
│     ┌───────────────┐   │  Issue & Renew   │◄──►│             │
│     │ CertKit Agent │◄──┤   Certificates   │    │             │
│     └─────────┬─┬───┘   │                ┌───┐  └─────────────┘
│               │ │ │     └───────────┬────│DNS│
│ /etc/gitlab ◄─┘ │ │                 │    └───┘
│ [x] Written     │ │                 │
│                 │ │                 │
│ Bundled nginx ◄─┘ │ ◄───────────────┘
│ [x] Reloaded      │       Verify
└───────────────────┘

CertKit manages issuance and renewal centrally using delegated DNS validation. You create a one-time CNAME record and CertKit handles every ACME challenge after that. Your GitLab server does not run ACME, no open ports, no DNS credentials. The agent writes the files and reloads the bundled nginx locally.

Using CertKit to manage our public-facing SSL certificates has been an excellent decision. The platform is user-friendly, certificates are easy to deploy, and the automation agent streamlines the entire certificate lifecycle, eliminating concerns around shortening certificate validity periods.

Chris Austin, IT Engineer, Buckman

The errors a trusted certificate makes disappear

The most-searched GitLab certificate problems aren't about installing certificates, they're about the fallout from bad ones. "SSL certificate problem: unable to get local issuer certificate" on clone. "x509: certificate signed by unknown authority" from runners and Docker. Self-signed and internal-CA certificates cause all of it, because every git client, runner, and container pull validates the chain independently, and the workarounds (sslVerify false, insecure registries, CA files copied onto every runner) each disable a protection somewhere.

A publicly trusted certificate that renews itself removes the whole class. Nothing to distribute to clients, nothing to whitelist, no verification to turn off.

What CertKit handles

Setup takes about ten minutes

  1. Connect your domain. Add a one-time CNAME record to delegate DNS validation to CertKit. Every renewal challenge after that is automatic.
  2. Install the CertKit Agent on the GitLab server. One command on the Linux host running GitLab. The agent runs as a background service and needs no inbound firewall rules.
  3. Attach the discovered GitLab config. The agent's inventory shows your GitLab instance and its certificate paths. Attach the renewed certificate to it and CertKit writes the files and reloads nginx on every renewal.

See the full architecture →

Why not GitLab's built-in Let's Encrypt?

Omnibus GitLab ships a Let's Encrypt integration, and if your instance is reachable from the internet on port 80 it's a fine choice. Most self-managed GitLab instances aren't. They live on private networks precisely because the code inside them is private, HTTP-01 validation can't reach them, and the renew-during-reconfigure model means a failed renewal surfaces as an expired certificate later.

CertKit issues the certificate via delegated DNS validation handled centrally, which works no matter how private the instance is. The agent writes the files and reloads nginx as one verified step, with no ACME client on the server and no DNS credentials on the box holding your source code.

GitLab is just one part of your stack

Most infrastructures have more than one place where certificates live: web servers like nginx and Apache, transfer servers like CrushFTP and FileZilla Server, the Kubernetes clusters beside them, and the load balancers in front of them. CertKit automates all of it from one account.

See all integrations

Start automating GitLab certificates today

Free 90-day trial. No credit card required. Direct access to our engineering team to get you set up.

Start free trial See pricing