-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Docker image with Nix inside #5453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # Using Nix within Docker | ||
|
|
||
| To run the latest stable release of Nix with Docker run the following command: | ||
|
|
||
| ```console | ||
| $ docker -ti run nixos/nix | ||
| Unable to find image 'nixos/nix:latest' locally | ||
| latest: Pulling from nixos/nix | ||
| 5843afab3874: Pull complete | ||
| b52bf13f109c: Pull complete | ||
| 1e2415612aa3: Pull complete | ||
| Digest: sha256:27f6e7f60227e959ee7ece361f75d4844a40e1cc6878b6868fe30140420031ff | ||
| Status: Downloaded newer image for nixos/nix:latest | ||
| 35ca4ada6e96:/# nix --version | ||
| nix (Nix) 2.3.12 | ||
| 35ca4ada6e96:/# exit | ||
| ``` | ||
|
|
||
| # What is included in Nix' Docker image? | ||
|
|
||
| The official Docker image is created using `pkgs.dockerTools.buildLayeredImage` | ||
| (and not with `Dockerfile` as it is usual with Docker images). You can still | ||
| base your custom Docker image on it as you would do with any other Docker | ||
| image. | ||
|
|
||
| The Docker image is also not based on any other image and includes minimal set | ||
| of runtime dependencies that are required to use Nix: | ||
|
|
||
| - pkgs.nix | ||
| - pkgs.bashInteractive | ||
| - pkgs.coreutils-full | ||
| - pkgs.gnutar | ||
| - pkgs.gzip | ||
| - pkgs.gnugrep | ||
| - pkgs.which | ||
| - pkgs.curl | ||
| - pkgs.less | ||
| - pkgs.wget | ||
| - pkgs.man | ||
| - pkgs.cacert.out | ||
| - pkgs.findutils | ||
|
|
||
| # Docker image with the latest development version of Nix | ||
|
|
||
| To get the latest image that was built by [Hydra](https://hydra.nixos.org) run | ||
| the following command: | ||
|
|
||
| ```console | ||
| $ curl -L https://hydra.nixos.org/job/nix/master/dockerImage.x86_64-linux/latest/download/1 | docker load | ||
| $ docker run -ti nix:2.5pre20211105 | ||
| ``` | ||
|
|
||
| You can also build a Docker image from source yourself: | ||
|
|
||
| ```console | ||
| $ nix build ./\#hydraJobs.dockerImage.x86_64-linux | ||
| $ docker load -i ./result | ||
| $ docker run -ti nix:2.5pre20211105 | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,264 @@ | ||
| { pkgs ? import <nixpkgs> { } | ||
| , lib ? pkgs.lib | ||
| , name ? "nix" | ||
| , tag ? "latest" | ||
| , crossSystem ? null | ||
| , channelName ? "nixpkgs" | ||
| , channelURL ? "https://nixos.org/channels/nixpkgs-unstable" | ||
| }: | ||
| let | ||
| buildPkgs = pkgs; | ||
| targetPkgs = | ||
| if crossSystem != null && crossSystem != pkgs.system | ||
| then { | ||
| aarch64-linux = pkgs.pkgsCross.aarch64-multiplatform; | ||
| armv7l-linux = pkgs.pkgsCross.armv7l-hf-multiplatform.system; | ||
| x86_64-linux = pkgs.pkgsCross.gnu64; | ||
| powerpc64le-linux = pkgs.pkgsCross.musl-power; | ||
| i686-linux = pkgs.pkgsCross.gnu32; | ||
| }.${crossSystem} | ||
| else pkgs; | ||
|
|
||
| defaultPkgs = with targetPkgs; [ | ||
| nix | ||
| bashInteractive | ||
| coreutils-full | ||
| gnutar | ||
| gzip | ||
| gnugrep | ||
| which | ||
| curl | ||
| less | ||
| wget | ||
| man | ||
| cacert.out | ||
| findutils | ||
| ]; | ||
|
|
||
| users = { | ||
|
|
||
| root = { | ||
| uid = 0; | ||
| shell = "/bin/bash"; | ||
| home = "/root"; | ||
| gid = 0; | ||
| }; | ||
|
|
||
| } // lib.listToAttrs ( | ||
| map | ||
| ( | ||
| n: { | ||
| name = "nixbld${toString n}"; | ||
| value = { | ||
| uid = 30000 + n; | ||
| gid = 30000; | ||
| groups = [ "nixbld" ]; | ||
| description = "Nix build user ${toString n}"; | ||
| }; | ||
| } | ||
| ) | ||
| (lib.lists.range 1 32) | ||
| ); | ||
|
|
||
| groups = { | ||
| root.gid = 0; | ||
| nixbld.gid = 30000; | ||
| }; | ||
|
|
||
| userToPasswd = ( | ||
| k: | ||
| { uid | ||
| , gid ? 65534 | ||
| , home ? "/var/empty" | ||
| , description ? "" | ||
| , shell ? "/bin/false" | ||
| , groups ? [ ] | ||
| }: "${k}:x:${toString uid}:${toString gid}:${description}:${home}:${shell}" | ||
| ); | ||
| passwdContents = ( | ||
| lib.concatStringsSep "\n" | ||
| (lib.attrValues (lib.mapAttrs userToPasswd users)) | ||
| ); | ||
|
|
||
| userToShadow = k: { ... }: "${k}:!:1::::::"; | ||
| shadowContents = ( | ||
| lib.concatStringsSep "\n" | ||
| (lib.attrValues (lib.mapAttrs userToShadow users)) | ||
| ); | ||
|
|
||
| # Map groups to members | ||
| # { | ||
| # group = [ "user1" "user2" ]; | ||
| # } | ||
| groupMemberMap = ( | ||
| let | ||
| # Create a flat list of user/group mappings | ||
| mappings = ( | ||
| builtins.foldl' | ||
| ( | ||
| acc: user: | ||
| let | ||
| groups = users.${user}.groups or [ ]; | ||
| in | ||
| acc ++ map | ||
| (group: { | ||
| inherit user group; | ||
| }) | ||
| groups | ||
| ) | ||
| [ ] | ||
| (lib.attrNames users) | ||
| ); | ||
| in | ||
| ( | ||
| builtins.foldl' | ||
| ( | ||
| acc: v: acc // { | ||
| ${v.group} = acc.${v.group} or [ ] ++ [ v.user ]; | ||
| } | ||
| ) | ||
| { } | ||
| mappings) | ||
| ); | ||
|
|
||
| groupToGroup = k: { gid }: | ||
| let | ||
| members = groupMemberMap.${k} or [ ]; | ||
| in | ||
| "${k}:x:${toString gid}:${lib.concatStringsSep "," members}"; | ||
| groupContents = ( | ||
| lib.concatStringsSep "\n" | ||
| (lib.attrValues (lib.mapAttrs groupToGroup groups)) | ||
| ); | ||
|
|
||
| nixConf = { | ||
| sandbox = "false"; | ||
| build-users-group = "nixbld"; | ||
| trusted-public-keys = "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="; | ||
| }; | ||
| nixConfContents = (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: "${n} = ${v}") nixConf)) + "\n"; | ||
|
|
||
| baseSystem = | ||
| let | ||
| nixpkgs = targetPkgs.path; | ||
| channel = targetPkgs.runCommand "channel-nixos" { } '' | ||
| mkdir $out | ||
| ln -s ${nixpkgs} $out/nixpkgs | ||
| echo "[]" > $out/manifest.nix | ||
| ''; | ||
| rootEnv = pkgs.buildEnv { | ||
| name = "root-profile-env"; | ||
| paths = defaultPkgs; | ||
| }; | ||
| profile = targetPkgs.runCommand "user-environment" { } '' | ||
| mkdir $out | ||
| cp -a ${rootEnv}/* $out/ | ||
|
|
||
| cat > $out/manifest.nix <<EOF | ||
| [ | ||
| ${lib.concatStringsSep "\n" (builtins.map (drv: let | ||
| outputs = drv.outputsToInstall or [ "out" ]; | ||
| in '' | ||
| { | ||
| ${lib.concatStringsSep "\n" (builtins.map (output: '' | ||
| ${output} = { outPath = "${lib.getOutput output drv}"; }; | ||
| '') outputs)} | ||
| outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ]; | ||
| name = "${drv.name}"; | ||
| outPath = "${drv}"; | ||
| system = "${drv.system}"; | ||
| type = "derivation"; | ||
| meta = { }; | ||
| } | ||
| '') defaultPkgs)} | ||
| ] | ||
| EOF | ||
| ''; | ||
| in | ||
| targetPkgs.runCommand "base-system" | ||
| { | ||
| inherit passwdContents groupContents shadowContents nixConfContents; | ||
| passAsFile = [ | ||
| "passwdContents" | ||
| "groupContents" | ||
| "shadowContents" | ||
| "nixConfContents" | ||
| ]; | ||
| allowSubstitutes = false; | ||
| preferLocalBuild = true; | ||
| } '' | ||
| env | ||
| set -x | ||
| mkdir -p $out/etc | ||
|
|
||
| cat $passwdContentsPath > $out/etc/passwd | ||
| echo "" >> $out/etc/passwd | ||
|
|
||
| cat $groupContentsPath > $out/etc/group | ||
| echo "" >> $out/etc/group | ||
|
|
||
| cat $shadowContentsPath > $out/etc/shadow | ||
| echo "" >> $out/etc/shadow | ||
|
|
||
| mkdir -p $out/usr | ||
| ln -s /nix/var/nix/profiles/share $out/usr/ | ||
|
|
||
| mkdir -p $out/nix/var/nix/gcroots | ||
|
|
||
| mkdir $out/tmp | ||
|
|
||
| mkdir -p $out/etc/nix | ||
| cat $nixConfContentsPath > $out/etc/nix/nix.conf | ||
|
|
||
| mkdir -p $out/root | ||
| mkdir -p $out/nix/var/nix/profiles/per-user/root | ||
|
|
||
| ln -s ${profile} $out/nix/var/nix/profiles/default-1-link | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it's better to initialize the profile by running
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not 100% but if I remember correctly I wasn't able to generate profile with |
||
| ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default | ||
| ln -s /nix/var/nix/profiles/default $out/root/.nix-profile | ||
|
|
||
| ln -s ${channel} $out/nix/var/nix/profiles/per-user/root/channels-1-link | ||
| ln -s $out/nix/var/nix/profiles/per-user/root/channels-1-link $out/nix/var/nix/profiles/per-user/root/channels | ||
|
|
||
| mkdir -p $out/root/.nix-defexpr | ||
| ln -s $out/nix/var/nix/profiles/per-user/root/channels $out/root/.nix-defexpr/channels | ||
| echo "${channelURL} ${channelName}" > $out/root/.nix-channels | ||
|
|
||
| mkdir -p $out/bin $out/usr/bin | ||
| ln -s ${targetPkgs.coreutils}/bin/env $out/usr/bin/env | ||
| ln -s ${targetPkgs.bashInteractive}/bin/bash $out/bin/sh | ||
| ''; | ||
|
|
||
| in | ||
| targetPkgs.dockerTools.buildLayeredImageWithNixDb { | ||
|
|
||
| inherit name tag; | ||
|
|
||
| contents = [ baseSystem ]; | ||
|
|
||
| extraCommands = '' | ||
| rm -rf nix-support | ||
| ln -s /nix/var/nix/profiles nix/var/nix/gcroots/profiles | ||
| ''; | ||
|
|
||
| config = { | ||
| Cmd = [ "/root/.nix-profile/bin/bash" ]; | ||
| Env = [ | ||
| "USER=root" | ||
| "PATH=${lib.concatStringsSep ":" [ | ||
| "/root/.nix-profile/bin" | ||
| "/nix/var/nix/profiles/default/bin" | ||
| "/nix/var/nix/profiles/default/sbin" | ||
| ]}" | ||
| "MANPATH=${lib.concatStringsSep ":" [ | ||
| "/root/.nix-profile/share/man" | ||
| "/nix/var/nix/profiles/default/share/man" | ||
| ]}" | ||
| "SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" | ||
| "GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" | ||
| "NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt" | ||
| "NIX_PATH=/nix/var/nix/profiles/per-user/root/channels:/root/.nix-defexpr/channels" | ||
| ]; | ||
| }; | ||
|
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.