A Let's Encrypt `ClusterIssuer` enables cert-manager to obtain free, trusted certificates for every ingress in the cluster. Let's Encrypt is a free certificate authority. cert-manager communicates with it over a protocol called ACME, which proves you control a domain before Let's Encrypt signs a certificate for it. You create the issuer once, annotate an `Ingress`, and cert-manager handles the rest. This assumes [cert-manager is installed](/docs/hetzner/apalla/network/dns-certs/install-cert-manager). ## Start on staging Let's Encrypt rate-limits how many certificates you can request for a domain, and a misconfigured issuer can exhaust that limit quickly. Use the staging endpoint until the flow works end to end, then switch to production. Staging certificates are not trusted by browsers, which is precisely why they are safe to iterate against. ```yaml title="clusterissuer-staging.yaml" apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-staging spec: acme: server: https://acme-staging-v02.api.letsencrypt.org/directory email: you@example.com privateKeySecretRef: name: letsencrypt-staging-account solvers: - http01: ingress: ingressClassName: nginx ``` Switch the `server` to `https://acme-v02.api.letsencrypt.org/directory` and rename the issuer to `letsencrypt-prod` once staging issues certificates cleanly. ## Prove domain control: HTTP-01 or DNS-01 Before Let's Encrypt signs a certificate, ACME requires cert-manager to prove you control the domain. It runs one of two challenge types, and the one you choose determines whether you can issue wildcards. HTTP-01 proves control by serving a token over HTTP through your ingress. It works for any host that already points to your load balancer and requires no DNS credentials. cert-manager adds a temporary ingress path for the challenge and removes it afterward. This is the `http01` solver in the staging issuer above. ```yaml solvers: - http01: ingress: ingressClassName: nginx ``` HTTP-01 cannot issue wildcard certificates. DNS-01 proves control by writing a TXT record to your zone, so it works even when the host is not reachable over HTTP, and it is the only challenge that can issue a wildcard (`*.example.com`). Provide cert-manager with a scoped API token for your DNS provider: ```yaml solvers: - dns01: cloudflare: apiTokenSecretRef: name: cloudflare-api-token key: token ``` To avoid granting cert-manager access to your entire zone, delegate the `_acme-challenge` record to a separate zone with a CNAME and set `cnameStrategy: Follow` on the solver. For wildcard and multi-host certificates and the CNAME delegation setup, see [Multi-domain and wildcard certificates](/docs/hetzner/apalla/network/expose/multi-domain-and-wildcard). ## Issue a certificate Point an `Ingress` at the issuer with an annotation, and name the Secret that cert-manager should populate: ```yaml metadata: annotations: cert-manager.io/cluster-issuer: letsencrypt-prod spec: tls: - hosts: [app.example.com] secretName: app-example-com-tls ``` ## Verify cert-manager creates a `Certificate` object and, once the challenge passes, writes the Secret: ```console $ kubectl get certificate NAME READY SECRET app-example-com-tls True app-example-com-tls $ kubectl describe certificate app-example-com-tls ``` `READY: True` means the certificate is issued and the ingress can serve HTTPS. If it remains `False`, the events on the `Certificate` and the `Order`/`Challenge` objects show which step failed, usually a DNS record that has not yet propagated or a challenge that could not reach the ingress. A certificate at the edge is one layer of the cluster's [security model](/docs/hetzner/apalla/concepts/ownership/security-model). Once the Secret exists, the ingress uses it to [terminate TLS](/docs/hetzner/apalla/network/expose/terminate-tls-at-ingress), and cert-manager renews it before it expires without requiring you to track the date. ## Where to go next - [Install cert-manager](/docs/hetzner/apalla/network/dns-certs/install-cert-manager) - [Terminate TLS at the ingress](/docs/hetzner/apalla/network/expose/terminate-tls-at-ingress) - [Rotate and renew certificates](/docs/hetzner/apalla/network/dns-certs/certificate-rotation-and-renewal)