Building NICo Containers

View as Markdown

This section provides instructions for building the containers for NVIDIA Infra Controller (NICo).

Installing Prerequisite Software

An Ubuntu 24.04 host or VM with at least 150GB of free disk space is required, and git and make must also be installed (macOS is not supported).

Clone the repo and run the build-host bootstrap. It installs everything needed to build the containers and boot artifacts — system packages, rustup, the mkosi/ipxe git submodules, Docker, and the cargo build tooling — in one idempotent step:

1git clone git@github.com:NVIDIA/infra-controller.git
2cd infra-controller
3make bootstrap # or: ./scripts/setup-build-host.sh

Reboot (or log out and back in) afterwards so the docker group membership and the userns sysctl change take effect.

Manual setup (what make bootstrap does)

make bootstrap runs scripts/setup-build-host.sh, which is equivalent to the following steps on an apt-based distribution such as Ubuntu 24.04:

  1. apt-get install build-essential cpio direnv mkosi uidmap curl file fakeroot git docker.io docker-buildx sccache protobuf-compiler libopenipmi-dev libudev-dev libboost-dev libgrpc-dev libprotobuf-dev libssl-dev libtss2-dev kea-dev systemd-boot systemd-ukify jq zip
  2. Add the correct hook for your shell
  3. Install rustup: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh (select Option 1)
  4. Start a new shell to pick up changes made from direnv and rustup.
  5. Clone NICo - git clone git@github.com:NVIDIA/infra-controller.git infra-controller
  6. cd infra-controller
  7. direnv allow
  8. git submodule update --init --recursive
  9. sudo systemctl enable docker.socket
  10. cargo install cargo-make cargo-cache
  11. echo "kernel.apparmor_restrict_unprivileged_userns=0" | sudo tee /etc/sysctl.d/99-userns.conf
  12. sudo usermod -aG docker $(id -un)
  13. reboot

Build all images with one command

Once the prerequisites above are installed, build the NICo container images from the top of the repo with a single make command:

1make images # deployable stack: NICo Core (nico) + the REST service images
2make images-all # the above plus the machine-validation and x86 boot-artifact images

Images are tagged localhost:5000/<name>:latest by default. Override the registry and tag to build under your own registry:

1make images IMAGE_REGISTRY=my-registry.example.com/nico IMAGE_TAG=v1.0.0

The deployable images are built for linux/amd64 (the NICo Dockerfiles are x86_64). On an arm64 host such as Apple Silicon they build under emulation, which is slow — a native linux/amd64 build host is recommended. Pass PLATFORM=linux/arm64 to build native arm64 images instead.

Run make help from the repo root to list the individual image targets (images-core, images-rest, images-machine-validation, images-boot-artifacts, images-bfb). The sections below document the per-image build commands that these targets wrap, for when you need to build or debug a single image.

Verifying the build

After make images-all completes, verify that all 14 deployable images were produced:

1docker images --filter "reference=${IMAGE_REGISTRY}/*:${IMAGE_TAG}" \
2 --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"

The count should be exactly 14:

ImageTarget
nicoimages-core
nico-rest-apiimages-rest
nico-rest-workflowimages-rest
nico-rest-site-managerimages-rest
nico-rest-site-agentimages-rest
nico-rest-dbimages-rest
nico-rest-cert-managerimages-rest
nico-flowimages-rest
nico-psmimages-rest
nico-nsmimages-rest
nico-mcpimages-rest
machine-validationimages-machine-validation
boot-artifacts-x86_64images-boot-artifacts
boot-artifacts-aarch64images-bfb
1# Quick count — should print 14
2docker images --filter "reference=${IMAGE_REGISTRY}/*:${IMAGE_TAG}" \
3 --format "{{.Repository}}" | wc -l

If the count is less than 14, the missing images indicate which sub-target failed. The three boot/validation images (machine-validation, boot-artifacts-x86_64, boot-artifacts-aarch64) require the full mkosi + Rust toolchain — if only 11 images appear, use make images instead of make images-all to build the deployable stack without them.

Three intermediate images are also created locally but are not tagged under IMAGE_REGISTRY: nico-buildcontainer-x86_64, nico-runtime-container-x86_64, and machine-validation-runner. These are build-time dependencies only and do not need to be pushed.

Building X86_64 Containers

NOTE: Execute these tasks in order. All commands are run from the top of the infra-controller directory.

Building the X86 build container

1docker build --file dev/docker/Dockerfile.build-container-x86_64 -t nico-buildcontainer-x86_64 .

Building the X86 runtime container

1docker build --file dev/docker/Dockerfile.runtime-container-x86_64 -t nico-runtime-container-x86_64 .

Building the boot artifact containers

1cargo make --cwd pxe --env SA_ENABLEMENT=1 build-boot-artifacts-x86-host-sa
2docker build --build-arg "CONTAINER_RUNTIME_X86_64=alpine:latest" -t boot-artifacts-x86_64 -f dev/docker/Dockerfile.release-artifacts-x86_64 .

Building the Machine Validation images

1docker build --build-arg CONTAINER_RUNTIME_X86_64=nico-runtime-container-x86_64 -t machine-validation-runner -f dev/docker/Dockerfile.machine-validation-runner .
2
3docker save --output crates/machine-validation/images/machine-validation-runner.tar machine-validation-runner:latest
4
5// This copies `machine-validation-runner.tar` into the `/images` directory on the `machine-validation-config` container. When using a kubernetes deployment model
6// this is the only `machine-validation` container you need to configure on the `nico-pxe` pod.
7
8docker build --build-arg CONTAINER_RUNTIME_X86_64=nico-runtime-container-x86_64 -t machine-validation-config -f dev/docker/Dockerfile.machine-validation-config .

Building nico-core container

1docker build --build-arg "CONTAINER_RUNTIME_X86_64=nico-runtime-container-x86_64" --build-arg "CONTAINER_BUILD_X86_64=nico-buildcontainer-x86_64" -f dev/docker/Dockerfile.release-container-sa-x86_64 -t nico .

Building the AARCH64 Containers and artifacts

Building the Cross-compile container

1docker build --file dev/docker/Dockerfile.build-artifacts-container-cross-aarch64 -t build-artifacts-container-cross-aarch64 .

Building the admin-cli

The admin-cli build does not produce a container. It produces a binary:

$REPO_ROOT/target/release/nico-admin-cli

BUILD_CONTAINER_X86_URL="nico-buildcontainer-x86_64" cargo make build-cli

Building the DPU BFB

1cargo make --cwd pxe --env SA_ENABLEMENT=1 build-boot-artifacts-bfb-sa
2
3docker build --build-arg "CONTAINER_RUNTIME_AARCH64=alpine:latest" -t boot-artifacts-aarch64 -f dev/docker/Dockerfile.release-artifacts-aarch64 .

NOTE: The CONTAINER_RUNTIME_AARCH64=alpine:latest build argument must be included. The aarch64 binaries are bundled into an x86 container.