Nic Docker Images
DevOps & Securitynic-docker-imagesNic Docker Images is an Agent Skill for devops & security published in the nginx/kubernetes-ingress repository on GitHub: a SKILL.md instruction file an AI agent can load to do this task.
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.
How to use this skill
Bring this guide into your coding agent with a prompt tailored to the tool you use.
- Open your project in Codex.
- Copy and paste the prompt below.
- Review files and risks before approving any action.
Inspect the Agent Skill at https://github.com/nginx/kubernetes-ingress/blob/HEAD/.github/skills/nic-docker-images/SKILL.md and all supporting files. Report provenance, permissions, scripts, dependencies, and security risks. Propose an exact installation into .agents/skills/nic-docker-images, but wait for my approval before writing files or running scripts.
Copying this prompt does not install or run the skill. Review third-party files before use.
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.
| OS | OSS | Plus | Plus+WAF | Plus+WAFv5 | Plus+DoS | Plus+WAF+DoS | Plus+FIPS | Plus+WAF+FIPS | Plus+WAFv5+FIPS |
|---|---|---|---|---|---|---|---|---|---|
| Debian | yes | yes | yes | yes | yes | yes | - | - | - |
| Alpine | yes | yes | - | - | - | - | yes | yes | yes |
| UBI 10 | yes | yes | yes | yes | yes | yes | - | - | - |
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.
| Target | BUILD_OS | NAP_MODULES |
|---|---|---|
debian-image | debian | - |
alpine-image | alpine | - |
ubi-image | ubi | - |
debian-image-plus | debian-plus | - |
alpine-image-plus | alpine-plus | - |
alpine-image-plus-fips | alpine-plus-fips | - |
alpine-image-nap-plus-fips | alpine-plus-nap-fips | waf |
alpine-image-nap-v5-plus-fips | alpine-plus-nap-v5-fips | waf |
ubi-image-plus | ubi-10-plus | - |
debian-image-nap-plus | debian-plus-nap | waf |
debian-image-nap-v5-plus | debian-plus-nap-v5 | waf |
debian-image-dos-plus | debian-plus-nap | dos |
debian-image-nap-dos-plus | debian-plus-nap | waf,dos |
ubi-image-nap-plus | ubi-10-plus-nap | waf |
ubi-image-nap-v5-plus | ubi-10-plus-nap-v5 | waf |
ubi-image-dos-plus | ubi-10-plus-nap | dos |
ubi-image-nap-dos-plus | ubi-10-plus-nap | waf,dos |
all-images | Builds 18 variants | - |
push | docker push to PREFIX:TAG | - |
patch-os | OS patches existing image | - |
Plus images receive $(PLUS_ARGS): --secret id=nginx-repo.crt --secret id=nginx-repo.key.
TARGET Variable
| Target | Use Case |
|---|---|
local | Default -- binary pre-built on host, copied in |
container | Binary built inside Docker (multi-arch capable) |
goreleaser | Binary from GoReleaser dist/ (CI builds) |
debug | Includes delve debugger |
download | Extracts binary from published Docker Hub image |
aws | AWS marketplace variant |
patched | OS patches an existing image |
Key Build Args
| Arg | Purpose | Source of truth |
|---|---|---|
BUILD_OS | Base image stage | Makefile targets + Dockerfile stages |
IC_VERSION | Ingress controller version | .github/data/version.txt |
NGINX_PLUS_VERSION | NGINX Plus version | build/Dockerfile |
NGINX_OSS_VERSION | NGINX OSS version | build/Dockerfile |
NAP_MODULES | App Protect modules | Any of waf, dos, or waf,dos |
PREBUILT_BASE_IMG | Base for prebuilt targets | GCR 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/)
| Script | Purpose |
|---|---|
common.sh | Sets up directories, copies NGINX templates (v1/v2), sets file permissions (101:0), runs setcap on nginx binaries |
agent.sh | Configures nginx-agent ownership; creates NMS compiler symlinks for NAP v4 |
nap-waf.sh | Creates WAF directories (/etc/nginx/waf/nac-policies, /opt/app_protect/) |
nap-dos.sh | Creates DoS directories (/root/app_protect_dos, /shared/cores) |
ubi-setup.sh | UBI-specific: installs shadow-utils, creates nginx user/group (101:0) |
ubi-clean.sh | UBI-specific: removes build-time packages, cleans dnf cache |
Key Conventions
- All images run as UID 101 (nginx user), with
setcap cap_net_bind_servicefor ports 80/443 - Docker BuildKit always enabled: uses
--mount=type=bind,--mount=type=secret,--mount=type=cache - Plus credentials use
--secretmounts, neverCOPYinto layers - Fixed upstream base images use pinned
@sha256:digests for reproducibility; some stages intentionally use build-arg/tag-selected bases (for exampleBUILD_OSor download/prebuilt images) - All images include
nginx-module-otel(OpenTelemetry) andnginx-agent(usage reporting) - Plus images add
njsandfips-checkmodules - Renovate manages base image digests and tool versions via
# renovate:comments
Gotchas
- Never store Plus credentials in image layers -- always use
--secretmounts - Never add
arm64to NAP image matrices -- NAP isamd64only - Always use
BUILD_OSto select variants, not separate Dockerfiles - The
commonstage unifies all variants -- changes there affect every image common.shdetects Plus viaBUILD_OScontaining "plus" and creates OIDC directoriespatch-os.shhandles OS-level security updates at build time- When adding new image dependencies, update the relevant OS-specific stage AND the common stage if needed