CtrlK
BlogDocsLog inGet started
Tessl Logo

nic-docker-images

Docker image build system, Dockerfile structure, image variants, build scripts, and Makefile targets for NIC. Use when building container images, modifying the Dockerfile, adding new image variants, debugging image builds, or working with build scripts.

64

Quality

76%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Medium

Suggest reviewing before use

Fix and improve this skill with Tessl

tessl review fix ./.github/skills/nic-docker-images/SKILL.md
SKILL.md
Quality
Evals
Security

NIC Docker Image Build System

Dockerfile Architecture

Single build/Dockerfile (~850 lines), heavily multi-stage. The BUILD_OS arg selects which base image stage is used.

nginx-files (scratch)           <- Collects repo files, signing keys, scripts
  |
OS-specific base stages         <- One per variant (debian, alpine, ubi, *-plus, *-nap)
  |
FROM ${BUILD_OS} AS common      <- Runs common.sh + patch-os.sh, sets permissions
  |
TARGET stages (final image)     <- local, container, goreleaser, debug, download, aws, patched

Image Variants

3 OS families x 2 NGINX editions x optional NAP = ~20 variants.

OSOSSPlusPlus+WAFPlus+WAFv5Plus+DoSPlus+WAF+DoSPlus+FIPSPlus+WAF+FIPSPlus+WAFv5+FIPS
Debianyesyesyesyesyesyes---
Alpineyesyes----yesyesyes
UBI 10yesyesyesyesyesyes---

Architecture: amd64 + arm64 for OSS and Plus. NAP variants are amd64 only.


Makefile Image Targets

All targets call docker build --platform linux/$(ARCH) --target $(TARGET) -f build/Dockerfile.

TargetBUILD_OSNAP_MODULES
debian-imagedebian-
alpine-imagealpine-
ubi-imageubi-
debian-image-plusdebian-plus-
alpine-image-plusalpine-plus-
alpine-image-plus-fipsalpine-plus-fips-
alpine-image-nap-plus-fipsalpine-plus-nap-fipswaf
alpine-image-nap-v5-plus-fipsalpine-plus-nap-v5-fipswaf
ubi-image-plusubi-10-plus-
debian-image-nap-plusdebian-plus-napwaf
debian-image-nap-v5-plusdebian-plus-nap-v5waf
debian-image-dos-plusdebian-plus-napdos
debian-image-nap-dos-plusdebian-plus-napwaf,dos
ubi-image-nap-plusubi-10-plus-napwaf
ubi-image-nap-v5-plusubi-10-plus-nap-v5waf
ubi-image-dos-plusubi-10-plus-napdos
ubi-image-nap-dos-plusubi-10-plus-napwaf,dos
all-imagesBuilds 18 variants-
pushdocker push to PREFIX:TAG-
patch-osOS patches existing image-

Plus images receive $(PLUS_ARGS): --secret id=nginx-repo.crt --secret id=nginx-repo.key.

TARGET Variable

TargetUse Case
localDefault -- binary pre-built on host, copied in
containerBinary built inside Docker (multi-arch capable)
goreleaserBinary from GoReleaser dist/ (CI builds)
debugIncludes delve debugger
downloadExtracts binary from published Docker Hub image
awsAWS marketplace variant
patchedOS patches an existing image

Key Build Args

ArgPurposeSource of truth
BUILD_OSBase image stageMakefile targets + Dockerfile stages
IC_VERSIONIngress controller version.github/data/version.txt
NGINX_PLUS_VERSIONNGINX Plus versionbuild/Dockerfile
NGINX_OSS_VERSIONNGINX OSS versionbuild/Dockerfile
NAP_MODULESApp Protect modulesAny of waf, dos, or waf,dos
PREBUILT_BASE_IMGBase for prebuilt targetsGCR image ref (set by CI)

Do not hard-code IC_VERSION or NGINX_VERSION values in this file or in other docs as they change every release. Always reference .github/data/version.txt or the Renovate-managed Dockerfile pin.


Build Scripts (build/scripts/)

ScriptPurpose
common.shSets up directories, copies NGINX templates (v1/v2), sets file permissions (101:0), runs setcap on nginx binaries
agent.shConfigures nginx-agent ownership; creates NMS compiler symlinks for NAP v4
nap-waf.shCreates WAF directories (/etc/nginx/waf/nac-policies, /opt/app_protect/)
nap-dos.shCreates DoS directories (/root/app_protect_dos, /shared/cores)
ubi-setup.shUBI-specific: installs shadow-utils, creates nginx user/group (101:0)
ubi-clean.shUBI-specific: removes build-time packages, cleans dnf cache

Key Conventions

  • All images run as UID 101 (nginx user), with setcap cap_net_bind_service for ports 80/443
  • Docker BuildKit always enabled: uses --mount=type=bind, --mount=type=secret, --mount=type=cache
  • Plus credentials use --secret mounts, never COPY into layers
  • Fixed upstream base images use pinned @sha256: digests for reproducibility; some stages intentionally use build-arg/tag-selected bases (for example BUILD_OS or download/prebuilt images)
  • All images include nginx-module-otel (OpenTelemetry) and nginx-agent (usage reporting)
  • Plus images add njs and fips-check modules
  • Renovate manages base image digests and tool versions via # renovate: comments

Gotchas

  • Never store Plus credentials in image layers -- always use --secret mounts
  • Never add arm64 to NAP image matrices -- NAP is amd64 only
  • Always use BUILD_OS to select variants, not separate Dockerfiles
  • The common stage unifies all variants -- changes there affect every image
  • common.sh detects Plus via BUILD_OS containing "plus" and creates OIDC directories
  • patch-os.sh handles OS-level security updates at build time
  • When adding new image dependencies, update the relevant OS-specific stage AND the common stage if needed
Repository
nginx/kubernetes-ingress
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.