Building NVIDIA Distroless Containers

NVIDIA Distroless images are minimal container images that contain only your application and its runtime dependencies — no package managers, shells, or other OS utilities. This results in a smaller attack surface and smaller image sizes.

All examples use multi-stage Docker builds: a full build environment compiles or prepares your application, then only the necessary artifacts are copied into the final distroless image.

Images are available at nvcr.io/nvidia/distroless/.


Python

Simple Script

A minimal Python application copied into the distroless Python image.

# hello.py
import sys
import os

for root, dirs, files in os.walk(sys.argv[1]):
    for f in files:
        print(os.path.join(root, f))
  
# Dockerfile
FROM python:3.14-slim AS build
COPY hello.py /app/hello.py

FROM nvcr.io/nvidia/distroless/python:3.14-v4.0.0
COPY --from=build /app /app
ENTRYPOINT ["python3", "/app/hello.py"]
  

With pip Dependencies

For packages that require compilation (e.g. psutil), use a multi-stage build with a virtualenv.

# requirements.txt
psutil==5.6.6
  
# Dockerfile
FROM debian:12-slim AS build
RUN apt-get update && \
    apt-get install --no-install-suggests --no-install-recommends -y \
    python3-venv gcc python3-dev libpython3-dev && \
    python3 -m venv /venv && \
    /venv/bin/pip install --upgrade pip setuptools wheel

FROM build AS build-venv
COPY requirements.txt /requirements.txt
RUN /venv/bin/pip install --disable-pip-version-check -r /requirements.txt

FROM gcr.io/distroless/python3-debian12
COPY --from=build-venv /venv /venv
COPY psutil_example.py /app/psutil_example.py
ENTRYPOINT ["/venv/bin/python3", "/app/psutil_example.py"]
  

Node.js

Simple App

// hello.js
console.log("Hello World");
  
# Dockerfile
FROM node:24 AS build
COPY . /app
WORKDIR /app

FROM nvcr.io/nvidia/distroless/node:24-v4.0.0
COPY --from=build /app /app
WORKDIR /app
CMD ["hello.js"]
  

Express.js App

// hello_express.js
const express = require("express");
const app = express();

app.get("/", (req, res) => {
  res.send("Hello World");
});

app.listen(3000, () => {
  console.log("Listening on port 3000");
});
  
# Dockerfile
FROM node:24 AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install --omit=dev
COPY . .

FROM gcr.io/distroless/nodejs22-debian12
COPY --from=build /app /app
WORKDIR /app
CMD ["hello_express.js"]
  

Java

// HelloJava.java
public class HelloJava {
    public static void main(String[] args) {
        System.out.println("Hello world");
    }
}
  
# Dockerfile
FROM eclipse-temurin:25-jdk AS build
COPY . /app
WORKDIR /app
RUN javac HelloJava.java && jar cfe app.jar HelloJava HelloJava.class

FROM nvcr.io/nvidia/distroless/java:25-v4.0.0
COPY --from=build /app/app.jar /app/app.jar
WORKDIR /app
CMD ["app.jar"]
  

Go

Go binaries compiled with CGO_ENABLED=0 are fully static and can use the smallest distroless base image.

// main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, world!")
}
  
# Dockerfile
FROM golang:1.22 AS build
WORKDIR /src
COPY go.mod ./
RUN go mod download
COPY . .
RUN go vet ./...
RUN go test ./...
RUN CGO_ENABLED=0 go build -o /app .

FROM nvcr.io/nvidia/distroless/go:4.0.0
COPY --from=build /app /app
ENTRYPOINT ["/app"]
  

C/C++

// hello_cc.cc
#include <iostream>

int main(int argc, char* argv[]) {
    std::cout << "Hello from distroless C++!" << std::endl;
    return 0;
}
  
# Dockerfile
FROM gcc:6 AS build
COPY . /app
WORKDIR /app
RUN g++ -o hello_cc hello_cc.cc

FROM nvcr.io/nvidia/distroless/cc:4.0.0
COPY --from=build /app/hello_cc /app/hello_cc
ENTRYPOINT ["/app/hello_cc"]
  

← Back to index