diff --git a/Makefile b/Makefile index 41ef919e4f..ffc8a38e8c 100644 --- a/Makefile +++ b/Makefile @@ -48,13 +48,23 @@ certificate-and-key: ## Create default cert and key ./build/generate_default_cert_and_key.sh .PHONY: build -build: ## Build Ingress Controller binary - @docker -v || (code=$$?; printf "\033[0;31mError\033[0m: there was a problem with Docker\n"; exit $$code) +build: download-binary-docker ## Build Ingress Controller binary ifeq (${TARGET},local) - @go version || (code=$$?; printf "\033[0;31mError\033[0m: unable to build locally, try using the parameter TARGET=container\n"; exit $$code) + @go version || (code=$$?; printf "\033[0;31mError\033[0m: unable to build locally, try using the parameter TARGET=container or TARGET=download\n"; exit $$code) CGO_ENABLED=0 GO111MODULE=on GOOS=linux go build -trimpath -ldflags "-s -w -X main.version=${VERSION} -X main.commit=${GIT_COMMIT} -X main.date=$(DATE)" -o nginx-ingress github.com/nginxinc/kubernetes-ingress/cmd/nginx-ingress endif +.PHONY: download-binary-docker +download-binary-docker: ## Download Docker image from which to extract Ingress Controller binary + @docker -v || (code=$$?; printf "\033[0;31mError\033[0m: there was a problem with Docker\n"; exit $$code) +ifeq (${TARGET},download) +DOWNLOAD_TAG := $(shell ./hack/docker.sh $(GIT_COMMIT) $(GIT_TAG)) +ifeq ($(DOWNLOAD_TAG),fail) +$(error unable to build with TARGET=download, this function is only available when building from a git tag or from the latest commit matching the edge image) +endif +override DOCKER_BUILD_OPTIONS += --build-arg DOWNLOAD_TAG=$(DOWNLOAD_TAG) +endif + .PHONY: build-goreleaser build-goreleaser: ## Build Ingress Controller binary using GoReleaser @goreleaser -v || (code=$$?; printf "\033[0;31mError\033[0m: there was a problem with GoReleaser. Follow the docs to install it https://goreleaser.com/install\n"; exit $$code) diff --git a/build/Dockerfile b/build/Dockerfile index 0366bd7c6a..419b136c2d 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -2,6 +2,7 @@ ARG BUILD_OS=debian ARG NGINX_PLUS_VERSION=r25 ARG UBI_VERSION=8 +ARG DOWNLOAD_TAG=edge ############################################# Base image for Debian ############################################# FROM nginx:1.21.3 AS debian @@ -281,3 +282,13 @@ ARG TARGETARCH LABEL org.nginx.kic.image.build.version="aws" COPY --chown=nginx:0 ./dist/aws_linux_$TARGETARCH/nginx-ingress / + + +############################################# Create image with nginx-ingress extracted from image on Docker Hub ############################################# +FROM nginx/nginx-ingress:${DOWNLOAD_TAG} as kic + +FROM common as download + +LABEL org.nginx.kic.image.build.version="binaries" + +COPY --from=kic /nginx-ingress / diff --git a/docs/content/installation/building-ingress-controller-image.md b/docs/content/installation/building-ingress-controller-image.md index 3c0ae52cf4..0625b0577e 100644 --- a/docs/content/installation/building-ingress-controller-image.md +++ b/docs/content/installation/building-ingress-controller-image.md @@ -1,12 +1,12 @@ --- title: Building the Ingress Controller Image -description: +description: weight: 2200 doctypes: [""] toc: true --- -This document explains how to build an Ingress Controller image using the source code. You can also use pre-built images: please see [here](/nginx-ingress-controller/installation/using-the-jwt-token-docker-secret) and [here](/nginx-ingress-controller/installation/pulling-ingress-controller-image) for details on how to pull the NGINX Ingress Controller based on NGINX Plus from the F5 Docker registry; for NGINX Ingress Controller based on NGINX OSS, we provide the images through [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/). +This document explains how to build an Ingress Controller image using the source code. You can also use pre-built images: please see [here](/nginx-ingress-controller/installation/using-the-jwt-token-docker-secret) and [here](/nginx-ingress-controller/installation/pulling-ingress-controller-image) for details on how to pull the NGINX Ingress Controller based on NGINX Plus from the F5 Docker registry; for NGINX Ingress Controller based on NGINX OSS, we provide the images through [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/) and [GitHub Container](https://github.com/nginxinc/kubernetes-ingress/pkgs/container/kubernetes-ingress). ## Prerequisites @@ -17,13 +17,13 @@ Before you can build the image, make sure that the following software is install * [OpenSSL](https://www.openssl.org/), optionally, if you would like to generate a self-signed certificate and a key for the default server. * For NGINX Plus, you must have the NGINX Plus license -- the certificate (`nginx-repo.crt`) and the key (`nginx-repo.key`). -Although the Ingress Controller is written in golang, golang is not required, you have the option to build the Ingress Controller in a Docker container. +Although the Ingress Controller is written in golang, golang is not required, you have the option to download the binary or to build the Ingress Controller in a Docker container. ## Building the Image and Pushing It to the Private Registry We build the image using the make utility and the provided `Makefile`. Let’s create the Ingress Controller binary, build an image and push the image to the private registry. -**Note**: If you have a local golang environment, you can remove `TARGET=container` from the `make` commands to speed up the build. +**Note**: If you have a local golang environment and you want to build the binary, you can remove `TARGET=download` from the `make` commands. If you want to build the binary, but you don't have a local golang environment you can use `TARGET=container`. 1. Make sure to run the `docker login` command first to log in to the registry. @@ -39,11 +39,11 @@ We build the image using the make utility and the provided `Makefile`. Let’s c 1. Build the image: * For **NGINX**: ``` - $ make debian-image PREFIX=myregistry.example.com/nginx-ingress TARGET=container + $ make debian-image PREFIX=myregistry.example.com/nginx-ingress TARGET=download ``` or if you wish to use alpine ``` - $ make alpine-image PREFIX=myregistry.example.com/nginx-ingress TARGET=container + $ make alpine-image PREFIX=myregistry.example.com/nginx-ingress TARGET=download ``` `myregistry.example.com/nginx-ingress` defines the repo in your private registry where the image will be pushed. Substitute that value with the repo in your private registry. @@ -56,13 +56,13 @@ We build the image using the make utility and the provided `Makefile`. Let’s c ``` Then run: ``` - $ make debian-image-plus PREFIX=myregistry.example.com/nginx-plus-ingress TARGET=container + $ make debian-image-plus PREFIX=myregistry.example.com/nginx-plus-ingress TARGET=download ``` `myregistry.example.com/nginx-plus-ingress` defines the repo in your private registry where the image will be pushed. Substitute that value with the repo in your private registry. As a result, the image **myregistry.example.com/nginx-plus-ingress:2.0.2** is built. Note that the tag `2.0.2` comes from the `VERSION` variable, defined in the Makefile. - **Note**: In the event of a patch version of [NGINX Plus being released](/nginx/releases/), 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="--no-cache"` to the `make` command. + **Note**: In the event of a patch version of [NGINX Plus being released](/nginx/releases/), 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. 1. Push the image: ``` @@ -107,4 +107,4 @@ The **Makefile** contains the following main variables for you to customize (eit * **VERSION** -- the current version of the Ingress Controller. * **TAG** -- the tag added to the image. It's set to the value of the `VERSION` variable by default. * **DOCKER_BUILD_OPTIONS** -- the [options](https://docs.docker.com/engine/reference/commandline/build/#options) for the `docker build` command. For example, `--pull`. -* **TARGET** -- By default, the Ingress Controller is compiled locally using a `local` golang environment. If you want to compile the Ingress Controller using your local golang environment, make sure that the Ingress Controller repo is in your `$GOPATH`. To compile the Ingress Controller using the Docker [golang](https://hub.docker.com/_/golang/) container, specify `TARGET=container`. +* **TARGET** -- By default, the Ingress Controller is compiled locally using a `local` golang environment. If you want to compile the Ingress Controller using your local golang environment, make sure that the Ingress Controller repo is in your `$GOPATH`. To compile the Ingress Controller using the Docker [golang](https://hub.docker.com/_/golang/) container, specify `TARGET=container`. If you checked out a tag or are on the latest commit on `master` you can specify `TARGET=download` to avoid compiling the binary. diff --git a/hack/docker.sh b/hack/docker.sh new file mode 100755 index 0000000000..bf221a7aad --- /dev/null +++ b/hack/docker.sh @@ -0,0 +1,26 @@ +#! /bin/bash + +git_commit=$1 +git_tag=$2 +docker_tag=edge + +commit_tag=$(git tag --contains ${git_commit}) + +if [[ ${commit_tag} == ${git_tag} ]]; then + # we're on the tag, use the docker image for the tag + docker_tag=${git_tag//v/} + echo ${docker_tag} + exit 0 + +else + # we're on master or a branch, try to download the latest edge and see if sha matches + docker pull nginx/nginx-ingress:${docker_tag} >/dev/null 2>&1 + DOCKER_SHA=$(docker inspect --format '{{ index .Config.Labels "org.opencontainers.image.revision" }}' nginx/nginx-ingress:${docker_tag}) + if [[ ${DOCKER_SHA} == ${git_commit} ]]; then + # we're on the same commit as the latest edge + echo ${docker_tag} + exit 0 + fi +fi + +echo "fail"