Expose Infrared over HTTPS
A port-forward is enough to install Infrared. To reach it without one, and to let GitHub reach it later, give it a hostname and a certificate. On k3s, Traefik and cert-manager are already there: cert-manager comes from your gitops repo at sync wave 10.
Before you expose it, check that:
- the setup wizard is finished, because until the platform admin exists the setup token is the only credential;
- you're on chart
0.1.0-alpha.6or later, so/mcprequires a bearer token (Connect an MCP client).
1. Open the ports and add the DNS record
- Allow TCP 80 and 443 to the node. Let's Encrypt's HTTP-01 challenge needs port 80 reachable from the internet.
- Point an
Arecord for your host at the node's public address. With a CDN or proxy in front, turn it off (DNS only) until the certificate is issued.
2. Add the issuer and the Ingress to the gitops repo
These files are yours. The operator's hydration never deletes a file and never rewrites one it doesn't render, so they survive template upgrades.
registry/clusters/<cluster>/components/infrared-ingress.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: infrared-ingress
namespace: argocd
labels:
app.kubernetes.io/part-of: infrared-gitops
annotations:
argocd.argoproj.io/sync-wave: "45" # after cert-manager (10) and Infrared (40)
spec:
project: platform
source:
repoURL: https://github.com/<org>/gitops
targetRevision: main
path: components/infrared-ingress
destination:
server: https://kubernetes.default.svc
namespace: infrared
syncPolicy:
automated: { prune: true, selfHeal: true }
syncOptions: [SkipDryRunOnMissingResource=true]
components/infrared-ingress/ holds a kustomization.yaml that lists the two files below.
issuer.yaml:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-http01
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-http01-account
solvers:
- http01:
ingress:
ingressClassName: traefik
ingress.yaml: HTTPS to the infrared Service, plus a redirect from HTTP. cert-manager's challenge path is longer than /, so Traefik routes challenges to it ahead of the redirect.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: infrared
namespace: infrared
annotations:
cert-manager.io/cluster-issuer: letsencrypt-http01
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
ingressClassName: traefik
tls:
- hosts: [<host>]
secretName: infrared-tls
rules:
- host: <host>
http:
paths:
- path: /
pathType: Prefix
backend: { service: { name: infrared, port: { number: 80 } } }
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: https-redirect
namespace: infrared
spec:
redirectScheme: { scheme: https, permanent: true }
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: infrared-http
namespace: infrared
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: infrared-https-redirect@kubernetescrd
spec:
ingressClassName: traefik
rules:
- host: <host>
http:
paths:
- path: /
pathType: Prefix
backend: { service: { name: infrared, port: { number: 80 } } }
Merge the PR. Argo CD syncs the Application, and cert-manager usually issues the certificate within a minute.
3. Check it
kubectl -n infrared get certificate infrared-tls # READY True
curl -sI http://<host>/ | head -1 # 301
curl -s -o /dev/null -w '%{http_code}\n' https://<host>/api/v1/orgs # 401 without a session
The API works out its external URL from the forwarded headers, so session cookies are marked Secure over HTTPS without any chart change.