From 289bb66f56d30ceb10d00574e0f5086a109d11b7 Mon Sep 17 00:00:00 2001 From: Remo Rechkemmer <59358383+monacoremo@users.noreply.github.com> Date: Wed, 20 May 2020 18:49:11 +0200 Subject: [PATCH] Reduce size of the static docker image by patching the Nix openssl package (#1528) * hook docker images into the default builds --- default.nix | 10 ++- nix/patches/default.nix | 3 + ...untime-dependencies-of-static-builds.patch | 89 +++++++++++++++++++ nix/static/default.nix | 1 + shell.nix | 4 + 5 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 nix/patches/openssl-split-runtime-dependencies-of-static-builds.patch diff --git a/default.nix b/default.nix index d7f0e24d7..44229fc78 100644 --- a/default.nix +++ b/default.nix @@ -81,12 +81,18 @@ rec { postgrestStatic = lib.justStaticExecutables (lib.dontCheck drvStatic); - # Docker image and loading script. + # Docker images and loading script. docker = pkgs.callPackage nix/docker { postgrest = postgrestStatic; }; + # Script `postgrest-docker-load` that loads the images built with Nix into + # Docker, using `docker load -i` under the hood. Referenced here from the top + # level so that it gets built by default. + dockerLoad = + docker.load; + # Environment in which PostgREST can be built with cabal, useful e.g. for - # defining a shell for nix-shell. + # defining a shell for `nix-shell`. env = drv.env; diff --git a/nix/patches/default.nix b/nix/patches/default.nix index 8cad309ce..ba7a835e5 100644 --- a/nix/patches/default.nix +++ b/nix/patches/default.nix @@ -22,4 +22,7 @@ nixpkgs-revert-ghc-bootstrap = ./nixpkgs-revert-ghc-bootstrap.patch; + + openssl-split-runtime-dependencies-of-static-builds = + ./openssl-split-runtime-dependencies-of-static-builds.patch; } diff --git a/nix/patches/openssl-split-runtime-dependencies-of-static-builds.patch b/nix/patches/openssl-split-runtime-dependencies-of-static-builds.patch new file mode 100644 index 000000000..bf5f61438 --- /dev/null +++ b/nix/patches/openssl-split-runtime-dependencies-of-static-builds.patch @@ -0,0 +1,89 @@ +From 2aabdaca408d22ce2b6aa078ba58a115f5bd7fe4 Mon Sep 17 00:00:00 2001 +From: Remo +Date: Fri, 15 May 2020 10:13:43 +0200 +Subject: [PATCH] openssl: split runtime dependencies of static builds into a + separate output + +--- + .../development/libraries/openssl/default.nix | 38 ++++++++++++++++--- + 1 file changed, 32 insertions(+), 6 deletions(-) + +diff --git a/pkgs/development/libraries/openssl/default.nix b/pkgs/development/libraries/openssl/default.nix +index 43170f25d38..6336a060911 100644 +--- a/pkgs/development/libraries/openssl/default.nix ++++ b/pkgs/development/libraries/openssl/default.nix +@@ -34,9 +34,22 @@ let + substituteInPlace crypto/async/arch/async_posix.h \ + --replace '!defined(__ANDROID__) && !defined(__OpenBSD__)' \ + '!defined(__ANDROID__) && !defined(__OpenBSD__) && 0' ++ '' + optionalString static ++ # On static builds, the ENGINESDIR will be empty, but its path will be ++ # compiled into the library. In order to minimize the runtime dependencies ++ # of packages that statically link openssl, we move it into the OPENSSLDIR, ++ # which will be separated into the 'etc' output. ++ '' ++ substituteInPlace Configurations/unix-Makefile.tmpl \ ++ --replace 'ENGINESDIR=$(libdir)/engines-{- $sover_dirname -}' \ ++ 'ENGINESDIR=$(OPENSSLDIR)/engines-{- $sover_dirname -}' + ''; + +- outputs = [ "bin" "dev" "out" "man" ] ++ optional withDocs "doc"; ++ outputs = ++ [ "bin" "dev" "out" "man" ] ++ ++ optional withDocs "doc" ++ # Separate output for the runtime dependencies of the static build. ++ ++ optional static "etc"; + setOutputFlags = false; + separateDebugInfo = !(stdenv.hostPlatform.useLLVM or false) && stdenv.cc.isGNU; + +@@ -72,7 +85,17 @@ let + configureFlags = [ + "shared" # "shared" builds both shared and static libraries + "--libdir=lib" +- "--openssldir=etc/ssl" ++ (if !static then ++ "--openssldir=etc/ssl" ++ else ++ # Separate the OPENSSLDIR into its own output, as its path will be ++ # compiled into 'libcrypto.a'. This makes it a runtime dependency of ++ # any package that statically links openssl, so we want to keep that ++ # output minimal. We need to prepend '/.' to the path in order to make ++ # it appear absolute before variable expansion, the 'prefix' would be ++ # prepended to it otherwise. ++ "--openssldir=/.$(etc)/etc/ssl" ++ ) + ] ++ stdenv.lib.optionals withCryptodev [ + "-DHAVE_CRYPTODEV" + "-DUSE_CRYPTODEV_DIGESTS" +@@ -103,6 +126,8 @@ let + rm "$out/lib/"*.a + fi + ++ # 'etc' is a separate output on static builds only. ++ etc=$out + '' + + '' + mkdir -p $bin +@@ -117,14 +142,15 @@ let + mv $out/include $dev/ + + # remove dependency on Perl at runtime +- rm -r $out/etc/ssl/misc ++ rm -r $etc/etc/ssl/misc + +- rmdir $out/etc/ssl/{certs,private} ++ rmdir $etc/etc/ssl/{certs,private} + ''; + + postFixup = stdenv.lib.optionalString (!stdenv.hostPlatform.isWindows) '' +- # Check to make sure the main output doesn't depend on perl +- if grep -r '${buildPackages.perl}' $out; then ++ # Check to make sure the main output and the static runtime dependencies ++ # don't depend on perl ++ if grep -r '${buildPackages.perl}' $out $etc; then + echo "Found an erroneous dependency on perl ^^^" >&2 + exit 1 + fi +-- +2.25.1 + diff --git a/nix/static/default.nix b/nix/static/default.nix index 7b987e06a..978d7aede 100644 --- a/nix/static/default.nix +++ b/nix/static/default.nix @@ -66,6 +66,7 @@ let patches.applyPatches "patched-nixpkgs" nixpkgs [ patches.nixpkgs-revert-ghc-bootstrap + patches.openssl-split-runtime-dependencies-of-static-builds ]; # Apply our overlay to the given pkgs. diff --git a/shell.nix b/shell.nix index 53d37a1d6..f0568bb1f 100644 --- a/shell.nix +++ b/shell.nix @@ -11,6 +11,10 @@ pkgs.lib.overrideDerivation env ( tests style lint + # We don't include the `postgrest-docker-load` here, as that would + # cause the shell to depend on building the Docker images and in turn + # on the static executable. Use `nix-shell default.nix -A dockerLoad` + # to get a shell with that script on the PATH. ]; shellHook =