# Build NGINX Ingress Controller with F5 DoS for NGINX




This document explains how to build an image for F5 NGINX Ingress Controller with F5 DoS for NGINX from source code.

**Note:** If you'd rather not build your own NGINX Ingress Controller image, see the [pre-built image options](#pre-built-images) at the end of this guide.

## Before you start

- To use F5 DoS for NGINX with NGINX Ingress Controller, you must have NGINX Plus.

## Prepare the environment {#prepare-environment}

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

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

    ```shell
    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.

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

    For instance if you want to clone version v, the commands to run would be:

    ```shell
    git clone https://github.com/nginx/kubernetes-ingress.git --branch v
    cd kubernetes-ingress/deployments
    ```

## Build the image {#build-docker-image}

Follow these steps to build the NGINX Controller Image with F5 DoS for NGINX.

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:

    ```shell
    ls nginx-repo.*
    ```

    You should see:

    ```shell
    nginx-repo.crt  nginx-repo.key
    ```

2. Build the image. Replace `<makefile target>` with your chosen build option and `<my-docker-registry>` with your private registry's path. Refer to the [Makefile targets](#makefile-targets) table below for the list of build options.

    ```shell
    make <makefile target> PREFIX=<my-docker-registry>/nginx-plus-ingress TARGET=download
    ```

    For example, to build a Debian-based image with NGINX Plus and F5 DoS for NGINX, run:

    ```shell
    make debian-image-dos-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_](/nic/install/build.md#makefile-details). 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.

### Makefile targets

| Makefile Target           | Description                                                       | Compatible Systems  |
|---------------------------|-------------------------------------------------------------------|---------------------|
| **debian-image-dos-plus** | Builds a Debian-based image with NGINX Plus and the [F5 DoS for NGINX](/nginx-app-protect-dos/) module. | Debian  |
| **debian-image-nap-dos-plus** | Builds a Debian-based image with NGINX Plus, [F5 DoS for NGINX](/nginx-app-protect-dos/), and [F5 WAF for NGINX](/nginx-app-protect/). | Debian  |
| **ubi-image-dos-plus**    | Builds a UBI-based image with NGINX Plus and the [F5 DoS for NGINX](/nginx-app-protect-dos/) module. | OpenShift |
| **ubi-image-nap-dos-plus** | Builds a UBI-based image with NGINX Plus, [F5 DoS for NGINX](/nginx-app-protect-dos/), and [F5 WAF for NGINX](/nginx-app-protect/). | OpenShift |

**Note:**  For the complete list of _Makefile_ targets and customizable variables, see the [Build NGINX Ingress Controller](/nic/install/build.md#makefile-details) topic. 

## Push the image to your private registry

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

To upload the image, run the following command. 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.

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

## Set up role-based access control (RBAC) {#set-up-rbac}

**Note:** To complete these steps you need admin access to your cluster. Refer to to your Kubernetes platform's documentation to set up admin access. For Google Kubernetes Engine (GKE), you can refer to their [Role-Based Access Control guide](https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control).

1. Create a namespace and a service account:

    ```shell
    kubectl apply -f deployments/common/ns-and-sa.yaml
    ```

2. Create a cluster role and binding for the service account:

    ```shell
    kubectl apply -f deployments/rbac/rbac.yaml
    ```

<br>

If you're planning to use F5 WAF for NGINX or F5 DoS for NGINX, additional roles and bindings are needed.

1. (F5 WAF for NGINX only) Create the *App Protect* role and binding:

    ```shell
    kubectl apply -f deployments/rbac/ap-rbac.yaml
    ```

2. (F5 DoS for NGINX only) Create the *App Protect DoS* role and binding:

    ```shell
    kubectl apply -f deployments/rbac/apdos-rbac.yaml
    ```

## Create common resources {#create-common-resources}

In this section, you'll create resources that most NGINX Ingress Controller installations require:

1. (Optional) Create a secret for the default NGINX server's TLS certificate and key. Complete this step only if you're using the [default server TLS secret](/nic/configuration/global-configuration/command-line-arguments#cmdoption-default-server-tls-secret.md) command-line argument. If you're not, feel free to skip this step.

    By default, the server returns a _404 Not Found_ page for all requests when no ingress rules are set up. Although we provide a self-signed certificate and key for testing purposes, we recommend using your own certificate.

    ```shell
    make secrets
    kubectl apply -f examples/shared-examples/default-server-secret/default-server-secret.yaml
    ```

2. Create a ConfigMap to customize your NGINX settings:

    ```shell
    kubectl apply -f deployments/common/nginx-config.yaml
    ```

3. Create an `IngressClass` resource. NGINX Ingress Controller won't start without an `IngressClass` resource.

    ```shell
    kubectl apply -f deployments/common/ingress-class.yaml
    ```

    If you want to make this NGINX Ingress Controller instance your cluster's default, uncomment the `ingressclass.kubernetes.io/is-default-class` annotation. This action will auto-assign `IngressClass` to new ingresses that don't specify an `ingressClassName`.

## Create custom resources {#create-custom-resources}

To make sure your NGINX Ingress Controller pods reach the `Ready` state, you'll need to create custom resource definitions (CRDs) for various components.

Alternatively, you can disable this requirement by setting the `-enable-custom-resources` command-line argument to `false`.

There are two ways you can install the custom resource definitions:

1. Using a URL to apply a single CRD yaml file, which we recommend.
1. Applying your local copy of the CRD yaml files, which requires you to clone the repository.

The core custom CRDs are the following:

- [VirtualServer and VirtualServerRoute](/nic/configuration/virtualserver-and-virtualserverroute-resources.md)
- [TransportServer](/nic/configuration/transportserver-resource.md)
- [Policy](/nic/configuration/policy-resource.md)
- [GlobalConfiguration](/nic/configuration/global-configuration/globalconfiguration-resource.md)

#### Install CRDs from single YAML

```shell
kubectl apply -f https://raw.githubusercontent.com/nginx/kubernetes-ingress/v/deploy/crds.yaml
```

#### Install CRDs after cloning the repo

**Note:**  

Read the steps outlined in [Upgrade from 3.x to 4.x](/nic/install/upgrade.md#upgrade-from-3x-to-4x) before running the CRD upgrade and perform the steps if applicable.

```shell
kubectl apply -f config/crd/bases/k8s.nginx.org_virtualservers.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_virtualserverroutes.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_transportservers.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_policies.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_globalconfigurations.yaml
```

## Create App Protect DoS custom resources

#### Install CRDs from single YAML

This single YAML file creates CRDs for the following resources:

- `APDosPolicy`
- `APDosLogConf`
- `DosProtectedResource`

```shell
kubectl apply -f https://raw.githubusercontent.com/nginx/kubernetes-ingress/v/deploy/crds-nap-dos.yaml
```

#### Install CRDs after cloning the repo

These YAML files create CRDs for the following resources:

- `APDosPolicy`
- `APDosLogConf`
- `DosProtectedResource`

```shell
kubectl apply -f config/crd/bases/appprotectdos.f5.com_apdoslogconfs.yaml
kubectl apply -f config/crd/bases/appprotectdos.f5.com_apdospolicy.yaml
kubectl apply -f config/crd/bases/appprotectdos.f5.com_dosprotectedresources.yaml
```

## Deploy NGINX Ingress Controller {#deploy-ingress-controller}

You have two options for deploying NGINX Ingress Controller:

- **Deployment**. Choose this method for the flexibility to dynamically change the number of NGINX Ingress Controller replicas.
- **DaemonSet**. Choose this method if you want NGINX Ingress Controller to run on all nodes or a subset of nodes.
- **StatefulSet**. Choose this method when you need stable, persistent storage and ordered deployment/scaling for your NGINX Ingress Controller pods.

Before you start, update the [command-line arguments](/nic/configuration/global-configuration/command-line-arguments.md) for the NGINX Ingress Controller container in the relevant manifest file to meet your specific requirements.

### Using a Deployment

For additional context on managing containers using Kubernetes Deployments, refer to the official Kubernetes [Deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) documentation.

When you deploy NGINX Ingress Controller as a Deployment, Kubernetes automatically sets up a single NGINX Ingress Controller pod.

- For NGINX, run:

    ```shell
    kubectl apply -f deployments/deployment/nginx-ingress.yaml
    ```

- For NGINX Plus, run:

    ```shell
    kubectl apply -f deployments/deployment/nginx-plus-ingress.yaml
    ```

    Update the `nginx-plus-ingress.yaml` file to include your chosen image from the F5 Container registry or your custom container image.

### Using a DaemonSet

For additional context on managing containers using Kubernetes DaemonSets, refer to the official Kubernetes [DaemonSets](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) documentation.

When you deploy NGINX Ingress Controller as a DaemonSet, Kubernetes creates an Ingress Controller pod on every node in the cluster.

- For NGINX, run:

    ```shell
    kubectl apply -f deployments/daemon-set/nginx-ingress.yaml
    ```

- For NGINX Plus, run:

    ```shell
    kubectl apply -f deployments/daemon-set/nginx-plus-ingress.yaml
    ```

    Update the `nginx-plus-ingress.yaml` file to include your chosen image from the F5 Container registry or your custom container image.

### Using a StatefulSet

For additional context on managing containers using Kubernetes StatefulSets, refer to the official Kubernetes [StatefulSets](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) documentation.

When you deploy NGINX Ingress Controller as a StatefulSet, Kubernetes creates pods with stable network identities and persistent storage.

- For NGINX, run:

    ```shell
    kubectl apply -f deployments/stateful-set/nginx-ingress.yaml
    ```

- For NGINX Plus, run:

    ```shell
    kubectl apply -f deployments/stateful-set/nginx-plus-ingress.yaml
    ```

    Update the `nginx-plus-ingress.yaml` file to include your chosen image from the F5 Container registry or your custom container image.

**Note:** 
StatefulSets include persistent volume claims for nginx cache storage via `volumeClaimTemplates`. You may need to configure a StorageClass in your cluster or modify the volumeClaimTemplates section in the manifest to match your storage requirements. Other volumes (like those needed for App Protect modules) are configured in the regular `volumes` section, not in volumeClaimTemplates.

## Install the App Protect DoS Arbitrator

**Note:**  If you install multiple NGINX Ingress Controllers in the same namespace, they will need to share the same Arbitrator because there can only be one Arbitrator in a single namespace. 

### Helm Chart

The App Protect DoS Arbitrator can be installed using the [F5 DoS for NGINX Helm Chart](https://github.com/nginxinc/nap-dos-arbitrator-helm-chart).
If you have the NGINX Helm Repository already added, you can install the App Protect DoS Arbitrator by running the following command:

```shell
helm install my-release-dos nginx-stable/nginx-appprotect-dos-arbitrator
```

### YAML Manifests

Alternatively, you can install the App Protect DoS Arbitrator using the YAML manifests provided in the NGINX Ingress Controller repo.

1. Create the namespace and service account:

    ```shell
      kubectl apply -f common/ns-and-sa.yaml
    ```

2. Deploy the F5 WAF for NGINX Arbitrator as a Deployment and service:

    ```shell
    kubectl apply -f deployment/appprotect-dos-arb.yaml
    kubectl apply -f service/appprotect-dos-arb-svc.yaml
    ```

## Enable F5 DoS for NGINX module

To enable the F5 DoS for NGINX Module:

- Add the `enable-app-protect-dos` [command-line argument](/nic/configuration/global-configuration/command-line-arguments.md#cmdoption-enable-app-protect-dos) to your Deployment, DaemonSet, or StatefulSet file.

## Confirm NGINX Ingress Controller is running

To confirm the NGINX Ingress Controller pods are operational, run:

```shell
kubectl get pods --namespace=nginx-ingress
```

For more information, see the [Configuration guide](/nic/integrations/app-protect-dos/configuration.md),the [NGINX Ingress Controller with App Protect DoS example for VirtualServer](https://github.com/nginx/kubernetes-ingress/tree/v/examples/custom-resources/app-protect-dos) and the [NGINX Ingress Controller with App Protect DoS example for Ingress](https://github.com/nginx/kubernetes-ingress/tree/v/examples/ingress-resources/app-protect-dos).

## Alternatives to building your own image {#pre-built-images}

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

- Download the image using your NGINX Ingress Controller subscription certificate and key. View the [Download NGINX Ingress Controller from the F5 Registry](/nic/install/images/registry-download.md) topic.
  - The [Add an NGINX Ingress Controller image to your cluster](/nic/install/images/add-image-to-cluster.md) topic describes how to use your subscription JWT token to get the image.

