Gateway Configuration

Gateway Configuration

This guide walks through deploying an example web app accessible at https://app1.dev.example.com/example using Kubernetes, rackctl for SSL management, and NGINX Ingress.

0. Add and verify your domain in the Portal

Before rackctl gen-ssl can issue a certificate (or create DNS records) for a domain, that domain’s parent domain must be added and verified under DNS Mappings in the Portal. This only needs to be done once per parent domain — every subdomain under it (e.g. app1.dev.example.com, app2.dev.example.com, …) is covered afterward.

  1. In the Portal, go to Allowed URLs for your settings page and click Add Domain. Enter the parent domain you control, e.g. dev.example.com.
    • This creates a dedicated hosted zone for the domain and puts it in a pending_verification state.
  2. The Portal will show you a set of NS records. Add these as NS records for dev.example.com at your registrar (or parent DNS provider).
    • DNS propagation isn’t instant — this can take anywhere from a few minutes up to ~48 hours depending on your registrar and existing TTLs.
  3. Click Verify (or re-check) in the Portal. This is safe to retry — the Portal checks live public DNS, not just its own records, so “not verified yet” is an expected result while propagation is still happening.
  4. Once the Portal shows the domain as Active, you’re ready to move on to step 1.

Important: You only add and verify the parent domain (e.g. dev.example.com) — not every individual app subdomain. rackctl gen-ssl and the wildcard DNS step below use whichever verified mapping most specifically covers the domain you request.

1. Generate SSL with rackctl

Use the following command to provision SSL for your domain:

rackctl gen-ssl app1.dev.example.com

app1.dev.example.com must fall under a domain you’ve already verified in step 0 (here, dev.example.com). Behind the scenes, gen-ssl now:

  1. Calls the Portal to ensure a wildcard DNS record (e.g. *.dev.example.com) exists and points at your cluster’s ingress IP — created or updated automatically in the verified hosted zone, so you don’t need to add this record yourself.
  2. Polls DNS until that record is visible, then proceeds with certificate issuance.

If the requested domain isn’t covered by any verified mapping, this step will fail with an error asking you to add and verify it in the Portal first (step 0).

Note: SSL termination is handled entirely by the rackctl system. Do not configure SSL-related annotations in your Kubernetes Ingress.

Note: Clusters created via rackctl are standard Kubernetes clusters and do not come with an ingress controller installed by default. Before creating the Ingress resource below, install NGINX Ingress:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

2. Create Ingress Resource

Create an ingress file named ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-prod
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"     # 1 hour timeout
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"     # 1 hour timeout
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"    # 60 seconds
    nginx.ingress.kubernetes.io/enable-websocket: "true"       # WebSocket support
    nginx.ingress.kubernetes.io/proxy-body-size: "0"           # 0 means no size restriction for POST/PUT/PATCH request body
spec:
  ingressClassName: nginx
  rules:
    - host: app1.dev.example.com
      http:
        paths:
          - path: /example
            pathType: Prefix
            backend:
              service:
                name: example-service
                port:
                  number: 80

3. Create Deployment for the App

Save the following as example-app/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-deploy
  labels:
    app: example-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
        - name: example-app
          image: docker.io/gingersociety/example-service
          ports:
            - containerPort: 80

4. Create Service for the App

Save the following as example-app/service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: example-service
  labels:
    app: example-app
spec:
  selector:
    app: example-app
  ports:
    - protocol: TCP
      name: http
      port: 80
      targetPort: 80

5. Deploy Resources

Apply the Kubernetes resources:

kubectl apply -f example-app/deployment.yaml
kubectl apply -f example-app/service.yaml
kubectl apply -f ingress.yaml

6. Access the Application

Once deployed and ingress is applied, access the app in your browser:

https://app1.dev.example.com/example

Notes

  • SSL is automatically handled by the rackctl system — Kubernetes Ingress does not need to manage certificates.
  • DNS for app1.dev.example.com is handled automatically once its parent domain is verified in the Portal (see step 0) — rackctl gen-ssl creates/updates the wildcard A record for you. You no longer need to manually point DNS at the ingress controller’s load balancer IP.
  • Removing a domain from DNS Mappings in the Portal deletes its hosted zone. If you’ve issued SSL certs or created records for subdomains under it, remove those first — Route53 won’t delete a zone that still has record sets beyond the default NS/SOA.
  • For troubleshooting, check logs with kubectl logs -n ingress-nginx <ingress-controller-pod-name>.