1{ lib, callPackage, fetchFromGitHub }:
2
3rec {
4 dockerGen = {
5 version
6 , cliRev, cliHash
7 , mobyRev, mobyHash
8 , runcRev, runcHash
9 , containerdRev, containerdHash
10 , tiniRev, tiniHash
11 , buildxSupport ? true, composeSupport ? true, sbomSupport ? false
12 # package dependencies
13 , stdenv, fetchFromGitHub, fetchpatch, buildGoPackage
14 , makeWrapper, installShellFiles, pkg-config, glibc
15 , go-md2man, go, containerd, runc, docker-proxy, tini, libtool
16 , sqlite, iproute2, docker-buildx, docker-compose, docker-sbom
17 , iptables, e2fsprogs, xz, util-linux, xfsprogs, git
18 , procps, rootlesskit, slirp4netns, fuse-overlayfs, nixosTests
19 , clientOnly ? !stdenv.isLinux, symlinkJoin
20 , withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd, systemd
21 , withBtrfs ? stdenv.isLinux, btrfs-progs
22 , withLvm ? stdenv.isLinux, lvm2
23 , withSeccomp ? stdenv.isLinux, libseccomp
24 }:
25 let
26 docker-runc = runc.overrideAttrs (oldAttrs: {
27 pname = "docker-runc";
28 inherit version;
29
30 src = fetchFromGitHub {
31 owner = "opencontainers";
32 repo = "runc";
33 rev = runcRev;
34 hash = runcHash;
35 };
36
37 # docker/runc already include these patches / are not applicable
38 patches = [];
39 });
40
41 docker-containerd = containerd.overrideAttrs (oldAttrs: {
42 pname = "docker-containerd";
43 inherit version;
44
45 src = fetchFromGitHub {
46 owner = "containerd";
47 repo = "containerd";
48 rev = containerdRev;
49 hash = containerdHash;
50 };
51
52 buildInputs = oldAttrs.buildInputs
53 ++ lib.optionals withSeccomp [ libseccomp ];
54 });
55
56 docker-tini = tini.overrideAttrs (oldAttrs: {
57 pname = "docker-init";
58 inherit version;
59
60 src = fetchFromGitHub {
61 owner = "krallin";
62 repo = "tini";
63 rev = tiniRev;
64 hash = tiniHash;
65 };
66
67 # Do not remove static from make files as we want a static binary
68 postPatch = "";
69
70 buildInputs = [ glibc glibc.static ];
71
72 env.NIX_CFLAGS_COMPILE = "-DMINIMAL=ON";
73 });
74
75 moby-src = fetchFromGitHub {
76 owner = "moby";
77 repo = "moby";
78 rev = mobyRev;
79 hash = mobyHash;
80 };
81
82 moby = buildGoPackage (lib.optionalAttrs stdenv.isLinux rec {
83 pname = "moby";
84 inherit version;
85
86 src = moby-src;
87
88 goPackagePath = "github.com/docker/docker";
89
90 nativeBuildInputs = [ makeWrapper pkg-config go-md2man go libtool installShellFiles ];
91 buildInputs = [ sqlite ]
92 ++ lib.optional withLvm lvm2
93 ++ lib.optional withBtrfs btrfs-progs
94 ++ lib.optional withSystemd systemd
95 ++ lib.optional withSeccomp libseccomp;
96
97 extraPath = lib.optionals stdenv.isLinux (lib.makeBinPath [ iproute2 iptables e2fsprogs xz xfsprogs procps util-linux git ]);
98
99 extraUserPath = lib.optionals (stdenv.isLinux && !clientOnly) (lib.makeBinPath [ rootlesskit slirp4netns fuse-overlayfs ]);
100
101 patches = lib.optionals (lib.versionOlder version "23") [
102 # This patch incorporates code from a PR fixing using buildkit with the ZFS graph driver.
103 # It could be removed when a version incorporating this patch is released.
104 (fetchpatch {
105 name = "buildkit-zfs.patch";
106 url = "https://github.com/moby/moby/pull/43136.patch";
107 hash = "sha256-1WZfpVnnqFwLMYqaHLploOodls0gHF8OCp7MrM26iX8=";
108 })
109 ];
110
111 postPatch = ''
112 patchShebangs hack/make.sh hack/make/
113 '';
114
115 buildPhase = ''
116 export GOCACHE="$TMPDIR/go-cache"
117 # build engine
118 cd ./go/src/${goPackagePath}
119 export AUTO_GOPATH=1
120 export DOCKER_GITCOMMIT="${cliRev}"
121 export VERSION="${version}"
122 ./hack/make.sh dynbinary
123 cd -
124 '';
125
126 installPhase = ''
127 cd ./go/src/${goPackagePath}
128 install -Dm755 ./bundles/dynbinary-daemon/dockerd $out/libexec/docker/dockerd
129
130 makeWrapper $out/libexec/docker/dockerd $out/bin/dockerd \
131 --prefix PATH : "$out/libexec/docker:$extraPath"
132
133 ln -s ${docker-containerd}/bin/containerd $out/libexec/docker/containerd
134 ln -s ${docker-containerd}/bin/containerd-shim $out/libexec/docker/containerd-shim
135 ln -s ${docker-runc}/bin/runc $out/libexec/docker/runc
136 ln -s ${docker-proxy}/bin/docker-proxy $out/libexec/docker/docker-proxy
137 ln -s ${docker-tini}/bin/tini-static $out/libexec/docker/docker-init
138
139 # systemd
140 install -Dm644 ./contrib/init/systemd/docker.service $out/etc/systemd/system/docker.service
141 substituteInPlace $out/etc/systemd/system/docker.service --replace /usr/bin/dockerd $out/bin/dockerd
142 install -Dm644 ./contrib/init/systemd/docker.socket $out/etc/systemd/system/docker.socket
143
144 # rootless Docker
145 install -Dm755 ./contrib/dockerd-rootless.sh $out/libexec/docker/dockerd-rootless.sh
146 makeWrapper $out/libexec/docker/dockerd-rootless.sh $out/bin/dockerd-rootless \
147 --prefix PATH : "$out/libexec/docker:$extraPath:$extraUserPath"
148 '';
149
150 DOCKER_BUILDTAGS = lib.optional withSystemd "journald"
151 ++ lib.optional (!withBtrfs) "exclude_graphdriver_btrfs"
152 ++ lib.optional (!withLvm) "exclude_graphdriver_devicemapper"
153 ++ lib.optional withSeccomp "seccomp";
154 });
155
156 plugins = lib.optional buildxSupport docker-buildx
157 ++ lib.optional composeSupport docker-compose
158 ++ lib.optional sbomSupport docker-sbom;
159 pluginsRef = symlinkJoin { name = "docker-plugins"; paths = plugins; };
160 in
161 buildGoPackage (lib.optionalAttrs (!clientOnly) {
162 # allow overrides of docker components
163 # TODO: move packages out of the let...in into top-level to allow proper overrides
164 inherit docker-runc docker-containerd docker-proxy docker-tini moby;
165 } // rec {
166 pname = "docker";
167 inherit version;
168
169 src = fetchFromGitHub {
170 owner = "docker";
171 repo = "cli";
172 rev = cliRev;
173 hash = cliHash;
174 };
175
176 goPackagePath = "github.com/docker/cli";
177
178 nativeBuildInputs = [
179 makeWrapper pkg-config go-md2man go libtool installShellFiles
180 ];
181
182 buildInputs = plugins ++ lib.optionals (lib.versionAtLeast version "23" && stdenv.isLinux) [
183 glibc
184 glibc.static
185 ];
186
187 postPatch = ''
188 patchShebangs man scripts/build/
189 substituteInPlace ./scripts/build/.variables --replace "set -eu" ""
190 '' + lib.optionalString (plugins != []) ''
191 substituteInPlace ./cli-plugins/manager/manager_unix.go --replace /usr/libexec/docker/cli-plugins \
192 "${pluginsRef}/libexec/docker/cli-plugins"
193 '';
194
195 # Keep eyes on BUILDTIME format - https://github.com/docker/cli/blob/${version}/scripts/build/.variables
196 buildPhase = ''
197 export GOCACHE="$TMPDIR/go-cache"
198
199 cd ./go/src/${goPackagePath}
200 # Mimic AUTO_GOPATH
201 mkdir -p .gopath/src/github.com/docker/
202 ln -sf $PWD .gopath/src/github.com/docker/cli
203 export GOPATH="$PWD/.gopath:$GOPATH"
204 export GITCOMMIT="${cliRev}"
205 export VERSION="${version}"
206 export BUILDTIME="1970-01-01T00:00:00Z"
207 source ./scripts/build/.variables
208 export CGO_ENABLED=1
209 go build -tags pkcs11 --ldflags "$GO_LDFLAGS" github.com/docker/cli/cmd/docker
210 cd -
211 '';
212
213 outputs = ["out"] ++ lib.optional (lib.versionOlder version "23") "man";
214
215 installPhase = ''
216 cd ./go/src/${goPackagePath}
217 install -Dm755 ./docker $out/libexec/docker/docker
218
219 makeWrapper $out/libexec/docker/docker $out/bin/docker \
220 --prefix PATH : "$out/libexec/docker:$extraPath"
221 '' + lib.optionalString (!clientOnly) ''
222 # symlink docker daemon to docker cli derivation
223 ln -s ${moby}/bin/dockerd $out/bin/dockerd
224 ln -s ${moby}/bin/dockerd-rootless $out/bin/dockerd-rootless
225
226 # systemd
227 mkdir -p $out/etc/systemd/system
228 ln -s ${moby}/etc/systemd/system/docker.service $out/etc/systemd/system/docker.service
229 ln -s ${moby}/etc/systemd/system/docker.socket $out/etc/systemd/system/docker.socket
230 '' + ''
231 # completion (cli)
232 installShellCompletion --bash ./contrib/completion/bash/docker
233 installShellCompletion --fish ./contrib/completion/fish/docker.fish
234 installShellCompletion --zsh ./contrib/completion/zsh/_docker
235 '' + lib.optionalString (stdenv.hostPlatform == stdenv.buildPlatform && lib.versionOlder version "23") ''
236 # Generate man pages from cobra commands
237 echo "Generate man pages from cobra"
238 mkdir -p ./man/man1
239 go build -o ./gen-manpages github.com/docker/cli/man
240 ./gen-manpages --root . --target ./man/man1
241 '' + lib.optionalString (lib.versionOlder version "23") ''
242 # Generate legacy pages from markdown
243 echo "Generate legacy manpages"
244 ./man/md2man-all.sh -q
245
246 installManPage man/*/*.[1-9]
247 '';
248
249 passthru = {
250 # Exposed for tarsum build on non-linux systems (build-support/docker/default.nix)
251 inherit moby-src;
252 tests = lib.optionals (!clientOnly) { inherit (nixosTests) docker; };
253 };
254
255 meta = with lib; {
256 homepage = "https://www.docker.com/";
257 description = "An open source project to pack, ship and run any application as a lightweight container";
258 longDescription = ''
259 Docker is a platform designed to help developers build, share, and run modern applications.
260
261 To enable the docker daemon on NixOS, set the `virtualisation.docker.enable` option to `true`.
262 '';
263 license = licenses.asl20;
264 maintainers = with maintainers; [ offline vdemeester periklis amaxine ];
265 mainProgram = "docker";
266 };
267 });
268
269 # Get revisions from
270 # https://github.com/moby/moby/tree/${version}/hack/dockerfile/install/*
271 docker_20_10 = callPackage dockerGen rec {
272 version = "20.10.26";
273 cliRev = "v${version}";
274 cliHash = "sha256-EPhsng0kLnweVbC8ZnH0NK1/yHlYSA5Sred4rWJX/Gs=";
275 mobyRev = "v${version}";
276 mobyHash = "sha256-IJ7m2mQnsLiom0EuZLpuLY6fYEko7rEy35igJv1AY04=";
277 runcRev = "v1.1.8";
278 runcHash = "sha256-rDJYEc64KW4Qa3Eg2oUjJqIKrg6THb5hxQFFbvb9Zp4=";
279 containerdRev = "v1.6.22";
280 containerdHash = "sha256-In7OkK3xm7Cz3H1jzG9b4tsZbmo44QCq8pNU+PPy8dY=";
281 tiniRev = "v0.19.0";
282 tiniHash = "sha256-ZDKu/8yE5G0RYFJdhgmCdN3obJNyRWv6K/Gd17zc1sI=";
283 };
284
285 docker_24 = callPackage dockerGen rec {
286 version = "24.0.5";
287 cliRev = "v${version}";
288 cliHash = "sha256-u1quVGTx/p8BDyRn33vYyyuE5BOhWMnGQ5uVX0PZ5mg=";
289 mobyRev = "v${version}";
290 mobyHash = "sha256-JQjRz1fHZlQRkNw/R8WWLV8caN3/U3mrKKQXbZt2crU=";
291 runcRev = "v1.1.8";
292 runcHash = "sha256-rDJYEc64KW4Qa3Eg2oUjJqIKrg6THb5hxQFFbvb9Zp4=";
293 containerdRev = "v1.7.1";
294 containerdHash = "sha256-WwedtcsrDQwMQcKFO5nnPiHyGJpl5hXZlmpbBe1/ftY=";
295 tiniRev = "v0.19.0";
296 tiniHash = "sha256-ZDKu/8yE5G0RYFJdhgmCdN3obJNyRWv6K/Gd17zc1sI=";
297 };
298}