Skip to content

Support configurable hostPort in helm chart #3321

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5d59c04
feat: hostPort configurable
Gasoid Apr 24, 2025
6dcba57
Merge branch 'main' into feat/hostPort
Gasoid Apr 30, 2025
b956397
Merge branch 'main' of github.com:nginx/nginx-gateway-fabric into fea…
Gasoid May 29, 2025
1f7f09a
Merge branch 'main' of github.com:nginx/nginx-gateway-fabric into fea…
Gasoid May 29, 2025
185ced7
feat: hostPort for agent-grpc configurable
Gasoid May 29, 2025
40f2b70
feat: helm schema
Gasoid May 29, 2025
bbf9a67
feat: helm config
Gasoid May 29, 2025
8317ade
hostPort crds
Gasoid Jun 10, 2025
ab12cf4
Merge branch 'main' of github.com:nginx/nginx-gateway-fabric into fea…
Gasoid Jun 10, 2025
bfe712d
hostPort crds
Gasoid Jun 10, 2025
fb1abc5
Merge branch 'main' into feat/hostPort
Gasoid Jun 10, 2025
343d24a
omitempty is obsolete
Gasoid Jun 10, 2025
f9ba83d
hostPort tests
Gasoid Jun 11, 2025
13897e1
Merge branch 'main' into feat/hostPort
Gasoid Jun 11, 2025
eed4093
gateway listener is ok
Gasoid Jun 11, 2025
50b3400
comments typo
Gasoid Jun 11, 2025
bb6fb37
Merge branch 'main' into feat/hostPort
Gasoid Jun 11, 2025
60fd6fd
Merge branch 'main' into feat/hostPort
Gasoid Jun 11, 2025
995eaa5
hostPorts list
Gasoid Jun 12, 2025
8f2e721
hostPorts list
Gasoid Jun 12, 2025
ed1d0c5
Merge branch 'main' into feat/hostPort
Gasoid Jun 12, 2025
3253d56
hostPorts list
Gasoid Jun 12, 2025
4a2868d
Merge branch 'feat/hostPort' of github.com:Gasoid/nginx-gateway-fabri…
Gasoid Jun 12, 2025
2e6a1ce
Merge branch 'main' into feat/hostPort
Gasoid Jun 12, 2025
1dc1850
Merge branch 'main' into feat/hostPort
Gasoid Jun 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions apis/v1alpha2/nginxproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,11 @@ type ContainerSpec struct {
// +optional
Lifecycle *corev1.Lifecycle `json:"lifecycle,omitempty"`

// HostPorts are the list of ports to expose on the host
//
// +optional
HostPorts []HostPort `json:"hostPorts,omitempty"`

// VolumeMounts describe the mounting of Volumes within a container.
//
// +optional
Expand Down Expand Up @@ -608,3 +613,16 @@ type NodePort struct {
// kubebuilder:validation:Maximum=65535
ListenerPort int32 `json:"listenerPort"`
}

// HostPort to expose on the host.
type HostPort struct {
// ContainerPort is nginx port.
// kubebuilder:validation:Minimum=1
// kubebuilder:validation:Maximum=65535
ContainerPort int32 `json:"containerPort"`

// Number of port to expose on the host.
// kubebuilder:validation:Minimum=1
// kubebuilder:validation:Maximum=65535
HostPort int32 `json:"hostPort"`
}
5 changes: 3 additions & 2 deletions charts/nginx-gateway-fabric/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,10 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri
| `certGenerator.ttlSecondsAfterFinished` | How long to wait after the cert generator job has finished before it is removed by the job controller. | int | `30` |
| `clusterDomain` | The DNS cluster domain of your Kubernetes cluster. | string | `"cluster.local"` |
| `gateways` | A list of Gateway objects. View https://gateway-api.sigs.k8s.io/reference/spec/#gateway for full Gateway reference. | list | `[]` |
| `nginx` | The nginx section contains the configuration for all NGINX data plane deployments installed by the NGINX Gateway Fabric control plane. | object | `{"config":{},"container":{},"debug":false,"image":{"pullPolicy":"Always","repository":"ghcr.io/nginx/nginx-gateway-fabric/nginx","tag":"edge"},"imagePullSecret":"","imagePullSecrets":[],"kind":"deployment","plus":false,"pod":{},"replicas":1,"service":{"externalTrafficPolicy":"Local","loadBalancerClass":"","loadBalancerIP":"","loadBalancerSourceRanges":[],"nodePorts":[],"type":"LoadBalancer"},"usage":{"caSecretName":"","clientSSLSecretName":"","endpoint":"","resolver":"","secretName":"nplus-license","skipVerify":false}}` |
| `nginx` | The nginx section contains the configuration for all NGINX data plane deployments installed by the NGINX Gateway Fabric control plane. | object | `{"config":{},"container":{"hostPorts":[]},"debug":false,"image":{"pullPolicy":"Always","repository":"ghcr.io/nginx/nginx-gateway-fabric/nginx","tag":"edge"},"imagePullSecret":"","imagePullSecrets":[],"kind":"deployment","plus":false,"pod":{},"replicas":1,"service":{"externalTrafficPolicy":"Local","loadBalancerClass":"","loadBalancerIP":"","loadBalancerSourceRanges":[],"nodePorts":[],"type":"LoadBalancer"},"usage":{"caSecretName":"","clientSSLSecretName":"","endpoint":"","resolver":"","secretName":"nplus-license","skipVerify":false}}` |
| `nginx.config` | The configuration for the data plane that is contained in the NginxProxy resource. This is applied globally to all Gateways managed by this instance of NGINX Gateway Fabric. | object | `{}` |
| `nginx.container` | The container configuration for the NGINX container. This is applied globally to all Gateways managed by this instance of NGINX Gateway Fabric. | object | `{}` |
| `nginx.container` | The container configuration for the NGINX container. This is applied globally to all Gateways managed by this instance of NGINX Gateway Fabric. | object | `{"hostPorts":[]}` |
| `nginx.container.hostPorts` | The hostPort configuration | list | `[]` |
| `nginx.debug` | Enable debugging for NGINX. Uses the nginx-debug binary. The NGINX error log level should be set to debug in the NginxProxy resource. | bool | `false` |
| `nginx.image.repository` | The NGINX image to use. | string | `"ghcr.io/nginx/nginx-gateway-fabric/nginx"` |
| `nginx.imagePullSecret` | The name of the secret containing docker registry credentials. Secret must exist in the same namespace as the helm release. The control plane will copy this secret into any namespace where NGINX is deployed. | string | `""` |
Expand Down
26 changes: 26 additions & 0 deletions charts/nginx-gateway-fabric/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,32 @@
},
"container": {
"description": "The container configuration for the NGINX container. This is applied globally to all Gateways managed by this\ninstance of NGINX Gateway Fabric.",
"properties": {
"hostPorts": {
"description": "The hostPort configuration",
"items": {
"properties": {
"containerPort": {
"maximum": 65535,
"minimum": 1,
"required": [],
"type": "integer"
},
"hostPort": {
"maximum": 65535,
"minimum": 1,
"required": [],
"type": "integer"
}
},
"required": [],
"type": "object"
},
"required": [],
"title": "hostPorts",
"type": "array"
}
},
"required": [],
"title": "container",
"type": "object"
Expand Down
24 changes: 23 additions & 1 deletion charts/nginx-gateway-fabric/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,29 @@ nginx:

# -- The container configuration for the NGINX container. This is applied globally to all Gateways managed by this
# instance of NGINX Gateway Fabric.
container: {}
container:

# @schema
# type: array
# items:
# type: object
# properties:
# containerPort:
# type: integer
# required: true
# minimum: 1
# maximum: 65535
# hostPort:
# type: integer
# required: true
# minimum: 1
# maximum: 65535
# @schema
# -- The hostPort configuration
hostPorts: []
# - containerPort: 80
# hostPort: 80

# -- The resource requirements of the NGINX container.
# resources: {}

Expand Down
16 changes: 16 additions & 0 deletions config/crd/bases/gateway.nginx.org_nginxproxies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,22 @@ spec:
StopSignal can only be set for Pods with a non-empty .spec.os.name
type: string
type: object
hostPorts:
description: |-
List of ports to expose on the host.
items:
containerPort:
description: |-
ContainerPort number of nginx
type: integer
hostPort:
description: |-
HostPort number to expose on the host
type: integer
required:
- containerPort
- hostPort
type: array
resources:
description: Resources describes the compute resource
requirements.
Expand Down
16 changes: 16 additions & 0 deletions deploy/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,22 @@ spec:
StopSignal can only be set for Pods with a non-empty .spec.os.name
type: string
type: object
hostPorts:
description: |-
List of ports to expose on the host.
items:
containerPort:
description: |-
ContainerPort of nginx
type: integer
hostPort:
description: |-
HostPort number to expose on the host
type: integer
required:
- containerPort
- hostPort
type: array
resources:
description: Resources describes the compute resource
requirements.
Expand Down
9 changes: 9 additions & 0 deletions internal/controller/provisioner/objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,15 @@ func (p *NginxProvisioner) buildNginxPodTemplateSpec(
container.Command = append(container.Command, "/agent/entrypoint.sh")
container.Args = append(container.Args, "debug")
}

for _, hostPort := range containerSpec.HostPorts {
for i, port := range container.Ports {
if hostPort.ContainerPort == port.ContainerPort {
container.Ports[i].HostPort = hostPort.HostPort
}
}
}

spec.Spec.Containers[0] = container
}
}
Expand Down
12 changes: 12 additions & 0 deletions internal/controller/provisioner/objects_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ func TestBuildNginxResourceObjects_NginxProxyConfig(t *testing.T) {
Name: "gw",
Namespace: "default",
},
Spec: gatewayv1.GatewaySpec{
Listeners: []gatewayv1.Listener{
{Name: "port-8443", Port: 8443, Protocol: "tcp"},
},
},
}

resourceName := "gw-nginx"
Expand Down Expand Up @@ -293,6 +298,7 @@ func TestBuildNginxResourceObjects_NginxProxyConfig(t *testing.T) {
corev1.ResourceCPU: resource.Quantity{Format: "100m"},
},
},
HostPorts: []ngfAPIv1alpha2.HostPort{{ContainerPort: int32(8443), HostPort: int32(8443)}},
},
},
},
Expand Down Expand Up @@ -344,6 +350,12 @@ func TestBuildNginxResourceObjects_NginxProxyConfig(t *testing.T) {
g.Expect(container.ImagePullPolicy).To(Equal(corev1.PullAlways))
g.Expect(container.Resources.Limits).To(HaveKey(corev1.ResourceCPU))
g.Expect(container.Resources.Limits[corev1.ResourceCPU].Format).To(Equal(resource.Format("100m")))

g.Expect(container.Ports).To(ContainElement(corev1.ContainerPort{
ContainerPort: 8443,
Name: "port-8443",
HostPort: 8443,
}))
}

func TestBuildNginxResourceObjects_Plus(t *testing.T) {
Expand Down