| Property | Value |
|---|---|
| Severity | Warning |
| Category | Best Practices |
| Default | Enabled |
| Auto-fix | Not available |
Description
Detects when the final stage of a Dockerfile usesnvidia/cuda:*devel* as its base image without
obvious compile-time needs such as nvcc, gcc, make, or cmake. The devel variant includes
the full CUDA compiler toolchain, development headers, and static libraries, which can add several
gigabytes to the final image.
Why this matters
- Image size —
develimages are typically 2—4 GB larger than the correspondingruntimevariant due tonvcc, development headers, and static libraries - Attack surface — shipping compiler toolchains and development headers in production images exposes unnecessary binaries that could be leveraged in a container escape or supply-chain attack
- Build cache efficiency — larger images take longer to pull, push, and layer-cache, slowing down CI/CD pipelines
- Best practice alignment — NVIDIA, Hugging Face, and major ML projects recommend using
develonly in builder stages and switching toruntimeorbasefor the shipped image
What is flagged
| Pattern | Flagged? |
|---|---|
Final stage FROM nvidia/cuda:12.x-devel-* with no compile signal | Yes |
Final stage FROM nvidia/cuda:12.x-cudnn-devel-* with no compile signal | Yes |
Final stage FROM nvidia/cuda:12.x-devel-* with nvcc, gcc, make, etc. | No — legitimate build stage |
Final stage FROM nvidia/cuda:12.x-devel-* with build-essential installed | No — build tools present |
Final stage FROM nvidia/cuda:12.x-runtime-* | No — already a runtime variant |
Final stage FROM nvidia/cuda:12.x-base-* | No — already a minimal variant |
Non-final stage using devel | No — builder stages legitimately need devel |
Examples
Violation
No violation
Detection details
The rule fires only when all of the following are true:- The final stage base image is
nvidia/cuda:*devel* - No compile signal is detected in the final stage
- Commands:
nvcc,gcc,g++,make,cmake,ninja - Packages:
build-essential,gcc,g++,make,cmake,ninja-build
COPY --from=... instruction is present in the final stage, the violation detail notes this
as additional evidence that the stage serves as a runtime image.