ZuploZuplo
LoginStart for Free
  • Documentation
  • API Reference
Getting Started
    Develop in the portal
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingDynamic MCP Server - Quickstart
    Develop locally with the CLI
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingDynamic MCP Server - Quickstart
Concepts
API Management
AI Gateway
MCP Gateway
MCP Server
Developer Portal
Development
Deploying & Source Control
Analytics
Observability
Networking & Infrastructure
    Overview
    Managed Dedicated
    Managed Edge
    Self Hosted
      OverviewRequirementsInstallVerify your installUpgradeTroubleshooting
    Custom Domains
    Securing Your Backend
    Web Application Firewalls
    DDoS Protection
Account Management
Programming API
Build with AI
Zuplo CLI
Migration Guides
Platform LimitsVersion Support PolicySecuritySupportTrust & ComplianceChangelog
powered by Zudoku
Self Hosted

Verify Your Install

Run the six checks in order. Each check depends on the previous one, which helps you identify the source of a failure. Checks one through five require only the installation. Check six also requires a Zuplo API key and project.

Check the deployments

Gate on readiness before testing anything over the network.

TerminalCode
kubectl wait --for=condition=Available deployment --all \ -n zuplo-system --timeout=5m kubectl wait --for=condition=Available deployment --all \ -n zuplo --timeout=5m
Code
deployment.apps/control-plane condition met deployment.apps/deployer condition met deployment.apps/gateway condition met deployment.apps/storage condition met deployment.apps/acme-forwarder condition met deployment.apps/custom-error-pages condition met deployment.apps/zuplo-cert-manager condition met deployment.apps/zuplo-cert-manager-cainjector condition met deployment.apps/zuplo-cert-manager-webhook condition met deployment.apps/zuplo-haproxy-ingress condition met deployment.apps/zuplo-kube-prometheus-stac-operator condition met deployment.apps/zuplo-kube-state-metrics condition met deployment.apps/zuplo-prometheus-adapter condition met

The control-plane, deployer, gateway, storage, and acme-forwarder deployments are part of the Zuplo management plane. The other deployments come from subcharts.

Check the ingress

Send a request for a hostname that has no Ingress. This checks that the load balancer can reach HAProxy.

TerminalCode
LB=$(kubectl get svc zuplo-haproxy-ingress -n zuplo \ -o jsonpath='{.status.loadBalancer.ingress[0].ip}') curl -i "http://$LB/" -H 'Host: no-such-deployment.example.com'
Code
HTTP/1.1 404 Not Found content-type: text/html { "type": "https://httpproblems.com/http-status/404", "title": "Not Found", "status": 404, "detail": "This Zuplo project does not exist" }

The expected result is 404 Not Found from HAProxy's default backend. A timeout or refused connection means that traffic isn't reaching the ingress controller.

Use a hostname without an Ingress for this check. Hosts with an Ingress redirect port 80 to HTTPS and return a 302 instead.

Requests for hosts with an Ingress are redirected from port 80 to 443. The separate challenge Ingress created by cert-manager continues to serve ACME challenge paths on port 80.

Check the control plane

The control plane turns your values into a Configuration resource, then creates the management API's Ingress from it.

TerminalCode
kubectl get configuration default -n zuplo-system -o yaml
Code
spec: account: name: acme-corp builder: registry: us-docker.pkg.dev/acme-corp/zuplo-gateways secretName: builder-secret deployments: subdomain: api.example.com certificates: certManager: issuer: zuplo-cluster-issuer managementApi: hostname: zuplo-admin.example.com ingressControllers: - haproxy

Confirm every value matches what you put in zuplo-values.yaml. A single-cluster installation has no workers or authorization entry. Those settings are for installations that distribute deployments across clusters.

Then confirm the reconciler acted on the rest:

TerminalCode
kubectl get ingress -n zuplo-system kubectl get clusterissuer
Code
NAME CLASS HOSTS ADDRESS PORTS AGE gateway-haproxy haproxy zuplo-admin.example.com 203.0.113.24 80, 443 62s NAME READY STATUS AGE zuplo-cluster-issuer True The ACME account was registered with the ACME server 116s

READY: True for zuplo-cluster-issuer means that the chart registered an account with the certificate authority. It doesn't indicate whether a certificate has been issued.

Configuration doesn't report a status. Check the Ingress and ClusterIssuer resources that it produces instead.

Check certificate issuance

Check that the certificate authority issued a certificate for the management API hostname:

TerminalCode
kubectl get certificate -A
Code
NAMESPACE NAME READY SECRET AGE zuplo-system gateway-cert-manager True gateway-cert-manager 4m

READY: True means that the certificate authority validated your hostname and issued a certificate. If it remains False for more than a few minutes, see Troubleshooting.

cert-manager retries automatically after you fix DNS. You don't need to restart it.

Check the management API

Send an unauthenticated request to check DNS, the load balancer, HAProxy, the certificate, and authentication:

TerminalCode
curl -i https://zuplo-admin.example.com/v1/deployments
Code
HTTP/2 401 { "type": "https://httpproblems.com/http-status/401", "title": "Unauthorized", "status": 401, "detail": "No Authorization Header", ... }

The expected result is 401 Unauthorized. It confirms that curl completed a TLS handshake with a trusted certificate and that the gateway requires an API key. A TLS error indicates a certificate problem. A timeout indicates a DNS or load balancer problem.

Confirm the certificate is the real one rather than HAProxy's self-signed fallback:

TerminalCode
echo | openssl s_client -connect zuplo-admin.example.com:443 \ -servername zuplo-admin.example.com 2>/dev/null | openssl x509 -noout -subject -issuer
Code
subject=CN=zuplo-admin.example.com issuer=C=US, O=Let's Encrypt, CN=YR2

An issuer of CN=kubernetes-ingress-ca means HAProxy is serving its built-in fallback certificate because no issued certificate is available. Repeat the certificate issuance check.

Deploy and call a project

The final check builds a gateway image in your cluster, stores it in your registry, and serves it from your infrastructure.

Deploy your project with the Zuplo CLI. The project field in zuplo.jsonc selects the project, and Zuplo routes the deployment to your cluster:

TerminalCode
export ZUPLO_API_KEY='<your Zuplo API key>' npx zuplo deploy

Zuplo compiles the project, then hands the compiled bundle to your cluster's management API, which builds the container image and rolls it out.

While the command runs, watch the build Job in your cluster:

TerminalCode
kubectl get jobs -n zuplo-system -w
Code
NAME STATUS COMPLETIONS DURATION AGE build-basic-main-ca9748b-ztcwzdd Running 0/1 32s 32s build-basic-main-ca9748b-ztcwzdd Complete 1/1 58s 63s

Confirm that the deployment uses an image from your registry:

TerminalCode
kubectl get deploy -n zuplo -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.template.spec.containers[0].image}{"\n"}{end}'
Code
basic-main-ca9748b us-docker.pkg.dev/acme-corp/zuplo-gateways/basic-main-ca9748b:20260806-172436

Ask the management API what it is serving:

TerminalCode
curl -H "Authorization: Bearer $ZUPLO_API_KEY" \ https://zuplo-admin.example.com/v1/deployments
Code
{ "data": [ { "projectName": "basic", "deploymentName": "basic-main-ca9748b-haproxy", "deploymentUrl": "https://basic-main-ca9748b.api.example.com" } ] }

Call the deployed API:

TerminalCode
curl https://basic-main-ca9748b.api.example.com/hello

The first request to a deployment can fail while cert-manager issues its certificate. Retry the request for up to a minute.

The CLI can misreport the status of deployments to self-hosted clusters. See Troubleshooting. Use the in-cluster checks to confirm the result.

Resolve a failed check

Troubleshooting lists errors from these checks and their causes.

Edit this page
Last modified on August 27, 2026
InstallUpgrade
On this page
  • Check the deployments
  • Check the ingress
  • Check the control plane
  • Check certificate issuance
  • Check the management API
  • Deploy and call a project
  • Resolve a failed check
YAML
JSON