diff options
Diffstat (limited to 'docker.nix')
-rw-r--r-- | docker.nix | 214 |
1 files changed, 150 insertions, 64 deletions
diff --git a/docker.nix b/docker.nix index cec3a2950..b23a9637f 100644 --- a/docker.nix +++ b/docker.nix @@ -1,5 +1,8 @@ { pkgs ? import <nixpkgs> { }, + # Git commit ID, if available + lixRevision ? null, + nix2container, lib ? pkgs.lib, name ? "lix", tag ? "latest", @@ -12,26 +15,51 @@ flake-registry ? null, }: let + layerContents = with pkgs; [ + # pulls in glibc and openssl, about 60MB + { contents = [ coreutils-full ]; } + # some stuff that is low in the closure graph and small ish, mostly to make + # incremental lix updates cheaper + { + contents = [ + curl + libxml2 + sqlite + ]; + } + # 50MB of git + { contents = [ gitMinimal ]; } + # 144MB of nixpkgs + { + contents = [ channel ]; + inProfile = false; + } + ]; + + # These packages are left to be auto layered by nix2container, since it is + # less critical that they get layered sensibly and they tend to not be deps + # of anything in particular + autoLayered = with pkgs; [ + bashInteractive + gnutar + gzip + gnugrep + which + less + wget + man + cacert.out + findutils + iana-etc + openssh + nix + ]; + defaultPkgs = - with pkgs; - [ - nix - bashInteractive - coreutils-full - gnutar - gzip - gnugrep - which - curl - less - wget - man - cacert.out - findutils - iana-etc - git - openssh - ] + lib.lists.flatten ( + map (x: if !(x ? inProfile) || x.inProfile then x.contents else [ ]) layerContents + ) + ++ autoLayered ++ extraPkgs; users = @@ -139,16 +167,17 @@ let )) + "\n"; + nixpkgs = pkgs.path; + channel = pkgs.runCommand "channel-nixpkgs" { } '' + mkdir $out + ${lib.optionalString bundleNixpkgs '' + ln -s ${nixpkgs} $out/nixpkgs + echo "[]" > $out/manifest.nix + ''} + ''; + baseSystem = let - nixpkgs = pkgs.path; - channel = pkgs.runCommand "channel-nixos" { inherit bundleNixpkgs; } '' - mkdir $out - if [ "$bundleNixpkgs" ]; then - ln -s ${nixpkgs} $out/nixpkgs - echo "[]" > $out/manifest.nix - fi - ''; rootEnv = pkgs.buildPackages.buildEnv { name = "root-profile-env"; paths = defaultPkgs; @@ -187,7 +216,7 @@ let profile = pkgs.buildPackages.runCommand "user-environment" { } '' mkdir $out cp -a ${rootEnv}/* $out/ - ln -s ${manifest} $out/manifest.nix + ln -sf ${manifest} $out/manifest.nix ''; flake-registry-path = if (flake-registry == null) then @@ -236,6 +265,7 @@ let ln -s /nix/var/nix/profiles/share $out/usr/ mkdir -p $out/nix/var/nix/gcroots + ln -s /nix/var/nix/profiles $out/nix/var/nix/gcroots/profiles mkdir $out/tmp @@ -248,14 +278,14 @@ let mkdir -p $out/nix/var/nix/profiles/per-user/root ln -s ${profile} $out/nix/var/nix/profiles/default-1-link - ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default + ln -s /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 + ln -s /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 + ln -s /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 @@ -273,43 +303,99 @@ let ln -s $globalFlakeRegistryPath $out/nix/var/nix/gcroots/auto/$rootName '') ); -in -pkgs.dockerTools.buildLayeredImageWithNixDb { - inherit name tag maxLayers; + layers = builtins.foldl' ( + layersList: el: + let + layer = nix2container.buildLayer { + deps = el.contents; + layers = layersList; + }; + in + layersList ++ [ layer ] + ) [ ] layerContents; - contents = [ baseSystem ]; + image = nix2container.buildImage { - extraCommands = '' - rm -rf nix-support - ln -s /nix/var/nix/profiles nix/var/nix/gcroots/profiles - ''; - fakeRootCommands = '' - chmod 1777 tmp - chmod 1777 var/tmp - ''; + inherit name tag maxLayers; - 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" + inherit layers; + + copyToRoot = [ baseSystem ]; + + initializeNixDatabase = true; + + perms = [ + { + path = baseSystem; + regex = "(/var)?/tmp"; + mode = "1777"; + } ]; + + 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" + ]; + + Labels = { + "org.opencontainers.image.title" = "Lix"; + "org.opencontainers.image.source" = "https://git.lix.systems/lix-project/lix"; + "org.opencontainers.image.vendor" = "Lix project"; + "org.opencontainers.image.version" = pkgs.nix.version; + "org.opencontainers.image.description" = "Minimal Lix container image, with some batteries included."; + } // lib.optionalAttrs (lixRevision != null) { "org.opencontainers.image.revision" = lixRevision; }; + }; + + meta = { + description = "Docker image for Lix. This is built with nix2container; see that project's README for details"; + longDescription = '' + Docker image for Lix, built with nix2container. + To copy it to your docker daemon, nix run .#dockerImage.copyToDockerDaemon + To copy it to podman, nix run .#dockerImage.copyTo containers-storage:lix + ''; + }; }; +in +image +// { + # We don't ship the tarball as the default output because it is a strange thing to want imo + tarball = + pkgs.buildPackages.runCommand "docker-image-tarball-${pkgs.nix.version}" + { + nativeBuildInputs = [ pkgs.buildPackages.bubblewrap ]; + meta.description = "Docker image tarball with Lix for ${pkgs.system}"; + } + '' + mkdir -p $out/nix-support + image=$out/image.tar + # bwrap for foolish temp dir selection code that forces /var/tmp: + # https://github.com/containers/skopeo.git/blob/60ee543f7f7c242f46cc3a7541d9ac8ab1c89168/vendor/github.com/containers/image/v5/internal/tmpdir/tmpdir.go#L15-L18 + mkdir -p $TMPDIR/fake-var/tmp + args=(--unshare-user --bind "$TMPDIR/fake-var" /var) + for dir in /*; do + args+=(--dev-bind "/$dir" "/$dir") + done + bwrap ''${args[@]} -- ${lib.getExe image.copyTo} docker-archive:$image + gzip $image + echo "file binary-dist $image" >> $out/nix-support/hydra-build-products + ''; } |