# How to issue and auto-renew a TLS certificate with Let's Encrypt

Source: https://docs.quake.ai/docs/network/how-to/lets-encrypt-certificate
Markdown: https://docs.quake.ai/docs/network/how-to/lets-encrypt-certificate.md

---

# How to issue and auto-renew a TLS certificate with Let's Encrypt

Use Certbot on a Quake AI instance to obtain and renew a TLS certificate from [Let's Encrypt](https://letsencrypt.org/). Terminate TLS on the application instance or on a self-managed reverse proxy.



- **Application instance:** Install the certificate on the VM's web server, such as Nginx, Caddy, or Apache.
- **Reverse proxy instance:** Install the certificate on Caddy, Nginx, HAProxy, or Traefik, then route requests to application instances over a private network.
- **External edge:** Let your CDN or WAF provider terminate public TLS and configure TLS from the edge to your Quake AI origin.



<PrerequisiteBlock methods={["cli"]}>

- A running Linux instance with a floating IP, SSH access, and a user that can run `sudo`
- A certificate hostname that resolves to the instance's floating IP ([point your domain at Quake AI](/docs/network/how-to/point-domain-to-quake-ai))
- Inbound `TCP` port `80` for `HTTP-01`, or API access at your DNS provider for `DNS-01`

</PrerequisiteBlock>

## Install Certbot




```bash
sudo apt update
sudo apt install -y certbot
```

For Nginx or Apache plugins:

```bash
sudo apt install -y python3-certbot-nginx
```

For Apache, install `python3-certbot-apache` instead.




```bash
sudo dnf install -y certbot
```




## Choose a challenge

Choose the challenge that matches your web server and certificate:

| Challenge | Requires | Use when |
|---|---|---|
| HTTP-01 (webroot) | Port `80` reachable on the hostname | Nginx/Apache already serves the site |
| HTTP-01 (standalone) | Port `80` free on the instance | No web server yet; certbot binds temporarily |
| DNS-01 | API access at your DNS host | Wildcard certificates (`*.example.com`) |

## Issue the certificate

### Use HTTP-01 with webroot

```bash
sudo certbot certonly --webroot \
  -w /var/www/html \
  -d www.example.com \
  --agree-tos -m admin@example.com --non-interactive
```

### Use HTTP-01 standalone

If another service uses port `80`, stop it before you run Certbot:

```bash
sudo certbot certonly --standalone \
  -d www.example.com \
  --agree-tos -m admin@example.com --non-interactive
```

### Use DNS-01 for a wildcard certificate

```bash
sudo certbot certonly --manual --preferred-challenges dns \
  -d example.com -d '*.example.com' \
  --agree-tos -m admin@example.com
```

Certbot prints a `_acme-challenge` TXT record. Add it at your DNS host, wait for propagation, then press Enter to continue.



The manual DNS flow requires you to update the TXT record during each renewal. For unattended wildcard renewal, use a [Certbot DNS plugin supported by your DNS provider](https://eff-certbot.readthedocs.io/en/stable/using.html#dns-plugins) and protect the provider credentials on the instance.



Certbot stores the certificate at `/etc/letsencrypt/live/www.example.com/fullchain.pem` and the private key at `/etc/letsencrypt/live/www.example.com/privkey.pem`.

## Configure Nginx or Apache

Point the TLS listener at `fullchain.pem` and `privkey.pem`. Reload the web server after each renewal.

For Nginx with the plugin:

```bash
sudo certbot --nginx -d www.example.com
```

## Configure automatic renewal

The operating-system package normally installs a systemd timer or cron entry for `certbot renew`. Check for a systemd timer:

```bash
systemctl list-timers | grep certbot
```

Test the renewal configuration:

```bash
sudo certbot renew --dry-run
```

The dry run must finish without renewal errors. If you use standalone mode, configure Certbot renewal hooks to stop and restart the web server, or switch to webroot mode so Certbot can use port `80`.

## Verify HTTPS and renewal

List the certificates Certbot manages:

```bash
sudo certbot certificates
```

The output should include the certificate name, covered domains, expiry date, and paths under `/etc/letsencrypt/live/`.

After you configure TLS termination, request the hostname:

```bash
curl -I https://www.example.com
```

A successful request returns an HTTP status line from your web server or reverse proxy without a TLS verification error. Run `sudo certbot renew --dry-run` again after you change the web server or challenge configuration.

## See also

- [How to point a domain at a Quake AI resource](/docs/network/how-to/point-domain-to-quake-ai)
- [Edge reverse proxy template](/resources/iac-templates/edge-reverse-proxy)
- [How to create an instance](/docs/compute/how-to/create-instance)
- [How to put a CDN in front of a Quake AI workload](/docs/network/how-to/front-with-cdn)
