nix-oci
nix-oci is a flake-parts module designed to streamline the management of OCI (Open Container Initiative) repositories using the Nix package manager. By leveraging nix2container as its backend, nix-oci facilitates the declarative creation and handling of container images, ensuring reproducibility and efficiency in containerized environments.
Installation
See the readme.
Options
oci.enableDevShell
Whether to enable the flake development shell.
Type: boolean
Default:
false
Declared by:
oci.enableFlakeOutputs
Whether to automatically expose OCI apps, packages, and checks as flake outputs.
Type: boolean
Default:
true
Example:
false
Declared by:
oci.enabled
Whether to enable Enable the OCI module…
Type: boolean
Default:
false
Example:
true
Declared by:
oci.flake.outputs.packages
Expose oci-<name> gated image packages.
Type: boolean
Default:
true
Declared by:
oci.flake.outputs.checks
Expose oci-gate-<name> checks. Disabled by default since the gate is already enforced by packages and apps.
Type: boolean
Default:
false
Declared by:
oci.flake.outputs.loadDocker
Expose oci-load-docker-<name> apps (load into Docker).
Type: boolean
Default:
true
Declared by:
oci.flake.outputs.loadPodman
Expose oci-load-podman-<name> apps (load into Podman).
Type: boolean
Default:
true
Declared by:
oci.flake.outputs.push
Expose oci-push-<name> apps (push to registry).
Type: boolean
Default:
true
Declared by:
oci.flake.outputs.sandbox
Expose oci-sandbox-<name> apps (bubblewrap shell).
Type: boolean
Default:
true
Declared by:
perSystem.oci.packages.amicontained
The package to use for amicontained.
Type: package
Default:
amicontained v0.4.9 static binary
Example:
amicontained v0.4.9 static binary
Declared by:
perSystem.oci.packages.cdk
The package to use for CDK.
Type: package
Default:
cdk v1.5.4 static binary
Example:
cdk v1.5.4 static binary
Declared by:
perSystem.oci.packages.conftest
The package to use for conftest.
Type: package
Default:
pkgs.conftest
Example:
pkgs.conftest
Declared by:
perSystem.oci.packages.containerStructureTest
The package to use for container-structure-test.
Type: package
Default:
pkgs.container-structure-test
Example:
pkgs.container-structure-test
Declared by:
perSystem.oci.packages.cosign
The package to use for cosign.
Type: package
Default:
pkgs.cosign
Example:
pkgs.cosign
Declared by:
perSystem.oci.packages.deepce
The package to use for deepce.
Type: package
Default:
deepce v0.1.0
Example:
deepce v0.1.0
Declared by:
perSystem.oci.packages.dgoss
The package to use for dgoss.
Type: package
Default:
pkgs.dgoss
Example:
pkgs.dgoss
Declared by:
perSystem.oci.packages.dive
The package to use for dive.
Type: package
Default:
pkgs.dive
Example:
pkgs.dive
Declared by:
perSystem.oci.packages.dockle
The package to use for dockle.
Type: package
Default:
pkgs.dockle
Example:
pkgs.dockle
Declared by:
perSystem.oci.packages.grype
The package to use for grype.
Type: package
Default:
pkgs.grype
Example:
pkgs.grype
Declared by:
perSystem.oci.packages.linpeas
The package to use for linpeas.
Type: package
Default:
linpeas 20260604
Example:
linpeas 20260604
Declared by:
perSystem.oci.packages.nix2container
The nix2container package.
Type: attribute set
Default:
inputs.nix2container.packages.${system}.nix2container
Example:
inputs.nix2container.packages.${system}.nix2container
Declared by:
perSystem.oci.packages.podman
The package to use for podman.
Type: package
Default:
pkgs.podman
Example:
pkgs.podman
Declared by:
perSystem.oci.packages.regctl
The package to use for regctl (multi-arch manifest tool).
Type: package
Default:
pkgs.regclient
Example:
pkgs.regclient
Declared by:
perSystem.oci.packages.skaffold
The package to use for skaffold.
Type: package
Default:
pkgs.skaffold
Example:
pkgs.skaffold
Declared by:
perSystem.oci.packages.skopeo
The package to use for skopeo.
Type: package
Default:
inputs.nix2container.packages.${system}.skopeo-nix2container
Example:
inputs.nix2container.packages.${system}.skopeo-nix2container
Declared by:
perSystem.oci.packages.skopeoTurbo
The turbo-patched skopeo package from nix2container-turbo. Null when the input is not available.
Type: null or package
Default:
inputs.nix2container-turbo.packages.${system}.skopeo
Declared by:
perSystem.oci.packages.soci-snapshotter
The package providing soci and soci-snapshotter-grpc binaries.
Type: package
Default:
soci-snapshotter v0.14.1 static binaries
Example:
soci-snapshotter v0.14.1 static binaries
Declared by:
perSystem.oci.packages.syft
The package to use for syft.
Type: package
Default:
pkgs.syft
Example:
pkgs.syft
Declared by:
perSystem.oci.packages.trivy
The package to use for trivy.
Type: package
Default:
pkgs.trivy
Example:
pkgs.trivy
Declared by:
perSystem.oci.packages.vulnix
The package to use for vulnix.
Type: package
Default:
pkgs.vulnix
Example:
pkgs.vulnix
Declared by:
perSystem.oci.containers
Container definitions. Each key is a container name.
Type: attribute set of (submodule)
Default:
{ }
Example:
{
my-app = {
package = pkgs.hello;
dependencies = [ pkgs.bash ];
};
}
Declared by:
perSystem.oci.containers.<name>.package
The main package for the container.
Type: null or package
Default:
null
Example:
pkgs.hello
Declared by:
perSystem.oci.containers.<name>.autoLabels
Whether to automatically generate OCI image labels from package metadata.
When enabled, the following labels are generated (user labels always override):
- OCI standard annotations (
org.opencontainers.image.*): title, version, description, licenses, base.name - Build info (
io.github.dauliac.nix-oci.build.*): system, optimized-layers, reproducible - Hardening hints (
io.github.dauliac.nix-oci.hardening.*): security posture - Kubernetes PSS level (
io.github.dauliac.nix-oci.kubernetes.pod-security-standard)
Type: boolean
Default:
true
Declared by:
perSystem.oci.containers.<name>.compliance.trivy.enabled
Whether to enable CIS compliance checking with Trivy.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.compliance.trivy.report
Compliance report format: all for detailed results or summary for a condensed overview.
Type: one of “all”, “summary”
Default:
"summary"
Declared by:
perSystem.oci.containers.<name>.compliance.trivy.spec
The compliance spec to check against. See trivy image --help for built-in specs.
Type: string
Default:
"docker-cis-1.6.0"
Example:
"docker-cis-1.6.0"
Declared by:
perSystem.oci.containers.<name>.credentialsLeak.configPath
Path where global credentials leak check configuration files will be stored.
Type: absolute path
Default:
config.rootPath + "/credentials-leak/"
Declared by:
perSystem.oci.containers.<name>.credentialsLeak.trivy.enabled
Whether to enable credentials leak detection with Trivy.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.cve.configPath
Path where CVE scanner configuration files will be stored.
Type: absolute path
Default:
config.rootPath
Declared by:
perSystem.oci.containers.<name>.cve.grype.enabled
Whether to enable CVE scanning with Grype.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.cve.grype.config.enabled
Whether to enable Grype configuration file generation.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.cve.grype.config.rootPath
Path where Grype configuration files will be stored.
Type: absolute path
Default:
config.cve.configPath + "/grype/"
Declared by:
perSystem.oci.containers.<name>.cve.trivy.enabled
Whether to enable CVE scanning with Trivy.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.cve.trivy.ignore.extra
Additional CVE identifiers to ignore globally in Trivy scans.
Type: list of string
Default:
[ ]
Declared by:
perSystem.oci.containers.<name>.cve.trivy.ignore.fileEnabled
Whether to enable Trivy CVE ignore file generation.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.cve.trivy.ignore.rootPath
Path where Trivy CVE ignore files will be stored.
Type: absolute path
Default:
config.cve.configPath
Declared by:
perSystem.oci.containers.<name>.cve.vulnix.enabled
Whether to enable CVE scanning with vulnix.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.cve.vulnix.whitelist.enabled
Whether to enable vulnix whitelist file.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.cve.vulnix.whitelist.rootPath
Path where vulnix whitelist files will be stored.
Type: absolute path
Default:
config.cve.configPath + "/vulnix/"
Declared by:
perSystem.oci.containers.<name>.declaredVolumes
OCI volume mount point declarations baked into the image manifest. These tell the container runtime which paths contain persistent data.
For NixOS containers, auto-derived from systemd service directories:
- StateDirectory → /var/lib/<dir>
- RuntimeDirectory → /run/<dir>
- CacheDirectory → /var/cache/<dir>
- LogsDirectory → /var/log/<dir>
This is separate from deploy-time volumes (host bind mounts).
Type: list of string
Default: Auto-derived from systemd service directories:
StateDirectory→/var/lib/<dir>RuntimeDirectory→/run/<dir>CacheDirectory→/var/cache/<dir>LogsDirectory→/var/log/<dir>
Example:
[
"/var/lib/postgresql"
"/var/log/nginx"
]
Declared by:
perSystem.oci.containers.<name>.dependencies
Additional dependencies packages to include in the container.
Type: list of package
Default:
[ ]
Example:
[ pkgs.bash pkgs.coreutils ]
Declared by:
perSystem.oci.containers.<name>.entrypoint
OCI entrypoint (command + arguments).
Full container example:
{ pkgs, ... }:
{
package = pkgs.python3;
entrypoint = [
"${pkgs.python3}/bin/python3"
"-m"
"http.server"
"8080"
];
}
Type: list of string
Default:
[ ]
Example:
[
"/bin/hello"
"--greeting"
"world"
]
Declared by:
perSystem.oci.containers.<name>.environment
Environment variables baked into the OCI manifest and passed to the runner.
Type: attribute set of string
Default:
{ }
Example:
{
RUST_LOG = "info";
}
Declared by:
perSystem.oci.containers.<name>.gid
GID for the non-root container user’s primary group.
Only used when isRoot = false. The default (4000) matches
the default UID to keep user/group mapping simple.
Type: signed integer
Default:
4000
Example:
1000
Declared by:
perSystem.oci.containers.<name>.gpu.enable
Enable NVIDIA GPU support for this container.
When enabled, sets environment variables that trigger the NVIDIA
Container Toolkit runtime injection (NVIDIA_VISIBLE_DEVICES,
NVIDIA_DRIVER_CAPABILITIES) and includes CUDA runtime libraries
from nixpkgs in the container image.
Compatible with the NVIDIA GPU Operator in Kubernetes – images built with this option work with both legacy (env-var) and CDI (Container Device Interface) injection modes.
Driver libraries (libcuda.so, libnvidia-ml.so, nvidia-smi)
are NOT bundled – they are always injected at runtime by the
host’s NVIDIA Container Toolkit.
Requires nixpkgs.config.cudaSupport = true and
nixpkgs.config.allowUnfree = true in the consuming flake.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.gpu.capabilities
NVIDIA driver capabilities to request at runtime.
Each capability controls which host driver libraries the NVIDIA Container Toolkit bind-mounts into the container:
"compute"– CUDA and OpenCL libraries."utility"– Management tools (nvidia-smi,libnvidia-ml.so)."graphics"– OpenGL, EGL, Vulkan, OptiX libraries."video"– Hardware video codec libraries (NVENC/NVDEC)."display"– X11 display output libraries."all"– All capabilities above.
Default: ["compute" "utility"] (CUDA compute + nvidia-smi).
Type: list of (one of “compute”, “utility”, “graphics”, “video”, “display”, “all”)
Default:
[
"compute"
"utility"
]
Declared by:
perSystem.oci.containers.<name>.gpu.cudaVersion
Minimum CUDA version constraint.
When set, the NVIDIA_REQUIRE_CUDA environment variable is
added to the image config (e.g. cuda>=12.2). The NVIDIA
Container Toolkit validates this against the host driver before
allowing the container to start.
When null (default), the version is auto-detected from the
cudaPackages in nixpkgs.
Type: null or string
Default:
null
Example:
"12.2"
Declared by:
perSystem.oci.containers.<name>.gpu.forwardCompat
Include CUDA forward compatibility libraries in the image.
When enabled, the cuda-compat package is added and
LD_LIBRARY_PATH is configured so compat libraries take
precedence over the host-injected driver libraries.
This allows the container to use a newer CUDA toolkit than the host driver natively supports. Useful when deploying to clusters where driver upgrades are infrequent.
Not all features are forward-compatible – some require kernel-mode driver support for new hardware capabilities.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.gpu.runtimeLibraries
CUDA toolkit libraries to include in the container image.
"cudart"– CUDA runtime (libcudart.so). Almost always needed."cublas"– cuBLAS linear algebra."cufft"– cuFFT Fourier transforms."curand"– cuRAND random number generation."cusolver"– cuSOLVER dense/sparse solvers."cusparse"– cuSPARSE sparse matrix operations."cudnn"– cuDNN deep learning primitives."tensorrt"– TensorRT inference optimization."nccl"– NCCL multi-GPU/node communication."cutlass"– CUTLASS GEMM templates."nvjpeg"– nvJPEG hardware JPEG decoding.
Only selected libraries are included to minimize image size.
Driver libraries (libcuda.so) are never bundled.
Type: list of (one of “cudart”, “cublas”, “cufft”, “curand”, “cusolver”, “cusparse”, “cudnn”, “tensorrt”, “nccl”, “cutlass”, “nvjpeg”)
Default:
[
"cudart"
]
Example:
[
"cudart"
"cublas"
"cudnn"
]
Declared by:
perSystem.oci.containers.<name>.hardening.enable
Enable container security hardening.
When enabled, applies build-time filesystem restrictions and generates runtime security hints consumed by deploy modules.
Three independent kernel primitives are available:
- Seccomp – syscall filtering (BPF at the syscall boundary)
- AppArmor – mandatory access control (LSM pathname-based)
- Capabilities + flags – privilege restriction at runtime
For containers using nixosConfig, these options are forwarded
to the inner NixOS module at oci.container.hardening and can
be overridden through NixOS module composition.
Full container example:
{
package = pkgs.busybox;
isRoot = true;
hardening = {
enable = true;
disableDns = true;
noTlsTrustStore = true;
seccomp = {
enable = true;
profile = "strict";
};
capabilities = {
drop = [ "ALL" ];
add = [ "NET_BIND_SERVICE" ];
};
readOnlyRootfs = true;
noNewPrivileges = true;
};
}
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.hardening.apparmor
AppArmor MAC profile configuration.
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.containers.<name>.hardening.apparmor.enable
Enable AppArmor profile generation for this container.
When enabled, a tailored AppArmor profile is generated as a
build output. The deploy module references it via
--security-opt apparmor=<profile>.
Requires the target host to have AppArmor enabled
(kernel LSM + apparmor_parser). On NixOS, set
security.apparmor.enable = true.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.hardening.apparmor.customProfile
Path to a custom AppArmor profile file. When set, overrides ALL computed profile rules. The profile must be a valid AppArmor profile file.
Note: cross-backend coherence checks cannot verify custom profiles — you take full responsibility for correctness.
Type: null or absolute path
Default:
null
Declared by:
perSystem.oci.containers.<name>.hardening.apparmor.denyMount
Deny mount operations inside the container.
Prevents filesystem remounting, overlay stacking, and
bind-mount escape attacks. Enforced via AppArmor
deny mount, rule.
Type: boolean
Default:
true
Declared by:
perSystem.oci.containers.<name>.hardening.apparmor.denyPtrace
Deny ptrace of other processes.
Prevents process inspection and memory manipulation attacks.
Enforced via AppArmor deny ptrace (read, read, trace, traceby),
rule.
Type: boolean
Default:
true
Declared by:
perSystem.oci.containers.<name>.hardening.apparmor.denyUserNamespace
Deny user namespace creation inside the container.
Prevents the class of Local Privilege Escalation (LPE) vulnerabilities where unprivileged processes exploit userns to reach normally-root-only kernel code paths (CVE-2023-2640, CVE-2023-32629, etc.).
Enforced via AppArmor deny userns_create, rule.
Complementary to seccomp clone(CLONE_NEWUSER) arg filter
and capability drop SYS_ADMIN.
Type: boolean
Default:
true
Declared by:
perSystem.oci.containers.<name>.hardening.apparmor.mode
AppArmor enforcement mode:
"enforce"– violations are blocked and logged (default). Use for production."complain"– violations are logged but NOT blocked. Useful for profile discovery before switching to enforce.
Type: one of “enforce”, “complain”
Default:
"enforce"
Declared by:
perSystem.oci.containers.<name>.hardening.capabilities
Linux capability restrictions applied at runtime by deploy modules.
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.containers.<name>.hardening.capabilities.add
Linux capabilities to add back after dropping.
Deploy modules translate to --cap-add.
Type: list of string
Default:
[ ]
Example:
[
"NET_BIND_SERVICE"
]
Declared by:
perSystem.oci.containers.<name>.hardening.capabilities.drop
Linux capabilities to drop. Defaults to ["ALL"].
Deploy modules translate to --cap-drop.
Type: list of string
Default:
[
"ALL"
]
Declared by:
perSystem.oci.containers.<name>.hardening.disableDns
Disable DNS resolution inside the container.
Sets /etc/nsswitch.conf hosts line to files only (no dns
backend). Applications using IP addresses directly are unaffected.
NOTE: /etc/resolv.conf is NOT written into the image because
container runtimes (Docker, Podman) always bind-mount it at
startup, masking any baked-in content. To fully enforce DNS
restriction at runtime, use --dns=127.0.0.1 or network
policies.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.hardening.noNewPrivileges
Set the no_new_privs bit. Prevents privilege escalation
via setuid/setgid binaries or file capabilities.
Deploy modules translate to
--security-opt=no-new-privileges.
Type: boolean
Default:
true
Declared by:
perSystem.oci.containers.<name>.hardening.noTlsTrustStore
Remove the TLS certificate trust store (/etc/ssl/certs).
Prevents all outgoing HTTPS connections.
Only use for containers that never initiate TLS connections. This is a nuclear option – most applications that make any outbound HTTP requests will break.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.hardening.readOnlyRootfs
Mount the container root filesystem as read-only at runtime.
Deploy modules translate to --read-only.
Prevents attackers from writing malware or achieving persistence if they gain initial access.
Type: boolean
Default:
true
Declared by:
perSystem.oci.containers.<name>.hardening.seccomp
Seccomp syscall filtering configuration.
Full container example:
{
package = pkgs.busybox;
hardening = {
enable = true;
seccomp = {
enable = true;
profile = "web-server";
mode = "enforce";
};
};
}
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.containers.<name>.hardening.seccomp.enable
Enable a custom seccomp profile for this container.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.hardening.seccomp.customProfileJson
Path to a custom seccomp profile JSON file following the
OCI runtime specification format. When set, overrides
the profile option.
Type: null or absolute path
Default:
null
Declared by:
perSystem.oci.containers.<name>.hardening.seccomp.mode
Seccomp enforcement mode:
"enforce"– block disallowed syscalls with SCMP_ACT_ERRNO (default)."audit"– log disallowed syscalls with SCMP_ACT_LOG but allow them. Useful for profile discovery and testing before switching to enforce.
Type: one of “enforce”, “audit”
Default:
"enforce"
Declared by:
perSystem.oci.containers.<name>.hardening.seccomp.profile
Predefined seccomp profile level:
-
"strict"– allowlist of ~60 syscalls. Suitable for static binaries, Go/Rust services. Blocksmount,ptrace,execve, and most process/namespace ops. -
"moderate"– blocks ~50 dangerous syscalls including io_uring and memfd_create. All profiles include argument-level filtering for clone (block namespace creation), socket (block AF_NETLINK/AF_PACKET), and ioctl (block TIOCSTI/TIOCLINUX terminal injection). -
"web-server"– strict base plus networking and threading syscalls. Suitable for HTTP servers. -
"database"– web-server base plus memory management syscalls (fadvise64, msync, mincore). Suitable for PostgreSQL, Redis, and similar services. -
"gpu-compute"– web-server base plus CUDA/GPU syscalls (perf_event_open, memfd_create, NUMA memory policy). Relaxes ioctl filtering for GPU command submission. Auto-selected whengpu.enable = true.
In the inner NixOS module, the profile auto-defaults to
"gpu-compute" when GPU is enabled, "web-server" when
a known web server is detected, and "database" when
PostgreSQL or Redis is detected.
Type: one of “strict”, “moderate”, “web-server”, “database”, “gpu-compute”
Default:
"moderate"
Declared by:
perSystem.oci.containers.<name>.healthcheck.command
Health check command (CMD form).
When non-empty, baked into the OCI image as Healthcheck.Test.
For NixOS-based containers, service adapters can auto-derive this from the NixOS module configuration (ports, endpoints, etc.).
Example: [ "curl" "-f" "http://localhost:8080/health" ]
Full container example:
{
package = pkgs.python3;
dependencies = [ pkgs.curl ];
entrypoint = [
"${pkgs.python3}/bin/python3"
"-m"
"http.server"
"8080"
];
ports = [ "8080:8080" ];
healthcheck = {
command = [
"${pkgs.curl}/bin/curl"
"-f"
"http://localhost:8080/"
];
interval = 15;
timeout = 3;
startPeriod = 5;
retries = 3;
};
}
Type: list of string
Default: Auto-derived by service adapters when available:
- nginx:
curlstub_status or/healthendpoint - caddy:
curladmin API (localhost:2019) - PostgreSQL:
pg_isready - Redis:
redis-cli ping - BIND/dnsmasq:
digDNS query - Postfix:
postfix status
Example:
[
"curl"
"-f"
"http://localhost:8080/health"
]
Declared by:
perSystem.oci.containers.<name>.healthcheck.interval
Seconds between health checks.
Type: signed integer
Default:
30
Declared by:
perSystem.oci.containers.<name>.healthcheck.retries
Number of consecutive failures before the container is considered unhealthy.
Type: signed integer
Default:
3
Declared by:
perSystem.oci.containers.<name>.healthcheck.startPeriod
Grace period (seconds) before the first health check runs after container start.
Type: signed integer
Default:
5
Declared by:
perSystem.oci.containers.<name>.healthcheck.timeout
Seconds to wait for a single health check to complete.
Type: signed integer
Default:
5
Declared by:
perSystem.oci.containers.<name>.homeManager.flake
The home-manager flake input. When set, enables home-manager integration for this container.
Example:
oci.containers.dev = {
homeManager.flake = inputs.home-manager;
homeManager.modules = [{ home.packages = [ pkgs.vim ]; }];
};
Type: null or unspecified value
Default:
null
Example:
"inputs.home-manager"
Declared by:
perSystem.oci.containers.<name>.homeManager.modules
Home-manager modules for the container user’s home directory.
These configure dotfiles, shell, git, editor, etc. Requires
homeManager.flake to be set.
Type: list of unspecified value
Default:
[ ]
Declared by:
perSystem.oci.containers.<name>.initializeNixDatabase
Populate the Nix database (/nix/var/nix/db/db.sqlite) with the
closure of all store paths shipped in the image.
Enable this when you need to run Nix commands (nix build,
nix eval, nix-store -q, …) inside the container. Without it,
the Nix store directory contains packages but the database is empty,
causing Nix to believe no packages are installed.
Disabled by default because copyToRoot flattens store paths to /,
creating phantom database entries for the flattened derivations.
This is harmless for in-container Nix usage but may confuse workflows
that validate database-vs-disk consistency.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.isRoot
Whether the container process runs as root.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.labels
OCI image labels (metadata key-value pairs).
Full container example:
{
package = pkgs.hello;
labels = {
"org.opencontainers.image.title" = "my-app";
"org.opencontainers.image.version" = "1.0.0";
"org.opencontainers.image.description" = "My containerized application";
};
}
Type: attribute set of string
Default:
{ }
Example:
{
"org.opencontainers.image.title" = "my-app";
"org.opencontainers.image.version" = "1.0.0";
}
Declared by:
perSystem.oci.containers.<name>.layerStrategy
Controls how nix2container splits store paths into sub-layers.
Only effective when optimizeLayers is true.
-
"minimal": exactly one layer per concern (deps, app). Produces 2 total layers. Most predictable cache behaviour – adding or removing a dependency only invalidates the deps layer. Best for projects with few images where cross-image sharing is not a priority. -
"fine-grained": each logical layer is further split using nix2container’s store-path popularity algorithm. The deps layer gets up to 80 sub-layers, andbuildImagesplits remaining paths into up to 40. Foundational packages (glibc, openssl) get their own sub-layers and are shared byte-for-byte across images in the same registry. Best for registries hosting many images with overlapping dependencies.
Type: one of “minimal”, “fine-grained”
Default:
"fine-grained"
Example:
"minimal"
Declared by:
perSystem.oci.containers.<name>.license.conftest.enabled
Whether to enable SBOM license compliance checking with Conftest.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.license.conftest.extraPolicyDirs
Additional directories containing Rego policy files for license checking. These are merged WITH the built-in license policies.
Type: list of absolute path
Default:
[ ]
Example:
[ ./my-license-policies ]
Declared by:
perSystem.oci.containers.<name>.license.conftest.namespaces
Rego namespaces to check. Each namespace maps to a package declaration in the license policy files.
Type: list of string
Default:
[
"license"
]
Example:
[
"license"
"custom_license"
]
Declared by:
perSystem.oci.containers.<name>.license.conftest.policyDir
Path to a directory containing Rego policy files for license checking.
Policies receive a CycloneDX SBOM JSON as input and should define
deny or warn rules in the license package. nix-oci ships
built-in policies that reject common forbidden licenses (AGPL, SSPL)
and warn on copyleft licenses (GPL, LGPL).
Type: absolute path
Default:
built-in nix-oci license policies
Declared by:
perSystem.oci.containers.<name>.lint.dockle.enabled
Whether to enable container image linting with Dockle.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.lint.dockle.exitLevel
Minimum severity level that causes a non-zero exit code.
Type: one of “info”, “warn”, “fatal”
Default:
"info"
Declared by:
perSystem.oci.containers.<name>.lint.dockle.ignore
List of Dockle checkpoint IDs to ignore (e.g. CIS-DI-0001).
Type: list of string
Default:
[
"CIS-DI-0005"
"CIS-DI-0006"
]
Example:
[
"CIS-DI-0001"
"DKL-DI-0006"
]
Declared by:
perSystem.oci.containers.<name>.mainService
Logical NixOS service name to extract container metadata from.
When set, nix-oci automatically derives:
- Entrypoint from the systemd
ExecStart - Stop signal from the systemd
KillSignalor service adapter - Working directory from
WorkingDirectoryor servicedataDir - Health check from the service adapter (curl, pg_isready, etc.)
- Volumes from
StateDirectory,RuntimeDirectory, etc.
For most services, this matches the NixOS option prefix
(e.g. "nginx" for services.nginx). For multi-instance services
(e.g. Redis), the service adapter resolves the actual systemd
unit name automatically.
Requires nixosConfig.modules to include the service configuration.
Type: null or string
Default:
null
Example:
"nginx"
Declared by:
perSystem.oci.containers.<name>.name
OCI image name. Defaults to the container attribute name.
Type: string
Default:
"‹name›"
Example:
"my-custom-image"
Declared by:
perSystem.oci.containers.<name>.optimizeLayers
Split container contents into deduplicated layers for optimal registry caching. Uses a two-level heuristic:
Level 1 – popularity-based splitting. Within each layer,
nix2container’s store-path popularity algorithm sorts paths by
how many other paths reference them. Foundational packages
(glibc, openssl, …) get their own sub-layers; application-specific
paths cluster together. Capped by a maxLayers budget per layer.
Level 2 – fold-based cross-layer deduplication. Layers are built in a chain where each layer references all predecessors. nix2container excludes any store path already present in an earlier layer, eliminating duplication across explicit layers.
The resulting layer stack (most stable first):
- Deps layer (runtime libraries,
maxLayers = 80when fine-grained) - App layer (package, shadow, configs)
Use layerStrategy to control sub-splitting granularity:
"fine-grained" (default) for maximum cross-image sharing,
"minimal" for exactly one layer per concern.
See Nix and layered Docker images for the original algorithm and nix2container for the implementation used here.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.performance.enable
Enable container performance tuning.
When enabled, applies build-time optimizations (allocator injection, glibc tunables, CPU-targeted libraries) and generates runtime hints consumed by deploy modules.
Three independent optimization axes are available:
- Allocator – replace glibc ptmalloc2 with mimalloc/tcmalloc via
LD_PRELOAD - glibc tunables – tune malloc arenas, tcache, mmap thresholds
- hwcaps – ship CPU-optimized library variants (glibc-hwcaps, per-arch)
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.performance.allocator
Alternative memory allocator injected via LD_PRELOAD.
-
"mimalloc"– Microsoft’s general-purpose allocator. Lowest RSS for small allocations, excellent for microservices. Works on musl. -
"tcmalloc"– Google’s per-CPU-cache allocator. Best throughput for large allocation patterns and high-concurrency servers. Requires glibc (does not work on musl). -
"jemalloc"– Facebook’s allocator used by Redis and Firefox. Best fragmentation resistance and P99 latency for long-running servers. Requires glibc (segfaults on musl).Warning: jemalloc uses
MADV_FREEby default, which inflates cgroup RSS accounting. The module automatically setsmuzzy_decay_ms:0unless overridden viaallocatorConfig. -
"snmalloc"– Microsoft Research lock-free allocator. Excellent for high cross-thread deallocation patterns (request/response servers where allocating thread differs from freeing thread). -
null– use glibc’s default ptmalloc2 (no injection).
The allocator library is added as a container dependency and
LD_PRELOAD is set in the OCI manifest Env.
Type: null or one of “mimalloc”, “tcmalloc”, “jemalloc”, “snmalloc”
Default:
null
Example:
"jemalloc"
Declared by:
perSystem.oci.containers.<name>.performance.allocatorConfig
Allocator-specific tuning parameters.
Keys and values depend on the selected performance.allocator:
mimalloc – keys become MIMALLOC_<KEY> environment variables:
PURGE_DELAY="100"– ms before purging unused pagesPURGE_DECOMMITS="1"– use MADV_DONTNEED (cgroup-accurate RSS)ARENA_EAGER_COMMIT="0"– lazy commit for memory-constrainedALLOW_LARGE_OS_PAGES="1"– use 2MB huge pages
tcmalloc – keys become TCMALLOC_<KEY> environment variables:
AGGRESSIVE_DECOMMIT="true"– aggressively return memory to OSMAX_TOTAL_THREAD_CACHE_BYTES="8388608"– 8MB thread cache capRELEASE_RATE="10.0"– OS memory return rate
jemalloc – keys are colon-joined into MALLOC_CONF:
narenas="2"– limit arenas (default: 4*ncpus)dirty_decay_ms="5000"– dirty page purge timingmuzzy_decay_ms="0"– skip MADV_FREE (critical for cgroups)background_thread="true"– offload purgingretain="false"– actually munmap under cgroup limitsmetadata_thp="auto"– THP for jemalloc metadata
snmalloc – no runtime tunables (configured at compile time).
When the selected allocator is null, this option is ignored.
Type: attribute set of string
Default:
{ }
Example:
{
background_thread = "true";
dirty_decay_ms = "5000";
muzzy_decay_ms = "0";
narenas = "2";
}
Declared by:
perSystem.oci.containers.<name>.performance.compression
Compression algorithm for OCI image layers during transport (skopeo).
"gzip"– universal compatibility, slower."zstd"– 3-5x faster compress/decompress, 12% smaller. Requires OCI 1.1+ registry (Docker Hub, ECR, GCR, GHCR support it). containerd 2.0+ required; containerd 1.7.x does NOT support zstd."gzip:estargz"– eStargz format for lazy pulling with stargz-snapshotter. Requiresperformance.turbo.enable = true. Cannot be combined with SOCI (performance.turbo.soci).
Type: one of “gzip”, “zstd”, “gzip:estargz”
Default:
"gzip"
Example:
"zstd"
Declared by:
perSystem.oci.containers.<name>.performance.glibcTunables
glibc tunables set via the GLIBC_TUNABLES environment variable.
Keys are tunable names (e.g. glibc.malloc.arena_max), values
are strings. Multiple tunables are colon-joined automatically.
Recommended for containers:
glibc.malloc.arena_max = "2"– cap malloc arenas to reduce RSSglibc.malloc.mmap_threshold = "131072"– reduce fragmentationglibc.malloc.tcache_count = "7"– tune per-thread cache
Only effective with glibc-based containers (not musl).
Type: attribute set of string
Default:
{ }
Example:
{
"glibc.malloc.arena_max" = "2";
}
Declared by:
perSystem.oci.containers.<name>.performance.glibcTunablesPreset
Curated glibc tunables preset for common container workloads.
Presets set glibcTunables values via mkDefault – explicit
glibcTunables entries always take precedence.
-
"memory-constrained"– for containers with <512MB memory limit. Aggressively reduces arena count and malloc overhead:arena_max=2, trim_threshold=32768, top_pad=0, mmap_threshold=65536, tcache_count=3 -
"high-throughput"– for CPU-bound servers with ample memory. Maximizes allocation throughput:arena_max=8, tcache_count=15, mxfast=256 -
"balanced"– safe defaults for general-purpose containers. Moderate arena count with sensible thresholds:arena_max=4, trim_threshold=131072, mmap_threshold=131072, tcache_count=7 -
null– no preset (only explicitglibcTunablesapply).
Only effective with glibc-based containers (not musl).
Type: null or one of “memory-constrained”, “high-throughput”, “balanced”
Default:
null
Example:
"balanced"
Declared by:
perSystem.oci.containers.<name>.performance.hugePages
Huge page configuration for reduced TLB misses and lower page walk latency.
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.containers.<name>.performance.hugePages.glibcHugetlb
glibc malloc.hugetlb tunable value.
0– disabled (default).1– useMADV_HUGEPAGEafter mmap.2– useMAP_HUGETLBdirectly (requires hugetlbfs).
Type: null or one of 0, 1, 2
Default:
null
Example:
1
Declared by:
perSystem.oci.containers.<name>.performance.hugePages.thpMode
Transparent Huge Pages mode hint. Sets glibc.malloc.hugetlb
tunable and generates an OCI label for host configuration.
"madvise"– recommended for containers."always"– aggressive, can cause compaction latency spikes.null– no THP hint (host default applies).
Type: null or one of “madvise”, “always”
Default:
null
Example:
"madvise"
Declared by:
perSystem.oci.containers.<name>.performance.hwcaps
glibc-hwcaps: ship CPU-optimized library variants selected at runtime.
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.containers.<name>.performance.hwcaps.enable
Build and ship CPU-optimized library variants via glibc-hwcaps.
The dynamic linker selects the best variant at process startup based on CPUID – zero application changes required.
Only effective on systems with hwcaps support (x86_64-linux). Auto-disabled on unsupported architectures in per-arch config.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.performance.hwcaps.levels
Microarchitecture levels to build optimized libraries for. Valid values depend on the target system:
- x86_64-linux:
"x86-64-v2","x86-64-v3","x86-64-v4"
The baseline is always included as fallback (not listed here).
Type: list of string
Default:
[ ]
Example:
[
"x86-64-v3"
]
Declared by:
perSystem.oci.containers.<name>.performance.hwcaps.libraries
Packages whose shared libraries to rebuild at each hwcaps level.
Only .so files are extracted into the hwcaps layer.
Good candidates: crypto (openssl), compression (zlib, zstd), math-heavy libraries, string processing.
Type: list of package
Default:
[ ]
Example:
[ pkgs.openssl pkgs.zlib ]
Declared by:
perSystem.oci.containers.<name>.performance.startup
Container process startup optimization.
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.containers.<name>.performance.startup.ldSoCache
Run ldconfig at image build time to pre-build
/etc/ld.so.cache with all library paths.
Eliminates filesystem search at process startup. Beneficial for containers with many shared libraries.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.performance.startup.stackSize
Default thread stack size override. Set via ulimit -s in
the container entrypoint.
Reducing from the default 8MB to 512KB-2MB saves significant virtual memory for containers with many threads.
Format: size in KB (e.g. "512" for 512KB, "2048" for 2MB).
Type: null or string
Default:
null
Example:
"512"
Declared by:
perSystem.oci.containers.<name>.performance.turbo.enable
Use nix2container-turbo patched skopeo for image pushes.
Enables cross-machine layer caching via OCI Referrers API: layer mappings (nix store hash → compressed digest) are stored in the registry so any machine can skip re-compressing and re-uploading unchanged layers. Repushes become sub-second regardless of image size.
Requires an OCI registry supporting the Referrers API (ECR, GHCR, Docker Hub, and most modern registries).
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.performance.turbo.layerCache
Enable cross-machine layer caching via OCI Referrers API.
Stores nix store path → compressed layer mappings as referrer manifests in the registry. Subsequent pushes from any machine look up these mappings and skip re-compression and re-upload for unchanged layers.
Achieves sub-second repush times regardless of image size.
Enabled by default when performance.turbo.enable = true.
Requires an OCI registry supporting the Referrers API.
Type: boolean
Default:
true
Example:
true
Declared by:
perSystem.oci.containers.<name>.performance.turbo.soci
Generate SOCI v2 indexes during push for lazy pulling.
When enabled, the turbo-patched skopeo generates zTOC (table of contents) for each layer during push and bundles them into a SOCI v2 index manifest alongside the image in an OCI Index.
Reduces cold-start times significantly for large images on AWS ECS/Fargate (~53s → ~20s for a 1GB image).
Requires performance.turbo.enable = true and gzip compression
(SOCI does not support zstd). eStargz and SOCI cannot be combined.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.performance.turbo.sociSpanSize
SOCI span size in bytes for zTOC checkpoint granularity.
Controls how often deflate checkpoints are inserted in the compressed layer data. Smaller values allow more precise random-access seeking (faster individual file access) at the cost of a larger zTOC index.
4194304(4 MiB) – default, good balance for most workloads.1048576(1 MiB) – finer granularity, better for many small files.8388608(8 MiB) – coarser, smaller index, better for large files.
Only effective when performance.turbo.soci = true.
Type: signed integer
Default:
4194304
Example:
4194304
Declared by:
perSystem.oci.containers.<name>.policy.conftest.enabled
Whether to enable OCI image config policy checking with Conftest.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.policy.conftest.extraPolicyDirs
Additional directories containing Rego policy files. These are merged WITH the built-in policies.
Type: list of absolute path
Default:
[ ]
Example:
[ ./my-policies ./team-policies ]
Declared by:
perSystem.oci.containers.<name>.policy.conftest.namespaces
Rego namespaces to check. Each namespace maps to a package declaration in the policy files.
Type: list of string
Default:
[
"main"
]
Example:
[
"main"
"custom"
]
Declared by:
perSystem.oci.containers.<name>.policy.conftest.policyDir
Path to a directory containing Rego policy files for Conftest.
Policies receive the OCI image config JSON as input and should
define deny or warn rules. nix-oci ships built-in policies
that check for common security issues (root user, leaked secrets
in env vars, missing labels).
Type: absolute path
Default:
built-in nix-oci OCI policies
Declared by:
perSystem.oci.containers.<name>.ports
Port mappings (e.g. ["8080:8080"]).
Baked into OCI manifest ExposedPorts and used by the runner service.
Full container example:
{
package = pkgs.python3;
entrypoint = [
"${pkgs.python3}/bin/python3"
"-m"
"http.server"
"8080"
];
ports = [ "8080:8080" ];
}
Type: list of string
Default:
[ ]
Example:
[
"8080:8080"
"443:443"
]
Declared by:
perSystem.oci.containers.<name>.registry
The OCI registry to use for pushing and pulling images.
Type: null or string
Default:
null
Declared by:
perSystem.oci.containers.<name>.rootPath
The root path to store the Nix OCI resources.
Type: absolute path
Default:
self + "/oci/"
Declared by:
perSystem.oci.containers.<name>.sbom.path
Path where SBOM files will be stored.
Type: absolute path
Default:
config.rootPath
Declared by:
perSystem.oci.containers.<name>.sbom.syft.enabled
Whether to enable SBOM generation with Syft.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.sbom.syft.config.enabled
Whether to enable Syft configuration file generation.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.sbom.syft.config.rootPath
Path where Syft configuration files will be stored.
Type: absolute path
Default:
config.sbom.path
Declared by:
perSystem.oci.containers.<name>.signing.cosign.enabled
Whether to enable OCI image signing with cosign.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.containers.<name>.signing.cosign.annotations
Key-value annotations to attach to every cosign signature.
These appear in cosign verify output and can be used
for policy enforcement (e.g. with Kyverno or OPA).
Type: attribute set of string
Default:
{ }
Example:
{
build-system = "nix";
repo = "https://github.com/example/repo";
}
Declared by:
perSystem.oci.containers.<name>.signing.cosign.certificateIdentityRegexp
Regular expression to match the certificate identity when
verifying keyless signatures. Required for keyless verification.
Example: "https://github.com/myorg/.*" or an email pattern.
Type: null or string
Default:
null
Declared by:
perSystem.oci.containers.<name>.signing.cosign.certificateOidcIssuerRegexp
Regular expression to match the OIDC issuer when verifying
keyless signatures. Required for keyless verification.
Example: "https://token.actions.githubusercontent.com".
Type: null or string
Default:
null
Declared by:
perSystem.oci.containers.<name>.signing.cosign.key
Path or KMS URI for the cosign signing key. Supports local files, environment variables, and KMS URIs:
- Local file:
./cosign.key - Environment variable:
env://COSIGN_PRIVATE_KEY - AWS KMS:
awskms://[ENDPOINT]/[ID/ALIAS/ARN] - GCP KMS:
gcpkms://projects/[PROJECT]/locations/[LOC]/keyRings/[RING]/cryptoKeys/[KEY] - Azure Key Vault:
azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - HashCorp Vault:
hashivault://[KEY]Only used whenkeylessis false.
Type: null or string
Default:
null
Declared by:
perSystem.oci.containers.<name>.signing.cosign.keyEnvVar
Environment variable consulted at runtime for the cosign key
path or URI. When set in the environment, its value is used as
--key <value>, overriding the Nix-configured key option.
Set to null to disable runtime override and always use the
Nix-configured key value.
Only relevant when keyless is false.
The default "COSIGN_KEY" matches cosign’s own convention.
Common patterns:
COSIGN_KEY=./cosign.key— local fileCOSIGN_KEY=env://COSIGN_PRIVATE_KEY— key content in another env varCOSIGN_KEY=awskms://...— KMS URI
Type: null or string
Default:
"COSIGN_KEY"
Declared by:
perSystem.oci.containers.<name>.signing.cosign.keyless
Use keyless (OIDC) signing via Sigstore Fulcio.
When true, cosign authenticates via an OIDC provider
(GitHub Actions, Google, Microsoft) and issues ephemeral
certificates. No key management required.
When false, key must be set.
Type: boolean
Default:
true
Declared by:
perSystem.oci.containers.<name>.signing.cosign.verify
Whether to verify the signature immediately after signing.
Type: boolean
Default:
true
Declared by:
perSystem.oci.containers.<name>.stopSignal
Signal to send for graceful container shutdown (e.g., “SIGQUIT”, “SIGINT”). When null, auto-derived for NixOS containers from the service adapter or systemd KillSignal. Falls back to the container runtime default (SIGTERM).
Type: null or string
Default: Auto-derived (strongest to weakest):
- service adapter signal (e.g.
SIGQUITfor nginx,SIGINTfor PostgreSQL) - systemd
KillSignal - container runtime default (
SIGTERM)
Example:
"SIGQUIT"
Declared by:
perSystem.oci.containers.<name>.tag
OCI image tag.
Type: string
Default:
"latest"
Example:
"v1.0.0"
Declared by:
perSystem.oci.containers.<name>.test.amicontained.enabled
Whether to enable amicontained container introspection globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.test.cdk.enabled
Whether to enable CDK container security auditing globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.test.containerStructureTest.enabled
Whether to enable container-structure-test globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.test.deepce.enabled
Whether to enable DEEPCE container escape detection globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.test.dgoss.enabled
Whether to enable dgoss testing globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.test.dgoss.hermetic
Run dgoss as a pure Nix derivation (check) using podman.
Requires extra-sandbox-paths = /sys/fs/cgroup in nix.conf.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.test.dive.enabled
Whether to enable Dive analysis globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.test.linpeas.enabled
Whether to enable linPEAS privilege escalation auditing globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.containers.<name>.uid
UID for the non-root container user.
Only used when isRoot = false. The default (4000) avoids
conflicts with system UIDs (< 1000) and common application
UIDs while remaining within the standard UID range.
Type: signed integer
Default:
4000
Example:
1000
Declared by:
perSystem.oci.containers.<name>.user
User to run the container process as.
Full container example:
{ pkgs, ... }:
{
package = pkgs.hello;
user = "nobody";
}
Type: string
Default:
"root"
Example:
"nobody"
Declared by:
perSystem.oci.containers.<name>.workingDir
Working directory for the container process. When null, auto-derived for NixOS containers from (strongest to weakest):
- systemd WorkingDirectory
- service dataDir (e.g., /var/lib/postgresql for PostgreSQL)
- user home directory (/root or /home/<user>)
For non-NixOS containers, defaults to the user home directory.
Type: null or string
Default: Auto-derived (strongest to weakest):
- systemd
WorkingDirectory - service
dataDir(e.g./var/lib/postgresql) - user home directory (
/rootor/home/<user>)
Example:
"/var/lib/postgresql"
Declared by:
perSystem.oci.flake.packages
OCI container packages that can be exposed as flake outputs.
Type: attribute set of package (read only)
Default:
{ }
Declared by:
perSystem.oci.flake.apps
OCI-related apps that can be exposed as flake outputs.
Type: attribute set of (attribute set) (read only)
Default:
Per-container sandbox, push, load-docker, load-podman apps.
Declared by:
perSystem.oci.flake.checks
OCI-related checks that can be exposed as flake outputs.
Type: attribute set of package (read only)
Default:
{ }
Declared by:
perSystem.oci.fromImageManifestDir
Runtime directory for manifest lock files, relative to the flake root.
Used by oci-update-manifests to write lock files to the working copy.
Each container gets a subdirectory: <dir>/<containerId>/manifest-lock.json.
Type: string
Default:
"./oci"
Declared by:
perSystem.oci.fromImageManifestRootPath
The root path for OCI manifest lock files (Nix path, used at build time). Each container gets a subdirectory.
Type: absolute path
Default:
config.oci.rootPath
Declared by:
perSystem.oci.perArchitecture
Per-architecture module definitions applied to every archConfigs entry.
Parallel to oci.perContainer – a top-level collector for per-architecture
options. Contributed modules are evaluated for every target architecture
within every container.
Each module receives these special arguments:
name: the target system string (e.g."aarch64-linux")containerConfig: the parent container’s evaluated configcontainerId: the container’s attribute namesystem: the host build systempkgs: nixpkgs for the host system
Example:
oci.perArchitecture = [
({ name, containerConfig, ... }: {
options.myArchOption = lib.mkOption { type = lib.types.str; };
})
];
Type: list of raw value
Default:
[ ]
Declared by:
perSystem.oci.perContainer
Per-container module definition.
Multiple modules can contribute to this option. Each contribution is a module that will be evaluated for every container with container-specific context.
The module receives these special arguments:
name: the attribute name of the container (from types.attrsOf)config: the container’s config (for reading within the module)globalConfig: the top-level flake configperSystemConfig: the perSystem configsystem: the current systempkgs: nixpkgs for current systemlib: nixpkgs lib
Type: per-container module
Default:
{ }
Declared by:
perSystem.oci.perContainer.package
The main package for the container.
Type: null or package
Default:
null
Example:
pkgs.hello
Declared by:
perSystem.oci.perContainer.autoLabels
Whether to automatically generate OCI image labels from package metadata.
When enabled, the following labels are generated (user labels always override):
- OCI standard annotations (
org.opencontainers.image.*): title, version, description, licenses, base.name - Build info (
io.github.dauliac.nix-oci.build.*): system, optimized-layers, reproducible - Hardening hints (
io.github.dauliac.nix-oci.hardening.*): security posture - Kubernetes PSS level (
io.github.dauliac.nix-oci.kubernetes.pod-security-standard)
Type: boolean
Default:
true
Declared by:
perSystem.oci.perContainer.compliance.trivy.enabled
Whether to enable CIS compliance checking with Trivy.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.compliance.trivy.report
Compliance report format: all for detailed results or summary for a condensed overview.
Type: one of “all”, “summary”
Default:
"summary"
Declared by:
perSystem.oci.perContainer.compliance.trivy.spec
The compliance spec to check against. See trivy image --help for built-in specs.
Type: string
Default:
"docker-cis-1.6.0"
Example:
"docker-cis-1.6.0"
Declared by:
perSystem.oci.perContainer.credentialsLeak.configPath
Path where global credentials leak check configuration files will be stored.
Type: absolute path
Default:
config.rootPath + "/credentials-leak/"
Declared by:
perSystem.oci.perContainer.credentialsLeak.trivy.enabled
Whether to enable credentials leak detection with Trivy.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.cve.configPath
Path where CVE scanner configuration files will be stored.
Type: absolute path
Default:
config.rootPath
Declared by:
perSystem.oci.perContainer.cve.grype.enabled
Whether to enable CVE scanning with Grype.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.cve.grype.config.enabled
Whether to enable Grype configuration file generation.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.cve.grype.config.rootPath
Path where Grype configuration files will be stored.
Type: absolute path
Default:
config.cve.configPath + "/grype/"
Declared by:
perSystem.oci.perContainer.cve.trivy.enabled
Whether to enable CVE scanning with Trivy.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.cve.trivy.ignore.extra
Additional CVE identifiers to ignore globally in Trivy scans.
Type: list of string
Default:
[ ]
Declared by:
perSystem.oci.perContainer.cve.trivy.ignore.fileEnabled
Whether to enable Trivy CVE ignore file generation.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.cve.trivy.ignore.rootPath
Path where Trivy CVE ignore files will be stored.
Type: absolute path
Default:
config.cve.configPath
Declared by:
perSystem.oci.perContainer.cve.vulnix.enabled
Whether to enable CVE scanning with vulnix.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.cve.vulnix.whitelist.enabled
Whether to enable vulnix whitelist file.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.cve.vulnix.whitelist.rootPath
Path where vulnix whitelist files will be stored.
Type: absolute path
Default:
config.cve.configPath + "/vulnix/"
Declared by:
perSystem.oci.perContainer.declaredVolumes
OCI volume mount point declarations baked into the image manifest. These tell the container runtime which paths contain persistent data.
For NixOS containers, auto-derived from systemd service directories:
- StateDirectory → /var/lib/<dir>
- RuntimeDirectory → /run/<dir>
- CacheDirectory → /var/cache/<dir>
- LogsDirectory → /var/log/<dir>
This is separate from deploy-time volumes (host bind mounts).
Type: list of string
Default: Auto-derived from systemd service directories:
StateDirectory→/var/lib/<dir>RuntimeDirectory→/run/<dir>CacheDirectory→/var/cache/<dir>LogsDirectory→/var/log/<dir>
Example:
[
"/var/lib/postgresql"
"/var/log/nginx"
]
Declared by:
perSystem.oci.perContainer.dependencies
Additional dependencies packages to include in the container.
Type: list of package
Default:
[ ]
Example:
[ pkgs.bash pkgs.coreutils ]
Declared by:
perSystem.oci.perContainer.entrypoint
OCI entrypoint (command + arguments).
Full container example:
{ pkgs, ... }:
{
package = pkgs.python3;
entrypoint = [
"${pkgs.python3}/bin/python3"
"-m"
"http.server"
"8080"
];
}
Type: list of string
Default:
[ ]
Example:
[
"/bin/hello"
"--greeting"
"world"
]
Declared by:
perSystem.oci.perContainer.environment
Environment variables baked into the OCI manifest and passed to the runner.
Type: attribute set of string
Default:
{ }
Example:
{
RUST_LOG = "info";
}
Declared by:
perSystem.oci.perContainer.gid
GID for the non-root container user’s primary group.
Only used when isRoot = false. The default (4000) matches
the default UID to keep user/group mapping simple.
Type: signed integer
Default:
4000
Example:
1000
Declared by:
perSystem.oci.perContainer.gpu.enable
Enable NVIDIA GPU support for this container.
When enabled, sets environment variables that trigger the NVIDIA
Container Toolkit runtime injection (NVIDIA_VISIBLE_DEVICES,
NVIDIA_DRIVER_CAPABILITIES) and includes CUDA runtime libraries
from nixpkgs in the container image.
Compatible with the NVIDIA GPU Operator in Kubernetes – images built with this option work with both legacy (env-var) and CDI (Container Device Interface) injection modes.
Driver libraries (libcuda.so, libnvidia-ml.so, nvidia-smi)
are NOT bundled – they are always injected at runtime by the
host’s NVIDIA Container Toolkit.
Requires nixpkgs.config.cudaSupport = true and
nixpkgs.config.allowUnfree = true in the consuming flake.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.gpu.capabilities
NVIDIA driver capabilities to request at runtime.
Each capability controls which host driver libraries the NVIDIA Container Toolkit bind-mounts into the container:
"compute"– CUDA and OpenCL libraries."utility"– Management tools (nvidia-smi,libnvidia-ml.so)."graphics"– OpenGL, EGL, Vulkan, OptiX libraries."video"– Hardware video codec libraries (NVENC/NVDEC)."display"– X11 display output libraries."all"– All capabilities above.
Default: ["compute" "utility"] (CUDA compute + nvidia-smi).
Type: list of (one of “compute”, “utility”, “graphics”, “video”, “display”, “all”)
Default:
[
"compute"
"utility"
]
Declared by:
perSystem.oci.perContainer.gpu.cudaVersion
Minimum CUDA version constraint.
When set, the NVIDIA_REQUIRE_CUDA environment variable is
added to the image config (e.g. cuda>=12.2). The NVIDIA
Container Toolkit validates this against the host driver before
allowing the container to start.
When null (default), the version is auto-detected from the
cudaPackages in nixpkgs.
Type: null or string
Default:
null
Example:
"12.2"
Declared by:
perSystem.oci.perContainer.gpu.forwardCompat
Include CUDA forward compatibility libraries in the image.
When enabled, the cuda-compat package is added and
LD_LIBRARY_PATH is configured so compat libraries take
precedence over the host-injected driver libraries.
This allows the container to use a newer CUDA toolkit than the host driver natively supports. Useful when deploying to clusters where driver upgrades are infrequent.
Not all features are forward-compatible – some require kernel-mode driver support for new hardware capabilities.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.gpu.runtimeLibraries
CUDA toolkit libraries to include in the container image.
"cudart"– CUDA runtime (libcudart.so). Almost always needed."cublas"– cuBLAS linear algebra."cufft"– cuFFT Fourier transforms."curand"– cuRAND random number generation."cusolver"– cuSOLVER dense/sparse solvers."cusparse"– cuSPARSE sparse matrix operations."cudnn"– cuDNN deep learning primitives."tensorrt"– TensorRT inference optimization."nccl"– NCCL multi-GPU/node communication."cutlass"– CUTLASS GEMM templates."nvjpeg"– nvJPEG hardware JPEG decoding.
Only selected libraries are included to minimize image size.
Driver libraries (libcuda.so) are never bundled.
Type: list of (one of “cudart”, “cublas”, “cufft”, “curand”, “cusolver”, “cusparse”, “cudnn”, “tensorrt”, “nccl”, “cutlass”, “nvjpeg”)
Default:
[
"cudart"
]
Example:
[
"cudart"
"cublas"
"cudnn"
]
Declared by:
perSystem.oci.perContainer.hardening.enable
Enable container security hardening.
When enabled, applies build-time filesystem restrictions and generates runtime security hints consumed by deploy modules.
Three independent kernel primitives are available:
- Seccomp – syscall filtering (BPF at the syscall boundary)
- AppArmor – mandatory access control (LSM pathname-based)
- Capabilities + flags – privilege restriction at runtime
For containers using nixosConfig, these options are forwarded
to the inner NixOS module at oci.container.hardening and can
be overridden through NixOS module composition.
Full container example:
{
package = pkgs.busybox;
isRoot = true;
hardening = {
enable = true;
disableDns = true;
noTlsTrustStore = true;
seccomp = {
enable = true;
profile = "strict";
};
capabilities = {
drop = [ "ALL" ];
add = [ "NET_BIND_SERVICE" ];
};
readOnlyRootfs = true;
noNewPrivileges = true;
};
}
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.hardening.apparmor
AppArmor MAC profile configuration.
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.perContainer.hardening.apparmor.enable
Enable AppArmor profile generation for this container.
When enabled, a tailored AppArmor profile is generated as a
build output. The deploy module references it via
--security-opt apparmor=<profile>.
Requires the target host to have AppArmor enabled
(kernel LSM + apparmor_parser). On NixOS, set
security.apparmor.enable = true.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.hardening.apparmor.customProfile
Path to a custom AppArmor profile file. When set, overrides ALL computed profile rules. The profile must be a valid AppArmor profile file.
Note: cross-backend coherence checks cannot verify custom profiles — you take full responsibility for correctness.
Type: null or absolute path
Default:
null
Declared by:
perSystem.oci.perContainer.hardening.apparmor.denyMount
Deny mount operations inside the container.
Prevents filesystem remounting, overlay stacking, and
bind-mount escape attacks. Enforced via AppArmor
deny mount, rule.
Type: boolean
Default:
true
Declared by:
perSystem.oci.perContainer.hardening.apparmor.denyPtrace
Deny ptrace of other processes.
Prevents process inspection and memory manipulation attacks.
Enforced via AppArmor deny ptrace (read, read, trace, traceby),
rule.
Type: boolean
Default:
true
Declared by:
perSystem.oci.perContainer.hardening.apparmor.denyUserNamespace
Deny user namespace creation inside the container.
Prevents the class of Local Privilege Escalation (LPE) vulnerabilities where unprivileged processes exploit userns to reach normally-root-only kernel code paths (CVE-2023-2640, CVE-2023-32629, etc.).
Enforced via AppArmor deny userns_create, rule.
Complementary to seccomp clone(CLONE_NEWUSER) arg filter
and capability drop SYS_ADMIN.
Type: boolean
Default:
true
Declared by:
perSystem.oci.perContainer.hardening.apparmor.mode
AppArmor enforcement mode:
"enforce"– violations are blocked and logged (default). Use for production."complain"– violations are logged but NOT blocked. Useful for profile discovery before switching to enforce.
Type: one of “enforce”, “complain”
Default:
"enforce"
Declared by:
perSystem.oci.perContainer.hardening.capabilities
Linux capability restrictions applied at runtime by deploy modules.
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.perContainer.hardening.capabilities.add
Linux capabilities to add back after dropping.
Deploy modules translate to --cap-add.
Type: list of string
Default:
[ ]
Example:
[
"NET_BIND_SERVICE"
]
Declared by:
perSystem.oci.perContainer.hardening.capabilities.drop
Linux capabilities to drop. Defaults to ["ALL"].
Deploy modules translate to --cap-drop.
Type: list of string
Default:
[
"ALL"
]
Declared by:
perSystem.oci.perContainer.hardening.disableDns
Disable DNS resolution inside the container.
Sets /etc/nsswitch.conf hosts line to files only (no dns
backend). Applications using IP addresses directly are unaffected.
NOTE: /etc/resolv.conf is NOT written into the image because
container runtimes (Docker, Podman) always bind-mount it at
startup, masking any baked-in content. To fully enforce DNS
restriction at runtime, use --dns=127.0.0.1 or network
policies.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.hardening.noNewPrivileges
Set the no_new_privs bit. Prevents privilege escalation
via setuid/setgid binaries or file capabilities.
Deploy modules translate to
--security-opt=no-new-privileges.
Type: boolean
Default:
true
Declared by:
perSystem.oci.perContainer.hardening.noTlsTrustStore
Remove the TLS certificate trust store (/etc/ssl/certs).
Prevents all outgoing HTTPS connections.
Only use for containers that never initiate TLS connections. This is a nuclear option – most applications that make any outbound HTTP requests will break.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.hardening.readOnlyRootfs
Mount the container root filesystem as read-only at runtime.
Deploy modules translate to --read-only.
Prevents attackers from writing malware or achieving persistence if they gain initial access.
Type: boolean
Default:
true
Declared by:
perSystem.oci.perContainer.hardening.seccomp
Seccomp syscall filtering configuration.
Full container example:
{
package = pkgs.busybox;
hardening = {
enable = true;
seccomp = {
enable = true;
profile = "web-server";
mode = "enforce";
};
};
}
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.perContainer.hardening.seccomp.enable
Enable a custom seccomp profile for this container.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.hardening.seccomp.customProfileJson
Path to a custom seccomp profile JSON file following the
OCI runtime specification format. When set, overrides
the profile option.
Type: null or absolute path
Default:
null
Declared by:
perSystem.oci.perContainer.hardening.seccomp.mode
Seccomp enforcement mode:
"enforce"– block disallowed syscalls with SCMP_ACT_ERRNO (default)."audit"– log disallowed syscalls with SCMP_ACT_LOG but allow them. Useful for profile discovery and testing before switching to enforce.
Type: one of “enforce”, “audit”
Default:
"enforce"
Declared by:
perSystem.oci.perContainer.hardening.seccomp.profile
Predefined seccomp profile level:
-
"strict"– allowlist of ~60 syscalls. Suitable for static binaries, Go/Rust services. Blocksmount,ptrace,execve, and most process/namespace ops. -
"moderate"– blocks ~50 dangerous syscalls including io_uring and memfd_create. All profiles include argument-level filtering for clone (block namespace creation), socket (block AF_NETLINK/AF_PACKET), and ioctl (block TIOCSTI/TIOCLINUX terminal injection). -
"web-server"– strict base plus networking and threading syscalls. Suitable for HTTP servers. -
"database"– web-server base plus memory management syscalls (fadvise64, msync, mincore). Suitable for PostgreSQL, Redis, and similar services. -
"gpu-compute"– web-server base plus CUDA/GPU syscalls (perf_event_open, memfd_create, NUMA memory policy). Relaxes ioctl filtering for GPU command submission. Auto-selected whengpu.enable = true.
In the inner NixOS module, the profile auto-defaults to
"gpu-compute" when GPU is enabled, "web-server" when
a known web server is detected, and "database" when
PostgreSQL or Redis is detected.
Type: one of “strict”, “moderate”, “web-server”, “database”, “gpu-compute”
Default:
"moderate"
Declared by:
perSystem.oci.perContainer.healthcheck.command
Health check command (CMD form).
When non-empty, baked into the OCI image as Healthcheck.Test.
For NixOS-based containers, service adapters can auto-derive this from the NixOS module configuration (ports, endpoints, etc.).
Example: [ "curl" "-f" "http://localhost:8080/health" ]
Full container example:
{
package = pkgs.python3;
dependencies = [ pkgs.curl ];
entrypoint = [
"${pkgs.python3}/bin/python3"
"-m"
"http.server"
"8080"
];
ports = [ "8080:8080" ];
healthcheck = {
command = [
"${pkgs.curl}/bin/curl"
"-f"
"http://localhost:8080/"
];
interval = 15;
timeout = 3;
startPeriod = 5;
retries = 3;
};
}
Type: list of string
Default: Auto-derived by service adapters when available:
- nginx:
curlstub_status or/healthendpoint - caddy:
curladmin API (localhost:2019) - PostgreSQL:
pg_isready - Redis:
redis-cli ping - BIND/dnsmasq:
digDNS query - Postfix:
postfix status
Example:
[
"curl"
"-f"
"http://localhost:8080/health"
]
Declared by:
perSystem.oci.perContainer.healthcheck.interval
Seconds between health checks.
Type: signed integer
Default:
30
Declared by:
perSystem.oci.perContainer.healthcheck.retries
Number of consecutive failures before the container is considered unhealthy.
Type: signed integer
Default:
3
Declared by:
perSystem.oci.perContainer.healthcheck.startPeriod
Grace period (seconds) before the first health check runs after container start.
Type: signed integer
Default:
5
Declared by:
perSystem.oci.perContainer.healthcheck.timeout
Seconds to wait for a single health check to complete.
Type: signed integer
Default:
5
Declared by:
perSystem.oci.perContainer.homeManager.flake
The home-manager flake input. When set, enables home-manager integration for this container.
Example:
oci.containers.dev = {
homeManager.flake = inputs.home-manager;
homeManager.modules = [{ home.packages = [ pkgs.vim ]; }];
};
Type: null or unspecified value
Default:
null
Example:
"inputs.home-manager"
Declared by:
perSystem.oci.perContainer.homeManager.modules
Home-manager modules for the container user’s home directory.
These configure dotfiles, shell, git, editor, etc. Requires
homeManager.flake to be set.
Type: list of unspecified value
Default:
[ ]
Declared by:
perSystem.oci.perContainer.initializeNixDatabase
Populate the Nix database (/nix/var/nix/db/db.sqlite) with the
closure of all store paths shipped in the image.
Enable this when you need to run Nix commands (nix build,
nix eval, nix-store -q, …) inside the container. Without it,
the Nix store directory contains packages but the database is empty,
causing Nix to believe no packages are installed.
Disabled by default because copyToRoot flattens store paths to /,
creating phantom database entries for the flattened derivations.
This is harmless for in-container Nix usage but may confuse workflows
that validate database-vs-disk consistency.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.isRoot
Whether the container process runs as root.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.labels
OCI image labels (metadata key-value pairs).
Full container example:
{
package = pkgs.hello;
labels = {
"org.opencontainers.image.title" = "my-app";
"org.opencontainers.image.version" = "1.0.0";
"org.opencontainers.image.description" = "My containerized application";
};
}
Type: attribute set of string
Default:
{ }
Example:
{
"org.opencontainers.image.title" = "my-app";
"org.opencontainers.image.version" = "1.0.0";
}
Declared by:
perSystem.oci.perContainer.layerStrategy
Controls how nix2container splits store paths into sub-layers.
Only effective when optimizeLayers is true.
-
"minimal": exactly one layer per concern (deps, app). Produces 2 total layers. Most predictable cache behaviour – adding or removing a dependency only invalidates the deps layer. Best for projects with few images where cross-image sharing is not a priority. -
"fine-grained": each logical layer is further split using nix2container’s store-path popularity algorithm. The deps layer gets up to 80 sub-layers, andbuildImagesplits remaining paths into up to 40. Foundational packages (glibc, openssl) get their own sub-layers and are shared byte-for-byte across images in the same registry. Best for registries hosting many images with overlapping dependencies.
Type: one of “minimal”, “fine-grained”
Default:
"fine-grained"
Example:
"minimal"
Declared by:
perSystem.oci.perContainer.license.conftest.enabled
Whether to enable SBOM license compliance checking with Conftest.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.license.conftest.extraPolicyDirs
Additional directories containing Rego policy files for license checking. These are merged WITH the built-in license policies.
Type: list of absolute path
Default:
[ ]
Example:
[ ./my-license-policies ]
Declared by:
perSystem.oci.perContainer.license.conftest.namespaces
Rego namespaces to check. Each namespace maps to a package declaration in the license policy files.
Type: list of string
Default:
[
"license"
]
Example:
[
"license"
"custom_license"
]
Declared by:
perSystem.oci.perContainer.license.conftest.policyDir
Path to a directory containing Rego policy files for license checking.
Policies receive a CycloneDX SBOM JSON as input and should define
deny or warn rules in the license package. nix-oci ships
built-in policies that reject common forbidden licenses (AGPL, SSPL)
and warn on copyleft licenses (GPL, LGPL).
Type: absolute path
Default:
built-in nix-oci license policies
Declared by:
perSystem.oci.perContainer.lint.dockle.enabled
Whether to enable container image linting with Dockle.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.lint.dockle.exitLevel
Minimum severity level that causes a non-zero exit code.
Type: one of “info”, “warn”, “fatal”
Default:
"info"
Declared by:
perSystem.oci.perContainer.lint.dockle.ignore
List of Dockle checkpoint IDs to ignore (e.g. CIS-DI-0001).
Type: list of string
Default:
[
"CIS-DI-0005"
"CIS-DI-0006"
]
Example:
[
"CIS-DI-0001"
"DKL-DI-0006"
]
Declared by:
perSystem.oci.perContainer.mainService
Logical NixOS service name to extract container metadata from.
When set, nix-oci automatically derives:
- Entrypoint from the systemd
ExecStart - Stop signal from the systemd
KillSignalor service adapter - Working directory from
WorkingDirectoryor servicedataDir - Health check from the service adapter (curl, pg_isready, etc.)
- Volumes from
StateDirectory,RuntimeDirectory, etc.
For most services, this matches the NixOS option prefix
(e.g. "nginx" for services.nginx). For multi-instance services
(e.g. Redis), the service adapter resolves the actual systemd
unit name automatically.
Requires nixosConfig.modules to include the service configuration.
Type: null or string
Default:
null
Example:
"nginx"
Declared by:
perSystem.oci.perContainer.name
OCI image name. Defaults to the container attribute name.
Type: string
Default:
"‹name›"
Example:
"my-custom-image"
Declared by:
perSystem.oci.perContainer.optimizeLayers
Split container contents into deduplicated layers for optimal registry caching. Uses a two-level heuristic:
Level 1 – popularity-based splitting. Within each layer,
nix2container’s store-path popularity algorithm sorts paths by
how many other paths reference them. Foundational packages
(glibc, openssl, …) get their own sub-layers; application-specific
paths cluster together. Capped by a maxLayers budget per layer.
Level 2 – fold-based cross-layer deduplication. Layers are built in a chain where each layer references all predecessors. nix2container excludes any store path already present in an earlier layer, eliminating duplication across explicit layers.
The resulting layer stack (most stable first):
- Deps layer (runtime libraries,
maxLayers = 80when fine-grained) - App layer (package, shadow, configs)
Use layerStrategy to control sub-splitting granularity:
"fine-grained" (default) for maximum cross-image sharing,
"minimal" for exactly one layer per concern.
See Nix and layered Docker images for the original algorithm and nix2container for the implementation used here.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.performance.enable
Enable container performance tuning.
When enabled, applies build-time optimizations (allocator injection, glibc tunables, CPU-targeted libraries) and generates runtime hints consumed by deploy modules.
Three independent optimization axes are available:
- Allocator – replace glibc ptmalloc2 with mimalloc/tcmalloc via
LD_PRELOAD - glibc tunables – tune malloc arenas, tcache, mmap thresholds
- hwcaps – ship CPU-optimized library variants (glibc-hwcaps, per-arch)
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.performance.allocator
Alternative memory allocator injected via LD_PRELOAD.
-
"mimalloc"– Microsoft’s general-purpose allocator. Lowest RSS for small allocations, excellent for microservices. Works on musl. -
"tcmalloc"– Google’s per-CPU-cache allocator. Best throughput for large allocation patterns and high-concurrency servers. Requires glibc (does not work on musl). -
"jemalloc"– Facebook’s allocator used by Redis and Firefox. Best fragmentation resistance and P99 latency for long-running servers. Requires glibc (segfaults on musl).Warning: jemalloc uses
MADV_FREEby default, which inflates cgroup RSS accounting. The module automatically setsmuzzy_decay_ms:0unless overridden viaallocatorConfig. -
"snmalloc"– Microsoft Research lock-free allocator. Excellent for high cross-thread deallocation patterns (request/response servers where allocating thread differs from freeing thread). -
null– use glibc’s default ptmalloc2 (no injection).
The allocator library is added as a container dependency and
LD_PRELOAD is set in the OCI manifest Env.
Type: null or one of “mimalloc”, “tcmalloc”, “jemalloc”, “snmalloc”
Default:
null
Example:
"jemalloc"
Declared by:
perSystem.oci.perContainer.performance.allocatorConfig
Allocator-specific tuning parameters.
Keys and values depend on the selected performance.allocator:
mimalloc – keys become MIMALLOC_<KEY> environment variables:
PURGE_DELAY="100"– ms before purging unused pagesPURGE_DECOMMITS="1"– use MADV_DONTNEED (cgroup-accurate RSS)ARENA_EAGER_COMMIT="0"– lazy commit for memory-constrainedALLOW_LARGE_OS_PAGES="1"– use 2MB huge pages
tcmalloc – keys become TCMALLOC_<KEY> environment variables:
AGGRESSIVE_DECOMMIT="true"– aggressively return memory to OSMAX_TOTAL_THREAD_CACHE_BYTES="8388608"– 8MB thread cache capRELEASE_RATE="10.0"– OS memory return rate
jemalloc – keys are colon-joined into MALLOC_CONF:
narenas="2"– limit arenas (default: 4*ncpus)dirty_decay_ms="5000"– dirty page purge timingmuzzy_decay_ms="0"– skip MADV_FREE (critical for cgroups)background_thread="true"– offload purgingretain="false"– actually munmap under cgroup limitsmetadata_thp="auto"– THP for jemalloc metadata
snmalloc – no runtime tunables (configured at compile time).
When the selected allocator is null, this option is ignored.
Type: attribute set of string
Default:
{ }
Example:
{
background_thread = "true";
dirty_decay_ms = "5000";
muzzy_decay_ms = "0";
narenas = "2";
}
Declared by:
perSystem.oci.perContainer.performance.compression
Compression algorithm for OCI image layers during transport (skopeo).
"gzip"– universal compatibility, slower."zstd"– 3-5x faster compress/decompress, 12% smaller. Requires OCI 1.1+ registry (Docker Hub, ECR, GCR, GHCR support it). containerd 2.0+ required; containerd 1.7.x does NOT support zstd."gzip:estargz"– eStargz format for lazy pulling with stargz-snapshotter. Requiresperformance.turbo.enable = true. Cannot be combined with SOCI (performance.turbo.soci).
Type: one of “gzip”, “zstd”, “gzip:estargz”
Default:
"gzip"
Example:
"zstd"
Declared by:
perSystem.oci.perContainer.performance.glibcTunables
glibc tunables set via the GLIBC_TUNABLES environment variable.
Keys are tunable names (e.g. glibc.malloc.arena_max), values
are strings. Multiple tunables are colon-joined automatically.
Recommended for containers:
glibc.malloc.arena_max = "2"– cap malloc arenas to reduce RSSglibc.malloc.mmap_threshold = "131072"– reduce fragmentationglibc.malloc.tcache_count = "7"– tune per-thread cache
Only effective with glibc-based containers (not musl).
Type: attribute set of string
Default:
{ }
Example:
{
"glibc.malloc.arena_max" = "2";
}
Declared by:
perSystem.oci.perContainer.performance.glibcTunablesPreset
Curated glibc tunables preset for common container workloads.
Presets set glibcTunables values via mkDefault – explicit
glibcTunables entries always take precedence.
-
"memory-constrained"– for containers with <512MB memory limit. Aggressively reduces arena count and malloc overhead:arena_max=2, trim_threshold=32768, top_pad=0, mmap_threshold=65536, tcache_count=3 -
"high-throughput"– for CPU-bound servers with ample memory. Maximizes allocation throughput:arena_max=8, tcache_count=15, mxfast=256 -
"balanced"– safe defaults for general-purpose containers. Moderate arena count with sensible thresholds:arena_max=4, trim_threshold=131072, mmap_threshold=131072, tcache_count=7 -
null– no preset (only explicitglibcTunablesapply).
Only effective with glibc-based containers (not musl).
Type: null or one of “memory-constrained”, “high-throughput”, “balanced”
Default:
null
Example:
"balanced"
Declared by:
perSystem.oci.perContainer.performance.hugePages
Huge page configuration for reduced TLB misses and lower page walk latency.
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.perContainer.performance.hugePages.glibcHugetlb
glibc malloc.hugetlb tunable value.
0– disabled (default).1– useMADV_HUGEPAGEafter mmap.2– useMAP_HUGETLBdirectly (requires hugetlbfs).
Type: null or one of 0, 1, 2
Default:
null
Example:
1
Declared by:
perSystem.oci.perContainer.performance.hugePages.thpMode
Transparent Huge Pages mode hint. Sets glibc.malloc.hugetlb
tunable and generates an OCI label for host configuration.
"madvise"– recommended for containers."always"– aggressive, can cause compaction latency spikes.null– no THP hint (host default applies).
Type: null or one of “madvise”, “always”
Default:
null
Example:
"madvise"
Declared by:
perSystem.oci.perContainer.performance.hwcaps
glibc-hwcaps: ship CPU-optimized library variants selected at runtime.
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.perContainer.performance.hwcaps.enable
Build and ship CPU-optimized library variants via glibc-hwcaps.
The dynamic linker selects the best variant at process startup based on CPUID – zero application changes required.
Only effective on systems with hwcaps support (x86_64-linux). Auto-disabled on unsupported architectures in per-arch config.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.performance.hwcaps.levels
Microarchitecture levels to build optimized libraries for. Valid values depend on the target system:
- x86_64-linux:
"x86-64-v2","x86-64-v3","x86-64-v4"
The baseline is always included as fallback (not listed here).
Type: list of string
Default:
[ ]
Example:
[
"x86-64-v3"
]
Declared by:
perSystem.oci.perContainer.performance.hwcaps.libraries
Packages whose shared libraries to rebuild at each hwcaps level.
Only .so files are extracted into the hwcaps layer.
Good candidates: crypto (openssl), compression (zlib, zstd), math-heavy libraries, string processing.
Type: list of package
Default:
[ ]
Example:
[ pkgs.openssl pkgs.zlib ]
Declared by:
perSystem.oci.perContainer.performance.startup
Container process startup optimization.
Type: submodule
Default:
{ }
Declared by:
perSystem.oci.perContainer.performance.startup.ldSoCache
Run ldconfig at image build time to pre-build
/etc/ld.so.cache with all library paths.
Eliminates filesystem search at process startup. Beneficial for containers with many shared libraries.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.performance.startup.stackSize
Default thread stack size override. Set via ulimit -s in
the container entrypoint.
Reducing from the default 8MB to 512KB-2MB saves significant virtual memory for containers with many threads.
Format: size in KB (e.g. "512" for 512KB, "2048" for 2MB).
Type: null or string
Default:
null
Example:
"512"
Declared by:
perSystem.oci.perContainer.performance.turbo.enable
Use nix2container-turbo patched skopeo for image pushes.
Enables cross-machine layer caching via OCI Referrers API: layer mappings (nix store hash → compressed digest) are stored in the registry so any machine can skip re-compressing and re-uploading unchanged layers. Repushes become sub-second regardless of image size.
Requires an OCI registry supporting the Referrers API (ECR, GHCR, Docker Hub, and most modern registries).
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.performance.turbo.layerCache
Enable cross-machine layer caching via OCI Referrers API.
Stores nix store path → compressed layer mappings as referrer manifests in the registry. Subsequent pushes from any machine look up these mappings and skip re-compression and re-upload for unchanged layers.
Achieves sub-second repush times regardless of image size.
Enabled by default when performance.turbo.enable = true.
Requires an OCI registry supporting the Referrers API.
Type: boolean
Default:
true
Example:
true
Declared by:
perSystem.oci.perContainer.performance.turbo.soci
Generate SOCI v2 indexes during push for lazy pulling.
When enabled, the turbo-patched skopeo generates zTOC (table of contents) for each layer during push and bundles them into a SOCI v2 index manifest alongside the image in an OCI Index.
Reduces cold-start times significantly for large images on AWS ECS/Fargate (~53s → ~20s for a 1GB image).
Requires performance.turbo.enable = true and gzip compression
(SOCI does not support zstd). eStargz and SOCI cannot be combined.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.performance.turbo.sociSpanSize
SOCI span size in bytes for zTOC checkpoint granularity.
Controls how often deflate checkpoints are inserted in the compressed layer data. Smaller values allow more precise random-access seeking (faster individual file access) at the cost of a larger zTOC index.
4194304(4 MiB) – default, good balance for most workloads.1048576(1 MiB) – finer granularity, better for many small files.8388608(8 MiB) – coarser, smaller index, better for large files.
Only effective when performance.turbo.soci = true.
Type: signed integer
Default:
4194304
Example:
4194304
Declared by:
perSystem.oci.perContainer.policy.conftest.enabled
Whether to enable OCI image config policy checking with Conftest.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.policy.conftest.extraPolicyDirs
Additional directories containing Rego policy files. These are merged WITH the built-in policies.
Type: list of absolute path
Default:
[ ]
Example:
[ ./my-policies ./team-policies ]
Declared by:
perSystem.oci.perContainer.policy.conftest.namespaces
Rego namespaces to check. Each namespace maps to a package declaration in the policy files.
Type: list of string
Default:
[
"main"
]
Example:
[
"main"
"custom"
]
Declared by:
perSystem.oci.perContainer.policy.conftest.policyDir
Path to a directory containing Rego policy files for Conftest.
Policies receive the OCI image config JSON as input and should
define deny or warn rules. nix-oci ships built-in policies
that check for common security issues (root user, leaked secrets
in env vars, missing labels).
Type: absolute path
Default:
built-in nix-oci OCI policies
Declared by:
perSystem.oci.perContainer.ports
Port mappings (e.g. ["8080:8080"]).
Baked into OCI manifest ExposedPorts and used by the runner service.
Full container example:
{
package = pkgs.python3;
entrypoint = [
"${pkgs.python3}/bin/python3"
"-m"
"http.server"
"8080"
];
ports = [ "8080:8080" ];
}
Type: list of string
Default:
[ ]
Example:
[
"8080:8080"
"443:443"
]
Declared by:
perSystem.oci.perContainer.registry
The OCI registry to use for pushing and pulling images.
Type: null or string
Default:
null
Declared by:
perSystem.oci.perContainer.rootPath
The root path to store the Nix OCI resources.
Type: absolute path
Default:
self + "/oci/"
Declared by:
perSystem.oci.perContainer.sbom.path
Path where SBOM files will be stored.
Type: absolute path
Default:
config.rootPath
Declared by:
perSystem.oci.perContainer.sbom.syft.enabled
Whether to enable SBOM generation with Syft.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.sbom.syft.config.enabled
Whether to enable Syft configuration file generation.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.sbom.syft.config.rootPath
Path where Syft configuration files will be stored.
Type: absolute path
Default:
config.sbom.path
Declared by:
perSystem.oci.perContainer.signing.cosign.enabled
Whether to enable OCI image signing with cosign.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.perContainer.signing.cosign.annotations
Key-value annotations to attach to every cosign signature.
These appear in cosign verify output and can be used
for policy enforcement (e.g. with Kyverno or OPA).
Type: attribute set of string
Default:
{ }
Example:
{
build-system = "nix";
repo = "https://github.com/example/repo";
}
Declared by:
perSystem.oci.perContainer.signing.cosign.certificateIdentityRegexp
Regular expression to match the certificate identity when
verifying keyless signatures. Required for keyless verification.
Example: "https://github.com/myorg/.*" or an email pattern.
Type: null or string
Default:
null
Declared by:
perSystem.oci.perContainer.signing.cosign.certificateOidcIssuerRegexp
Regular expression to match the OIDC issuer when verifying
keyless signatures. Required for keyless verification.
Example: "https://token.actions.githubusercontent.com".
Type: null or string
Default:
null
Declared by:
perSystem.oci.perContainer.signing.cosign.key
Path or KMS URI for the cosign signing key. Supports local files, environment variables, and KMS URIs:
- Local file:
./cosign.key - Environment variable:
env://COSIGN_PRIVATE_KEY - AWS KMS:
awskms://[ENDPOINT]/[ID/ALIAS/ARN] - GCP KMS:
gcpkms://projects/[PROJECT]/locations/[LOC]/keyRings/[RING]/cryptoKeys/[KEY] - Azure Key Vault:
azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - HashCorp Vault:
hashivault://[KEY]Only used whenkeylessis false.
Type: null or string
Default:
null
Declared by:
perSystem.oci.perContainer.signing.cosign.keyEnvVar
Environment variable consulted at runtime for the cosign key
path or URI. When set in the environment, its value is used as
--key <value>, overriding the Nix-configured key option.
Set to null to disable runtime override and always use the
Nix-configured key value.
Only relevant when keyless is false.
The default "COSIGN_KEY" matches cosign’s own convention.
Common patterns:
COSIGN_KEY=./cosign.key— local fileCOSIGN_KEY=env://COSIGN_PRIVATE_KEY— key content in another env varCOSIGN_KEY=awskms://...— KMS URI
Type: null or string
Default:
"COSIGN_KEY"
Declared by:
perSystem.oci.perContainer.signing.cosign.keyless
Use keyless (OIDC) signing via Sigstore Fulcio.
When true, cosign authenticates via an OIDC provider
(GitHub Actions, Google, Microsoft) and issues ephemeral
certificates. No key management required.
When false, key must be set.
Type: boolean
Default:
true
Declared by:
perSystem.oci.perContainer.signing.cosign.verify
Whether to verify the signature immediately after signing.
Type: boolean
Default:
true
Declared by:
perSystem.oci.perContainer.stopSignal
Signal to send for graceful container shutdown (e.g., “SIGQUIT”, “SIGINT”). When null, auto-derived for NixOS containers from the service adapter or systemd KillSignal. Falls back to the container runtime default (SIGTERM).
Type: null or string
Default: Auto-derived (strongest to weakest):
- service adapter signal (e.g.
SIGQUITfor nginx,SIGINTfor PostgreSQL) - systemd
KillSignal - container runtime default (
SIGTERM)
Example:
"SIGQUIT"
Declared by:
perSystem.oci.perContainer.tag
OCI image tag.
Type: string
Default:
"latest"
Example:
"v1.0.0"
Declared by:
perSystem.oci.perContainer.test.amicontained.enabled
Whether to enable amicontained container introspection globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.test.cdk.enabled
Whether to enable CDK container security auditing globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.test.containerStructureTest.enabled
Whether to enable container-structure-test globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.test.deepce.enabled
Whether to enable DEEPCE container escape detection globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.test.dgoss.enabled
Whether to enable dgoss testing globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.test.dgoss.hermetic
Run dgoss as a pure Nix derivation (check) using podman.
Requires extra-sandbox-paths = /sys/fs/cgroup in nix.conf.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.test.dive.enabled
Whether to enable Dive analysis globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.test.linpeas.enabled
Whether to enable linPEAS privilege escalation auditing globally for all containers.
Type: boolean
Default:
false
Declared by:
perSystem.oci.perContainer.uid
UID for the non-root container user.
Only used when isRoot = false. The default (4000) avoids
conflicts with system UIDs (< 1000) and common application
UIDs while remaining within the standard UID range.
Type: signed integer
Default:
4000
Example:
1000
Declared by:
perSystem.oci.perContainer.user
User to run the container process as.
Full container example:
{ pkgs, ... }:
{
package = pkgs.hello;
user = "nobody";
}
Type: string
Default:
"root"
Example:
"nobody"
Declared by:
perSystem.oci.perContainer.workingDir
Working directory for the container process. When null, auto-derived for NixOS containers from (strongest to weakest):
- systemd WorkingDirectory
- service dataDir (e.g., /var/lib/postgresql for PostgreSQL)
- user home directory (/root or /home/<user>)
For non-NixOS containers, defaults to the user home directory.
Type: null or string
Default: Auto-derived (strongest to weakest):
- systemd
WorkingDirectory - service
dataDir(e.g./var/lib/postgresql) - user home directory (
/rootor/home/<user>)
Example:
"/var/lib/postgresql"
Declared by:
perSystem.oci.pipeline.defaultBackend
Default backend for probe-phase steps:
"vm"— probes run as NixOS VM derivations (build-time gate)."daemon"— probes run as scripts in the Taskfile (runtime).
Individual steps can override via oci.pipeline.steps.<name>.backend.
Type: one of “vm”, “daemon”
Default:
"vm"
Declared by:
perSystem.oci.pipeline.envVars.pushedTag
Stdout marker for pushed tag output.
Type: string
Default:
"NIX_OCI_PUSHED_TAG"
Declared by:
perSystem.oci.pipeline.envVars.registry
Env var name for the target registry.
Type: string
Default:
"NIX_OCI_REGISTRY"
Declared by:
perSystem.oci.pipeline.envVars.registryFallback
Fallback env var for registry (GitLab compat).
Type: string
Default:
"CI_REGISTRY_IMAGE"
Declared by:
perSystem.oci.pipeline.envVars.reportDir
Env var name for the report output directory.
Type: string
Default:
"NIX_OCI_REPORT_DIR"
Declared by:
perSystem.oci.pipeline.steps
Registry of pipeline steps contributed by tool lib.nix files.
Each step has: phase, category, backend, deps, isEnabled, mkStamp (for build-time gate), mkScript (for Taskfile).
Adding a new tool = one registration. The pipeline composer picks it up automatically.
Type: attribute set of (submodule)
Default:
{ }
Declared by:
perSystem.oci.pipeline.steps.<name>.backend
Execution backend override. When null, inferred from phase:
- build-check → pure
- probe → global oci.pipeline.defaultBackend
- pre-push/post-push → daemon
Type: null or one of “pure”, “vm”, “daemon”
Default:
null
Declared by:
perSystem.oci.pipeline.steps.<name>.category
Tool category for documentation and grouping.
Type: one of “policy”, “cve”, “lint”, “compliance”, “sbom”, “signing”, “structure”, “probe”, “license”, “push”, “credentials”
Declared by:
perSystem.oci.pipeline.steps.<name>.deps
Step names this step depends on (DAG ordering for Taskfile).
Type: list of string
Default:
[ ]
Declared by:
perSystem.oci.pipeline.steps.<name>.isEnabled
Function containerConfig → bool that determines whether this
step is active for a given container.
Type: function that evaluates to a(n) boolean
Declared by:
perSystem.oci.pipeline.steps.<name>.label
Custom output prefix for Taskfile (e.g. probe:cdk instead of probe-cdk).
Type: null or string
Default:
null
Declared by:
perSystem.oci.pipeline.steps.<name>.mkScript
For daemon backend: function { containerId, perSystemConfig } → package.
The package is a writeShellApplication added to the Taskfile.
Type: null or (function that evaluates to a(n) package)
Default:
null
Declared by:
perSystem.oci.pipeline.steps.<name>.mkStamp
For pure/vm backend: function { containerId, perSystemConfig } → derivation.
The derivation is a stamp (touch $out on success).
Added to the gate’s nativeBuildInputs.
Type: null or (function that evaluates to a(n) package)
Default:
null
Declared by:
perSystem.oci.pipeline.steps.<name>.parallel
Whether this step can run concurrently with siblings in the same phase.
Type: boolean
Default:
true
Declared by:
perSystem.oci.pipeline.steps.<name>.phase
Pipeline phase:
"build-check"— pure Nix derivation, no runtime needed (conftest, dockle, dive, sbom)."probe"— container introspection (amicontained, cdk, deepce, linpeas, cst, dgoss)."pre-push"— runs before push (load-image)."post-push"— runs after push (signing, compliance scans).
Type: one of “build-check”, “probe”, “pre-push”, “post-push”
Declared by:
perSystem.oci.pipeline.steps.<name>.timeout
Timeout in seconds for this step (Taskfile timeout field).
Type: signed integer
Default:
120
Declared by:
perSystem.oci.rootPath
The root path to store the Nix OCI resources.
Type: absolute path
Default:
self + "/oci/"
Declared by:
perSystem.oci.turbo.enable
Use nix2container-turbo patched skopeo for all container pushes.
Enables cross-machine layer caching via OCI Referrers API by default.
Per-container overrides: oci.containers.<name>.performance.turbo.enable.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.turbo.layerCache
Enable cross-machine layer caching via OCI Referrers API for all containers.
Per-container overrides: oci.containers.<name>.performance.turbo.layerCache.
Type: boolean
Default:
true
Example:
true
Declared by:
perSystem.oci.turbo.soci
Generate SOCI v2 indexes during push for all containers.
Enables lazy pulling on AWS ECS/Fargate and containerd with
soci-snapshotter.
Per-container overrides: oci.containers.<name>.performance.turbo.soci.
Type: boolean
Default:
false
Example:
true
Declared by:
perSystem.oci.turbo.sociSpanSize
Default SOCI span size in bytes for all containers.
Per-container overrides: oci.containers.<name>.performance.turbo.sociSpanSize.
Type: signed integer
Default:
4194304
Example:
4194304
Declared by:
perSystem.test.oci.perContainer
BDD test specs contributed by .test.nix files.
Outer key = option group (e.g. “hardening-seccomp”). Inner key = scenario name (e.g. “blocks-dangerous-syscalls”). Value = test spec with BDD metadata + assertions.
Type: attribute set of attribute set of (submodule)
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions
Assertions to verify after building/running the container.
Type: submodule
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.containerInspect
Expected podman inspect fields (dot-path notation).
Example: { "HostConfig.LogConfig.Type" = "passthrough"; }
Type: attribute set of raw value
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.fails
Commands that must fail (exit != 0) when run via
podman run --rm --entrypoint <command> <image>.
Used for testing seccomp blocks, capability drops, etc.
Optionally assert a specific exit code.
Type: list of (submodule)
Default:
[ ]
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.fails.*.args
Arguments passed to the command.
Type: string
Default:
""
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.fails.*.command
Binary to run as entrypoint.
Type: string
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.fails.*.exitCode
If set, assert this specific exit code. Otherwise any non-zero.
Type: null or signed integer
Default:
null
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.fileContains
Files in the image that must contain a string.
Uses podman create + cp to read from image layers directly
(bypasses runtime bind-mounts like resolv.conf).
Example: { "/etc/nsswitch.conf" = "files"; }
Type: attribute set of string
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.fileNotContains
Files in the image that must NOT contain a string.
Example: { "/etc/ssl/certs/ca-bundle.crt" = "BEGIN CERTIFICATE"; }
Type: attribute set of string
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.httpResponds
HTTP endpoint check with built-in wait/retry.
Uses wait_for_open_port + wait_until_succeeds + curl.
Type: null or (submodule)
Default:
null
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.httpResponds.contains
If set, assert response body contains this string.
Type: string
Default:
""
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.httpResponds.path
HTTP path to request.
Type: string
Default:
"/"
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.httpResponds.port
Port to check.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.imageConfig
Expected OCI image Config fields.
Checked via podman image inspect → .Config.<key>.
Example: { User = "nobody"; ExposedPorts."8080/tcp" = {}; }
Type: attribute set of raw value
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.labels
Expected OCI labels.
Checked via podman image inspect → .Labels.<key>.
Example: { "org.opencontainers.image.title" = "my-app"; }
Type: attribute set of string
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.processEnv
Expected process environment variables.
Read from /proc/1/environ inside the running container
(captures OCI-configured env vars that env may not show).
Example: { LD_PRELOAD = "jemalloc"; }
Type: attribute set of string
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.runtime
Raw Python test script (escape hatch). In the pytest
context, this becomes a standalone test function body
with client (docker SDK) available.
Type: strings concatenated with “\n”
Default:
""
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.succeeds
Commands that must succeed (exit 0) when run via
podman run --rm --entrypoint <command> <image>.
Optionally check stdout contains a string.
Type: list of (submodule)
Default:
[ ]
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.succeeds.*.args
Arguments passed to the command.
Type: string
Default:
""
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.succeeds.*.command
Binary to run as entrypoint.
Type: string
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.succeeds.*.stdout
If set, assert stdout contains this string.
Type: null or string
Default:
null
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.assertions.systemdProps
Expected systemd service properties.
Checked via systemctl show <service> --property=<keys>.
Example: { Type = "notify"; NotifyAccess = "all"; }
Type: attribute set of string
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.container
Container config for this BDD test scenario. Used by the new .test.nix BDD system.
Type: raw value
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.default
Container config using only defaults.
Tests that the option’s default value produces a valid container.
(Legacy _tests system — use container for new BDD specs.)
Type: raw value
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.exampleFile
Link to an examples/ file for documentation cross-reference.
Type: null or absolute path
Default:
null
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.given
BDD precondition / context (rendered in test coverage docs).
Type: string
Default:
""
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.level
Test depth — determines what kind of check is generated:
"eval"— container config evaluates without error (cheapest)."build"— OCI image builds successfully."inspect"— image metadata / file contents (VM, no container run)."runtime"— oneshotpodman run --rm, check output / exit code."deploy"— long-running daemon via systemd, check HTTP / env / lifecycle.
Type: one of “eval”, “build”, “inspect”, “runtime”, “deploy”
Default:
"eval"
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.mode
Container run mode (only relevant for runtime/deploy levels):
"oneshot"—podman run --rm, runs command and exits."daemon"— deployed via systemd, stays running for interaction.
Type: one of “oneshot”, “daemon”
Default:
"oneshot"
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.override
Container config with the example value applied.
Tests that overriding the option with its documented example works.
(Legacy _tests system — use container for new BDD specs.)
Type: raw value
Default:
{ }
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.target
Which test harness to use:
"oci"— flake-parts container (podman run)."nixos-oci"— NixOS container eval + systemd."home-manager-oci"— home-manager activation."deploy-nixos"— full NixOS deployment."deploy-home-manager"— home-manager deployment.
Type: one of “oci”, “nixos-oci”, “home-manager-oci”, “deploy-nixos”, “deploy-home-manager”
Default:
"oci"
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.testDependencies
Extra packages injected into the test container for testing purposes. These are NOT part of the option being tested — they are test harness dependencies (e.g., a C binary that probes io_uring for seccomp tests).
Type: list of package
Default:
[ ]
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.“then”
BDD expected outcome (rendered in test coverage docs).
Type: string
Default:
""
Declared by:
perSystem.test.oci.perContainer.<name>.<name>.when
BDD action or trigger (rendered in test coverage docs).
Type: string
Default:
""
Declared by: