## File: README.md

[](https://scorecard.dev/viewer/?uri=github.com/nginx/kubernetes-ingress)
[](https://github.com/nginx/kubernetes-ingress/actions/workflows/regression.yml?query=event%3Aschedule)
[](https://opensource.org/licenses/Apache-2.0)
[](https://goreportcard.com/report/github.com/nginx/kubernetes-ingress)
[](https://codecov.io/gh/nginx/kubernetes-ingress)
[](https://github.com/nginx/kubernetes-ingress/releases/latest)

[](https://hub.docker.com/r/nginx/nginx-ingress)

[](https://artifacthub.io/packages/container/nginx-ingress/kubernetes-ingress)
[](https://www.repostatus.org/#active)


# NGINX Ingress Controller

This repo provides an implementation of an Ingress Controller for NGINX and NGINX Plus from the people behind NGINX.

---

## Join The Next Community Call

We value community input and would love to see you at the next community call. At these calls, we discuss PRs by community members as well as issues, discussions and feature requests.

**Zoom**: [NGINX Ingress Controller - Community Call](https://f5.zoom.us/j/98544055687?pwd=q4sGaaeWM0DawJTePBGbCngtfLJxgq.1&from=addon)

**Meeting ID:** `985 4405 5687`

**Passcode:** `982193`

**When**: 16:00 GMT / [Convert to your timezone](https://dateful.com/convert/gmt?t=16), every other Monday.

| **Community Call Dates** |
| ------------------------ |
| **2026-07-13**           |
| **2026-07-27**           |
| **2026-08-10**           |
| **2026-08-24**           |
| **2026-09-07**           |
| **2026-09-21**           |
| **2026-10-05**           |
| **2026-10-19**           |
| **2026-11-02**           |
| **2026-11-16**           |
| **2026-11-30**           |
| **2026-12-14**           |

You can also join the [NGINX Community Forum](https://community.nginx.org) to chat about the NGINX Ingress Controller.

---

NGINX Ingress Controller works with both NGINX and NGINX Plus and supports the standard Ingress features - content-based
routing and TLS/SSL termination.

Additionally, several NGINX and NGINX Plus features are available as extensions to the Ingress resource via annotations
and the ConfigMap resource. In addition to HTTP, NGINX Ingress Controller supports load balancing Websocket, gRPC, TCP
and UDP applications. See
[ConfigMap](https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/configmap-resource/) and
[Annotations](https://docs.nginx.com/nginx-ingress-controller/configuration/ingress-resources/advanced-configuration-with-annotations/)
docs to learn more about the supported features and customization options.

As an alternative to the Ingress, NGINX Ingress Controller supports the VirtualServer and VirtualServerRoute resources.
They enable use cases not supported with the Ingress resource, such as traffic splitting and advanced content-based
routing. See [VirtualServer and VirtualServerRoute resources
doc](https://docs.nginx.com/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/).

TCP, UDP and TLS Passthrough load balancing is also supported. See the [TransportServer resource
doc](https://docs.nginx.com/nginx-ingress-controller/configuration/transportserver-resource/).

Read [this doc](https://docs.nginx.com/nginx-ingress-controller/overview/nginx-plus/) to learn more about NGINX Ingress
Controller with NGINX Plus.

> **Note**
>
> This project is different from the NGINX Ingress Controller in
[kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx) repo.

## Ingress and Ingress Controller

### What is the Ingress?

The Ingress is a Kubernetes resource that lets you configure an HTTP load balancer for applications running on
Kubernetes, represented by one or more [Services](https://kubernetes.io/docs/concepts/services-networking/service/).
Such a load balancer is necessary to deliver those applications to clients outside of the Kubernetes cluster.

The Ingress resource supports the following features:

- **Content-based routing**:
  - *Host-based routing*. For example, routing requests with the host header `foo.example.com` to one group of services
  and the host header `bar.example.com` to another group.
  - *Path-based routing*. For example, routing requests with the URI that starts with `/serviceA` to service A and
  requests with the URI that starts with `/serviceB` to service B.
- **TLS/SSL termination** for each hostname, such as `foo.example.com`.

See the [Ingress User Guide](https://kubernetes.io/docs/concepts/services-networking/ingress/) to learn more about the
Ingress resource.

### What is the Ingress Controller?

The Ingress Controller is an application that runs in a cluster and configures an HTTP load balancer according to
Ingress resources. The load balancer can be a software load balancer running in the cluster or a hardware or cloud load
balancer running externally. Different load balancers require different Ingress Controller implementations.

In the case of NGINX, the Ingress Controller is deployed in a pod along with the load balancer.

## Getting Started

> **Note**
>
> All documentation should only be used with the latest stable release, indicated on [the releases
> page](https://github.com/nginx/kubernetes-ingress/releases) of the GitHub repository.

1. Install NGINX Ingress Controller using the [Helm
   chart](https://docs.nginx.com/nginx-ingress-controller/install/helm/) or the Kubernetes
   [manifests](https://docs.nginx.com/nginx-ingress-controller/install/manifests/).
1. Configure load balancing for a simple web application:
    - Use the Ingress resource. See the [Cafe
      example](https://github.com/nginx/kubernetes-ingress/tree/main/examples/ingress-resources/complete-example).
    - Or the VirtualServer resource. See the [Basic
      configuration](https://github.com/nginx/kubernetes-ingress/tree/main/examples/custom-resources/basic-configuration)
      example.
1. See additional configuration [examples](https://github.com/nginx/kubernetes-ingress/tree/main/examples).
1. Learn more about all available configuration and customization in the
   [docs](https://docs.nginx.com/nginx-ingress-controller/).

## NGINX Ingress Controller Releases

We publish NGINX Ingress Controller releases on GitHub. See our [releases
page](https://github.com/nginx/kubernetes-ingress/releases).

The latest stable release is [5.5.4](https://github.com/nginx/kubernetes-ingress/releases/tag/v5.5.4). For production
use, we recommend that you choose the latest stable release.

The edge version is useful for experimenting with new features that are not yet published in a stable release. To use
it, choose the *edge* version built from the [latest
commit](https://github.com/nginx/kubernetes-ingress/commits/main) from the main branch.

To use NGINX Ingress Controller, you need to have access to:

- An NGINX Ingress Controller image.
- Installation manifests or a Helm chart.
- Documentation and examples.

It is important that the versions of those things above match.

The table below summarizes the options regarding the images, Helm chart, manifests, documentation and examples and gives
your links to the correct versions:

| Version | Description | Image for NGINX | Image for NGINX Plus | Installation Manifests and Helm Chart | Documentation and Examples |
| ------- | ----------- | --------------- | -------------------- | --------------------------------------- | -------------------------- |
| Latest stable release | For production use | Use the 5.5.4 images from [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/), [GitHub Container](https://github.com/nginx/kubernetes-ingress/pkgs/container/kubernetes-ingress), [Amazon ECR Public Gallery](https://gallery.ecr.aws/nginx/nginx-ingress) or [Quay.io](https://quay.io/repository/nginx/nginx-ingress) or [build your own image](https://docs.nginx.com/nginx-ingress-controller/install/build/). | Use the 5.5.4 images from the [F5 Container Registry](https://docs.nginx.com/nginx-ingress-controller/install/images/registry-download/) or [Build your own image](https://docs.nginx.com/nginx-ingress-controller/install/build). | [Manifests](https://github.com/nginx/kubernetes-ingress/tree/v5.5.4/deployments). [Helm chart](https://github.com/nginx/kubernetes-ingress/tree/v5.5.4/charts/nginx-ingress). | [Documentation](https://docs.nginx.com/nginx-ingress-controller/). [Examples](https://docs.nginx.com/nginx-ingress-controller/configuration/configuration-examples/). |
| Edge/Nightly | For testing and experimenting | Use the edge or nightly images from [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/), [GitHub Container](https://github.com/nginx/kubernetes-ingress/pkgs/container/kubernetes-ingress), [Amazon ECR Public Gallery](https://gallery.ecr.aws/nginx/nginx-ingress) or [Quay.io](https://quay.io/repository/nginx/nginx-ingress) or [build your own image](https://docs.nginx.com/nginx-ingress-controller/install/build/). | [Build your own image](https://docs.nginx.com/nginx-ingress-controller/install/build/). | [Manifests](https://github.com/nginx/kubernetes-ingress/tree/main/deployments). [Helm chart](https://github.com/nginx/kubernetes-ingress/tree/main/charts/nginx-ingress). | [Documentation](https://docs.nginx.com/nginx-ingress-controller). [Examples](https://github.com/nginx/kubernetes-ingress/tree/main/examples). |

## SBOM (Software Bill of Materials)

We generate SBOMs for the binaries and the Docker images.

### Binaries

The SBOMs for the binaries are available in the releases page. The SBOMs are generated using
[syft](https://github.com/anchore/syft) and are available in SPDX format.

### Docker Images

The SBOMs for the Docker images are available in the [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/), [GitHub
Container](https://github.com/nginx/kubernetes-ingress/pkgs/container/kubernetes-ingress), [Amazon ECR Public
Gallery](https://gallery.ecr.aws/nginx/nginx-ingress) or [Quay.io](https://quay.io/repository/nginx/nginx-ingress)
repositories. The SBOMs are generated using [syft](https://github.com/anchore/syft) and stored as an attestation in the
image manifest.

For example to retrieve the SBOM for `linux/amd64` from Docker Hub and analyze it using
[grype](https://github.com/anchore/grype) you can run the following command:

```console
docker buildx imagetools inspect nginx/nginx-ingress:edge --format '{{ json (index .SBOM "linux/amd64").SPDX }}' | grype
```

## Contacts

We’d like to hear your feedback! If you have any suggestions or experience issues with our Ingress Controller, please
create an issue or send a pull request on GitHub.

## Contributing

If you'd like to contribute to the project, please read our [Contributing guide](CONTRIBUTING.md).

## Support

For NGINX Plus customers NGINX Ingress Controller (when used with NGINX Plus) is covered by the support contract.

---

## File: charts/nginx-ingress/README.md

# Helm Documentation

Please refer to the [Installation with Helm](https://docs.nginx.com/nginx-ingress-controller/install/helm/) guide in the NGINX Ingress Controller documentation site.

---

## File: deployments/README.md

# Installation

This folder includes Kubernetes manifests for installing NGINX or NGINX Plus Ingress Controller. Read [the installation
instructions](https://docs.nginx.com/nginx-ingress-controller/install/).

---

## File: examples/shared-examples/wildcard-tls-certificate/README.md

# Wildcard TLS Certificate

The wildcard TLS certificate simplifies the configuration of TLS termination if you need to use the same TLS certificate
in multiple Ingress and VirtualServer resources from various namespaces. Typically, such a certificate is for a
subdomain (for example, `*.example.com`), while the hosts in the Ingress and VirtualServer resources include that
subdomain (for example, `foo.example.com`, `bar.example.com`).

## Example

### Prerequisites

Start the Ingress Controller with the `-wildcard-tls-secret` [command-line
argument](https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/command-line-arguments/#cmdoption-wildcard-tls-secret)
set to a TLS secret with a wildcard cert/key. For example:

```yaml
-wildcard-tls-secret=nginx-ingress/wildcard-tls-secret
```

**Note**: the Ingress Controller supports only one wildcard TLS secret.

### Configuring TLS Termination

In the example below we configure TLS termination for an Ingress for the host `foo.example.com` and a VirtualServer for
the host `bar.example.com`:

`foo` Ingress from the namespace `foo`:

 ```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: foo
  namespace: foo
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - foo.example.com
  rules:
  - host: foo.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: foo-service
            port:
              number: 80
 ```

`bar` VirtualServer from the namespace `bar`:

```yaml
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: bar
  namespace: bar
spec:
  host: bar.example.com
  tls:
    secret: ""
  upstreams:
  - name: bar
    service: bar-service
    port: 80
  routes:
  - path: /
    action:
      pass: bar
```

Because we don't reference any TLS secret in the resources above -- there is no `secret` field in the `tls` section of
the Ingress resource and the `secret` field is empty in the VirtualServer -- NGINX will use the wildcard secret
specified in the `-wildcard-tls-secret` command-line argument.

---

## File: examples/shared-examples/rbac/README.md

# RBAC

It is possible to run the Ingress Controller in a cluster with
[RBAC](https://kubernetes.io/docs/admin/authorization/rbac/) enabled.
Read the [installation instructions](https://docs.nginx.com/nginx-ingress-controller/install/manifests).

---

## File: examples/shared-examples/proxy-protocol/README.md

# PROXY Protocol

Proxies and load balancers, such as HAProxy or ELB, can pass the client's information (the IP address and the port) to
the next proxy or load balancer via the PROXY Protocol. To enable NGINX Ingress Controller to receive that information,
use the `proxy-protocol` ConfigMaps configuration key as well as the `real-ip-header` and the `set-real-ip-from` keys.
Once you enable the PROXY Protocol, it is enabled for every Ingress and VirtualServer resource. **NOTE** TransportServer
resource supports PROXY Protocol only when TLS Passthrough is enabled for the Ingress Controller.

## Syntax

The `proxy-protocol` key syntax is as follows:

```yaml
proxy-protocol: "True | False"
```

Additionally, you must configure the following keys:

- **real-ip-header**: Set its value to `proxy_protocol`.
- **set-real-ip-from**: Set its value to the IP address or the subnet of the proxy or the load balancer. See
  [set-real-ip-from](https://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from)

## Example

In the example below we configure the PROXY Protocol via a ConfigMaps resource. `set-real-ip-from` is set to
`192.168.0.0/16`. This is the CIDR range of the proxy that sits in front of the Ingress Controller in this example. You
can set this to `0.0.0.0/0` to trust all IPs. After we create the ConfigMaps resource, the client's IP address is
available via the `$remote_addr` variable in the NGINX configuration. By default, NGINX Ingress Controller logs the
value of this variable and also passes the value to the backend service in the `X-Real-IP` header.

The default log format for NGINX is `'$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent
"$http_referer" "$http_user_agent"'`

```yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
data:
  proxy-protocol: "True"
  real-ip-header: "proxy_protocol"
  set-real-ip-from: "192.168.0.0/16"
```

---

## File: examples/shared-examples/otel/README.md

# Enable OpenTelemetry

This is the example code used in the [Enable OpenTelemetry](https://docs.nginx.com/nginx-ingress-controller/logging-and-monitoring/opentelemetry) documentation.

---

## File: examples/shared-examples/nginx-plus-secret/README.md

# NGINX Plus Secret

Refer to the [Create License Secret](https://docs.nginx.com/nginx-ingress-controller/install/license-secret/) docs to download and create a License Secret

---

## File: examples/shared-examples/custom-templates/README.md

# Custom Templates

The Ingress Controller allows you to customize your templates through a
[ConfigMap](https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/configmap-resource/#snippets-and-custom-templates)
via the following keys:

- `main-template` - Sets the main NGINX configuration template.
- `ingress-template` - Sets the Ingress NGINX configuration template for an Ingress resource.
- `virtualserver-template` - Sets the NGINX configuration template for an VirtualServer resource.
- `transportserver-template` - Sets the NGINX configuration template for a TransportServer resource.

## Example

```yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
  namespace: nginx-ingress
data:
  main-template: |
    worker_processes  {{.WorkerProcesses}};
    ...
        include /etc/nginx/conf.d/*.conf;
    }
  ingress-template: |
    {{range $upstream := .Upstreams}}
    upstream {{$upstream.Name}} {
      {{if $upstream.LBMethod }}{{$upstream.LBMethod}};{{end}}
    ...
    }{{end}}
  virtualserver-template: |
    {{ range $u := .Upstreams }}
    upstream {{ $u.Name }} {
      {{ if ne $u.UpstreamZoneSize "0" }}zone {{ $u.Name }} {{ $u.UpstreamZoneSize }};{{ end }}
    ...
    }
    {{ end }}
  transportserver-template: |
    {{- range $u := .Upstreams }}
    upstream {{ $u.Name }} {
        zone {{ $u.Name }} 256k;
    ...
    }
```

**Notes:**

- The templates are truncated for the clarity of the example.
- The templates for NGINX (the main `nginx.tmpl` and the Ingress `nginx.ingress.tmpl`) and NGINX Plus (the main
  `nginx-plus.tmpl` and the Ingress `nginx-plus.ingress.tmpl`) are located at
  [internal/configs/version1](../../../internal/configs/version1/). The VirtualServer templates for NGINX
  (`nginx.virtualserver.tmpl`) and NGINX Plus (`nginx-plus.virtualserver.tmpl`) are located at
  [internal/configs/version2](../../../internal/configs/version2/).

## Troubleshooting

- If a custom template contained within the ConfigMap is invalid on startup, the Ingress Controller will fail to start,
  the error will be reported in the Ingress Controller logs.

    An example of an error from the logs:

    ```text
    Error updating NGINX main template: template: nginxTemplate:98: unexpected EOF
    ```

- If a custom template contained within the ConfigMap is invalid on update, the Ingress Controller will not update the
  NGINX configuration, the error will be reported in the Ingress Controller logs and an event with the error will be
  associated with the ConfigMap.

    An example of an error from the logs:

    ```text
    Error when updating config from ConfigMap: Invalid nginx configuration detected, not reloading
    ```

  An example of an event with an error (you can view events associated with the ConfigMap by running `kubectl describe
  -n nginx-ingress configmap nginx-config`):

    ```text
    Events:
      Type     Reason            Age                From                      Message
      ----     ------            ----               ----                      -------
      Normal   Updated           12s (x2 over 25s)  nginx-ingress-controller  Configuration from nginx-ingress/nginx-config was updated
      Warning  UpdatedWithError  10s                nginx-ingress-controller  Configuration from nginx-ingress/nginx-config was updated, but not applied: Error when parsing the main template: template: nginxTemplate:98: unexpected EOF
      Warning  UpdatedWithError  8s                 nginx-ingress-controller  Configuration from nginx-ingress/nginx-config was updated, but not applied: Error when writing main Config
    ```

- If custom templates from before version 5.5 are used without updating to match the upstream versions, the Ingress
  Controller may fail to start. The error will be reported in the Ingress Controller logs.

  An example of an error from the logs:

    ```text
    Error generating NGINX main config: template: nginxTemplate:142:18: executing "nginxTemplate" at <.DefaultHTTPListenerPort>: can't evaluate field DefaultHTTPListenerPort in type *version1.MainConfig
    ```

---

## File: examples/shared-examples/custom-log-format/README.md

# Custom NGINX log format

This example lets you set the log-format for NGINX using the configmap resource

```yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
  namespace: nginx-ingress
data:
  log-format:  '$remote_addr - $remote_user [$time_local] "$request" $status $grpc_status $body_bytes_sent "$http_referer"  "$http_user_agent" "$http_x_forwarded_for" "$resource_name" "$resource_type" "$resource_namespace" "$service"'
```

In addition to the [built-in NGINX variables](https://nginx.org/en/docs/varindex.html), you can also use the variables
that the Ingress Controller configures:

- $resource_type - The type of kubernetes resource that handled the client request.
- $resource_name - The name of the resource
- $resource_namespace - The namespace the resource exists in.
- $service - The name of the service the client request was sent to.
- $grpc_status - the gRPC status code, which is constructed either from the HTTP/2 trailer (grpc_status) returned from
  the backend for normal conditions, or from the HTTP/2 header (grpc_status) set either by the backend or by NGINX
  itself for some error conditions.

**note** These variables are only available for Ingress, VirtualServer and VirtualServerRoute resources.