Overview
Nginx is a high-performance web server and reverse proxy. This template deploys Nginx as a stateless reverse proxy that routes incoming requests by path to other workloads in the same GVC, so several internal services can share one public endpoint. Thenginx.conf is generated from your locations values and mounted into the container from a secret.
A default install also deploys a small example backend and routes every request to it, so you can confirm the proxy works before pointing it at your own services.
This template does not create a GVC. It deploys into an existing GVC that you already have, and every workload it proxies to must already exist in that same GVC.
What Gets Created
Prerequisites
None for a default install. To proxy to your own services, each target workload must already exist in the same GVC, and its internal firewall must allow traffic fromRELEASE_NAME-nginx (for example same-gvc, or a workload list that includes the proxy).
Installation
Install the template into an existing GVC. No--set values are required:
UI
Browse, install, and manage templates visually
CLI
Manage templates from your terminal
Terraform
Declare templates in your Terraform configurations
Pulumi
Declare templates in your Pulumi programs
Configuration
Proxy Workload
proxyWorkload.image— the Nginx container image.proxyWorkload.port— the container port exposed by the workload. Leave it at80: the generatednginx.conflistens on80and the health probes check port80, neither of which follows this value.proxyWorkload.capacityAI— enables Control Plane CapacityAI on the proxy workload.proxyWorkload.timeoutSeconds— the workload request timeout in seconds.
Resources
resources.cpu/resources.memory— the CPU and memory limit for each Nginx replica.
Autoscaling
autoscaling.minScale/autoscaling.maxScale— the minimum and maximum replica count. The proxy is stateless, so raisingmaxScalescales it horizontally.autoscaling.maxConcurrency— the maximum number of concurrent requests per replica.
Example Backend
true, the chart deploys RELEASE_NAME-example and routes every / request to it. Set it to false before routing to your own services; otherwise the example keeps the / route.
Locations
location block that forwards matching requests to a workload in the same GVC:
Enter only the workload name in
workload. The chart builds the fully qualified internal hostname itself, WORKLOAD_NAME.GVC_NAME.cpln.local, and uses it for both the upstream address and the Host header sent to the target.
Example routing two paths to two services:
Built-in Routes
Two routes are always present, whateverlocations contains:
Any
500, 502, 503 or 504 from an upstream workload is replaced with the /fail response, so the client sees the JSON error body rather than the upstream page.
Connecting
Read the canonical endpoint:
{"success":true,"message":"OK"} means Nginx is serving. With the example backend enabled, a request to https://CANONICAL_ENDPOINT/ returns the example greeting page.
Operations
Changing the Routing
Thenginx.conf lives in the RELEASE_NAME-nginx-config secret and is rebuilt from your values on every Helm upgrade. Edit locations (and enableExample) in your values file, then upgrade:
nginx.conf:
Upgrading From 1.1.1 or Earlier
Versions 1.1.1 and earlier defaultedproxyWorkload.image to nginx:latest. Version 1.1.2 pins it to nginx:1.31.4, so an upgrade that does not set the image restarts the proxy on the pinned version. The proxy holds no data, so nothing needs to be migrated. To keep a specific image, set proxyWorkload.image explicitly.
Scaling and Availability
The proxy is stateless, so it scales horizontally. The shipped default runs exactly one replica (minScale: 1, maxScale: 1), which means a restart or redeployment briefly interrupts traffic. Set autoscaling.minScale to 2 or more for an endpoint other systems depend on, and raise autoscaling.maxScale to let it scale out under load.
Troubleshooting
Every request returns the example page
Every request returns the example page
Symptom: You added
locations, but requests to / still return the example greeting page.Cause: enableExample is still true, so the example backend keeps the / route.Fix: Set enableExample: false, run a Helm upgrade, then force a redeployment as described in Changing the Routing.A route returns the JSON error body
A route returns the JSON error body
Symptom: Requests to one of your paths return
500 with {"success":false,"message":"Error"}.Cause: The upstream returned a 5xx or could not be reached. The usual reasons are a workload value that does not match the target name exactly, a wrong port, or a target whose internal firewall does not allow RELEASE_NAME-nginx.Fix: Check that the target exists in the same GVC and listens on the configured port, put only the bare workload name in workload, and allow the proxy in the target’s internal firewall. Read the proxy logs to see the upstream error:The proxy never becomes ready after a routing change
The proxy never becomes ready after a routing change
Symptom: After an upgrade the proxy restarts repeatedly, while
cpln helm upgrade itself reported success.Cause: locations is written into nginx.conf as-is, so a malformed entry is only caught when Nginx starts. Two entries with the same path, or a / entry while enableExample is true, produce a duplicate location that Nginx refuses to load.Fix: Read the startup error in the logs, correct the entry in your values, and upgrade again:A routing change has no effect
A routing change has no effect
Symptom: The upgrade succeeded, but the proxy still routes the old way.Cause: The running replicas are still using the
nginx.conf they started with.Fix: Force a redeployment:Important Notes
- Set
enableExample: falsebefore routing to your own services; the default sends all/traffic to the example backend. - Put only the bare workload name in
locations[].workload; the chart appends.GVC_NAME.cpln.localitself. - Each target workload’s internal firewall must allow
RELEASE_NAME-nginx, or its route returns the JSON error body. - The proxy is always open to the internet; there is no value to make it private.
- Leave
proxyWorkload.portat80; Nginx and its health probes are fixed to that port. - After changing routing, force a redeployment so the replicas load the new
nginx.conf. - The example backend image,
gcr.io/knative-samples/helloworld-go, publishes only:latestand cannot be pinned; it does not affect the proxy.
External References
Nginx Documentation
Official Nginx documentation
Nginx Location Directive
How location paths and regex modifiers are matched
Nginx Reverse Proxy Guide
Proxying requests to upstream servers
Nginx Template
View the source files, default values, and chart definition