Scrydon
DeploymentPrerequisites

TLS

TLS certificate prerequisites for Scrydon ingress

All services must be served over HTTPS. For a public hostname that reaches Traefik directly, we recommend cert-manager with Let's Encrypt for automatic certificate provisioning.

If your hostname is private-only (app.internal, something.local, or another zone that is not delegated in public DNS), Let's Encrypt cannot issue a certificate for it. Use an internal ACME CA such as step-ca, or bring your own corporate certificate. If TLS terminates at an upstream load balancer, follow TLS Offloading. See TLS Certificates for the full decision guide.

1. Install cert-manager

# Install cert-manager (if not already present)
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager --create-namespace \
  --set crds.enabled=true

2. Create a ClusterIssuer

The chart does not create the issuer for you. When ingress.tls.enabled: true (the default), the chart annotates its Ingress with cert-manager.io/cluster-issuer: letsencrypt-prod, but you must create a ClusterIssuer of that exact name. Without it the certificate stays stuck (READY=False, "Issuing certificate as Secret does not exist") and no ACME challenge is ever attempted.

# clusterissuer-letsencrypt-prod.yaml — apply once, after cert-manager is running
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod          # MUST match ingress.tls.clusterIssuer (chart default)
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@yourdomain.com   # a real address — Let's Encrypt emails expiry notices here
    privateKeySecretRef:
      name: letsencrypt-prod-account-key   # cert-manager CREATES this Secret; do not pre-create it
    solvers:
      - http01:
          ingress:
            class: traefik        # must match your ingress controller class
kubectl apply -f clusterissuer-letsencrypt-prod.yaml
kubectl get clusterissuer letsencrypt-prod   # wait for READY=True

privateKeySecretRef.name is not a secret you supply. cert-manager generates an ACME account key on first reconcile and stores it under that name in the cert-manager namespace. The only value you must provide is a real email.

Point DNS at the Traefik LoadBalancer IP before creating a production issuer. Let's Encrypt validates over HTTP-01 by fetching http://<your-host>/.well-known/acme-challenge/..., so the hostname must resolve publicly to the ingress IP and port 80 must be reachable. Issuing against prod while DNS is wrong can trip the "5 failed validations per hostname per hour" limit. De-risk the first run with the staging server (https://acme-staging-v02.api.letsencrypt.org/directory, issuer name letsencrypt-staging, and ingress.tls.clusterIssuer: letsencrypt-staging), confirm a cert issues, then switch to prod.

If you use a different issuer name, set it in your values:

ingress:
  tls:
    enabled: true
    clusterIssuer: my-issuer   # defaults to letsencrypt-prod

3. Verify issuance

kubectl get clusterissuer                  # No resources found here = the cause; go back to step 2
kubectl get certificate -A                 # the chart's cert flips to READY=True
kubectl describe challenge -A              # if stuck: shows the HTTP-01 / DNS error

Alternatively, you can supply your own certificates as Kubernetes TLS Secrets, use an internal ACME issuer, or terminate TLS at a load balancer in front of the cluster. See TLS Certificates and TLS Offloading.

On this page

On this page