Building NGINX Ingress Controller

Learn how to build an NGINX Ingress Controller image from source codes and upload it to a private Docker registry. You’ll also find information on the Makefile targets and variables.

Pre-built image alternatives
If you’d rather not build your own NGINX Ingress Controller image, see the pre-built image options at the end of this guide.

Before you start

To get started, you need the following software installed on your machine:

  • Docker v19.03 or higher
  • GNU Make
  • git
  • OpenSSL, optionally, if you would like to generate a self-signed certificate and a key for the default server.
  • For NGINX Plus users, download the certificate (nginx-repo.crt) and key (nginx-repo.key) from MyF5.

Although NGINX Ingress Controller is written in Golang, you don’t need to have Golang installed. You can either download the precompiled binary file or build NGINX Ingress Controller in a Docker container.


Prepare the environment

Get your system ready for building and pushing the NGINX Ingress Controller image.

  1. Sign in to your private registry. Replace <my-docker-registry> with the path to your own private registry.

    docker login <my-docker-registry>
    
  2. Clone the NGINX Ingress Controller GitHub repository. Replace <version_number> with the version of NGINX Ingress Controller you want.

    git clone https://github.com/nginxinc/kubernetes-ingress.git --branch <version_number>
    cd kubernetes-ingress
    

    For instance if you want to clone version v3.5.1, the commands to run would be:

    git clone https://github.com/nginxinc/kubernetes-ingress.git --branch v3.5.1
    cd kubernetes-ingress
    

Build the NGINX Ingress Controller image

After setting up your environment, follow these steps to build the NGINX Ingress Controller image.

Note:
If you have a local Golang environment and want to build the binary yourself, remove TARGET=download from the make commands. If you don’t have Golang but still want to build the binary, use TARGET=container.

For NGINX

  1. Build the image. Replace <my-docker-registry> with your private registry’s path.

    • For a Debian-based image:

      make debian-image PREFIX=<my-docker-registry>/nginx-ingress TARGET=download
      
    • For an Alpine-based image:

      make alpine-image PREFIX=<my-docker-registry>/nginx-ingress TARGET=download
      

    What to expect: The image is built and tagged with a version number, which is derived from the VERSION variable in the Makefile. This version number is used for tracking and deployment purposes.

For NGINX Plus

  1. Place your NGINX Plus license files (nginx-repo.crt and nginx-repo.key) in the project’s root folder. To verify they’re in place, run:

    ls nginx-repo.*
    

    You should see:

    nginx-repo.crt  nginx-repo.key
    
  2. Build the image. Replace <my-docker-registry> with your private registry’s path.

    make debian-image-plus PREFIX=<my-docker-registry>/nginx-plus-ingress TARGET=download
    

    What to expect: The image is built and tagged with a version number, which is derived from the VERSION variable in the Makefile. This version number is used for tracking and deployment purposes.

Note:
In the event a patch version of NGINX Plus is released, make sure to rebuild your image to get the latest version. If your system is caching the Docker layers and not updating the packages, add DOCKER_BUILD_OPTIONS="--pull --no-cache" to the make command.

Push the image to your private registry

Once you’ve successfully built the NGINX or NGINX Plus Ingress Controller image, the next step is to upload it to your private Docker registry. This makes the image available for deployment to your Kubernetes cluster.

For NGINX

  1. Upload the NGINX image. If you’re using a custom tag, append TAG=your-tag to the command. Replace <my-docker-registry> with your private registry’s path.

    make push PREFIX=<my-docker-registry>/nginx-ingress
    

For NGINX Plus

  1. Upload the NGINX Plus image. Like with the NGINX image, if you’re using a custom tag, add TAG=your-tag to the end of the command. Replace <my-docker-registry> with your private registry’s path.

    make push PREFIX=<my-docker-registry>/nginx-plus-ingress
    

Makefile details

This section provides comprehensive information on the targets and variables available in the Makefile. These targets and variables allow you to customize how you build, tag, and push your NGINX or NGINX Plus images.

Key Makefile targets

Tip:
To view available Makefile targets, run make with no target or type make help.

Key targets include:

Target
Description
build Creates the NGINX Ingress Controller binary with your local Go environment.
alpine-image Builds an Alpine-based image with NGINX.
alpine-image-plus Builds an Alpine-based image with NGINX Plus.
alpine-image-plus-fips Builds an Alpine-based image with NGINX Plus and FIPS.
debian-image Builds a Debian-based image with NGINX.
debian-image-plus Builds a Debian-based image with NGINX Plus.
debian-image-nap-plus Builds a Debian-based image with NGINX Plus and the NGINX App Protect WAF module.
debian-image-dos-plus Builds a Debian-based image with NGINX Plus and the NGINX App Protect DoS module.
debian-image-nap-dos-plus Builds a Debian-based image with NGINX Plus, NGINX App Protect WAF and NGINX App Protect DoS modules.
ubi-image Builds a UBI-based image with NGINX for OpenShift clusters.
ubi-image-plus Builds a UBI-based image with NGINX Plus for OpenShift clusters.
ubi-image-nap-plus Builds a UBI-based image with NGINX Plus and the NGINX App Protect WAF module for OpenShift clusters.
ubi-image-dos-plus Builds a UBI-based image with NGINX Plus and the NGINX App Protect DoS module for OpenShift clusters.
ubi-image-nap-dos-plus

Builds a UBI-based image with NGINX Plus, NGINX App Protect WAF and the NGINX App Protect DoS module for OpenShift clusters.

Important: Save your RHEL organization and activation keys in a file named rhel_license at the project root.

For instance:

RHEL_ORGANIZATION=1111111
RHEL_ACTIVATION_KEY=your-key

Additional useful targets

A few other useful targets:

Target
Description
push Pushes the built image to the Docker registry. Configures with PREFIX and TAG.
all Runs test, lint, verify-codegen, update-crds, and debian-image. Stops and reports an error if any of these targets fail.
test Runs unit tests.
certificate-and-key NGINX Ingress Controller requires a certificate and key for the default HTTP/HTTPS server. You have several options:
  • Reference them in a TLS Secret in a command-line argument to NGINX Ingress Controller.
  • Add them to the image in in a file in PEM format as /etc/nginx/secrets/default.
  • Generate a self-signed certificate and key with this target.
Note, you must include the ADD instruction in your Dockerfile to copy the cert and key to the image.

Makefile variables you can customize

The Makefile includes several key variables. You have the option to either modify these variables directly in the Makefile or override them when you run the make command.

Variable
Description
ARCH Defines the architecture for the image and binary. The default is amd64, but you can also choose from arm64, arm, ppc64le, and s390x.
PREFIX Gives the image its name. The default is nginx/nginx-ingress.
TAG Adds a tag to the image. This is often the version of the NGINX Ingress Controller.
DOCKER_BUILD_OPTIONS Allows for additional options during the docker build process, like --pull.
TARGET

Determines the build environment. NGINX Ingress Controller compiles locally in a Golang environment by default. Ensure the NGINX Ingress Controller repo resides in your $GOPATH if you select this option.

Alternatively, you can set TARGET=container to build using a Docker Golang container. To skip compiling the binary if you’re on a specific tag or the latest main branch commit, set TARGET=download.


Alternatives to building your own image

If you prefer not to build your own NGINX Ingress Controller image, you can use pre-built images. Here are your options:

NGINX Ingress Controller: Download the image nginx/nginx-ingress from DockerHub or GitHub.

NGINX Plus Ingress Controller: You have two options for this, both requiring an NGINX Ingress Controller subscription.