diff --git a/doc/functions.xml b/doc/functions.xml
index 3b60f46d81da..96bd95958eae 100644
--- a/doc/functions.xml
+++ b/doc/functions.xml
@@ -20,4 +20,5 @@
+
diff --git a/doc/functions/ocitools.xml b/doc/functions/ocitools.xml
new file mode 100644
index 000000000000..4500c41a34ae
--- /dev/null
+++ b/doc/functions/ocitools.xml
@@ -0,0 +1,76 @@
+
+ pkgs.ociTools
+
+
+ pkgs.ociTools is a set of functions for creating
+ containers according to the
+ OCI
+ container specification v1.0.0. Beyond that it makes no assumptions
+ about the container runner you choose to use to run the created container.
+
+
+
+ buildContainer
+
+
+ This function creates a simple OCI container that runs a single command
+ inside of it. An OCI container consists of a config.json
+ and a rootfs directory.The nix store of the container will contain all
+ referenced dependencies of the given command.
+
+
+
+ The parameters of buildContainer with an example value
+ are described below:
+
+
+
+ Build Container
+
+buildContainer {
+ cmd = with pkgs; writeScript "run.sh" ''
+ #!${bash}/bin/bash
+ ${coreutils}/bin/exec ${bash}/bin/bash
+ '';
+
+ mounts = {
+ "/data" = {
+ type = "none";
+ source = "/var/lib/mydata";
+ options = [ "bind" ];
+ };
+ };
+
+ readonly = false;
+}
+
+
+
+
+
+ cmd specifies the program to run inside the container.
+ This is the only required argument for buildContainer.
+ All referenced packages inside the derivation will be made available
+ inside the container
+
+
+
+
+ mounts specifies additional mount points chosen by the
+ user. By default only a minimal set of necessary filesystems are mounted
+ into the container (e.g procfs, cgroupfs)
+
+
+
+
+ readonly makes the container's rootfs read-only if it is set to true.
+ The default value is false false.
+
+
+
+
+
+
diff --git a/pkgs/build-support/oci-tools/default.nix b/pkgs/build-support/oci-tools/default.nix
new file mode 100644
index 000000000000..18b238033ffd
--- /dev/null
+++ b/pkgs/build-support/oci-tools/default.nix
@@ -0,0 +1,78 @@
+{ lib, writeText, runCommand, writeReferencesToFile }:
+
+{
+ buildContainer =
+ { args
+ , mounts ? {}
+ , os ? "linux"
+ , arch ? "x86_64"
+ , readonly ? false
+ }:
+ let
+ sysMounts = {
+ "/proc" = {
+ type = "proc";
+ source = "proc";
+ };
+ "/dev" = {
+ type = "tmpfs";
+ source = "tmpfs";
+ options = [ "nosuid" "strictatime" "mode=755" "size=65536k" ];
+ };
+ "/dev/pts" = {
+ type = "devpts";
+ source = "devpts";
+ options = [ "nosuid" "noexec" "newinstance" "ptmxmode=0666" "mode=755" "gid=5" ];
+ };
+ "/dev/shm" = {
+ type = "tmpfs";
+ source = "shm";
+ options = [ "nosuid" "noexec" "nodev" "mode=1777" "size=65536k" ];
+ };
+ "/dev/mqueue" = {
+ type = "mqueue";
+ source = "mqueue";
+ options = [ "nosuid" "noexec" "nodev" ];
+ };
+ "/sys" = {
+ type = "sysfs";
+ source = "sysfs";
+ options = [ "nosuid" "noexec" "nodev" "ro" ];
+ };
+ "/sys/fs/cgroup" = {
+ type = "cgroup";
+ source = "cgroup";
+ options = [ "nosuid" "noexec" "nodev" "realatime" "ro" ];
+ };
+ };
+ config = writeText "config.json" (builtins.toJSON {
+ ociVersion = "1.0.0";
+ platform = {
+ inherit os arch;
+ };
+
+ linux = {
+ namespaces = map (type: { inherit type; }) [ "pid" "network" "mount" "ipc" "uts" ];
+ };
+
+ root = { path = "rootfs"; inherit readonly; };
+
+ process = {
+ inherit args;
+ user = { uid = 0; gid = 0; };
+ cwd = "/";
+ };
+
+ mounts = lib.mapAttrsToList (destination: { type, source, options ? null }: {
+ inherit destination type source options;
+ }) sysMounts;
+ });
+ in
+ runCommand "join" {} ''
+ set -o pipefail
+ mkdir -p $out/rootfs/{dev,proc,sys}
+ cp ${config} $out/config.json
+ xargs tar c < ${writeReferencesToFile args} | tar -xC $out/rootfs/
+ '';
+}
+
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index a39687a80f6f..8b008ffe0af3 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -391,6 +391,8 @@ in
nix-gitignore = callPackage ../build-support/nix-gitignore { };
+ ociTools = callPackage ../build-support/oci-tools { };
+
pathsFromGraph = ../build-support/kernel/paths-from-graph.pl;
pruneLibtoolFiles = makeSetupHook { name = "prune-libtool-files"; }