1# Examples of using the docker tools to build packages.
2#
3# This file defines several docker images. In order to use an image,
4# build its derivation with `nix-build`, and then load the result with
5# `docker load`. For example:
6#
7# $ nix-build '<nixpkgs>' -A dockerTools.examples.redis
8# $ docker load < result
9
10{ pkgs, buildImage, buildLayeredImage, fakeNss, pullImage, shadowSetup, buildImageWithNixDb, pkgsCross, streamNixShellImage }:
11
12let
13 nixosLib = import ../../../nixos/lib {
14 # Experimental features need testing too, but there's no point in warning
15 # about it, so we enable the feature flag.
16 featureFlags.minimalModules = {};
17 };
18 evalMinimalConfig = module: nixosLib.evalModules { modules = [ module ]; };
19
20in
21
22rec {
23 # 1. basic example
24 bash = buildImage {
25 name = "bash";
26 tag = "latest";
27 copyToRoot = pkgs.buildEnv {
28 name = "image-root";
29 paths = [ pkgs.bashInteractive ];
30 pathsToLink = [ "/bin" ];
31 };
32 };
33
34 # 2. service example, layered on another image
35 redis = buildImage {
36 name = "redis";
37 tag = "latest";
38
39 # for example's sake, we can layer redis on top of bash or debian
40 fromImage = bash;
41 # fromImage = debian;
42
43 copyToRoot = pkgs.buildEnv {
44 name = "image-root";
45 paths = [ pkgs.redis ];
46 pathsToLink = [ "/bin" ];
47 };
48
49 runAsRoot = ''
50 mkdir -p /data
51 '';
52
53 config = {
54 Cmd = [ "/bin/redis-server" ];
55 WorkingDir = "/data";
56 Volumes = {
57 "/data" = {};
58 };
59 };
60 };
61
62 # 3. another service example
63 nginx = let
64 nginxPort = "80";
65 nginxConf = pkgs.writeText "nginx.conf" ''
66 user nobody nobody;
67 daemon off;
68 error_log /dev/stdout info;
69 pid /dev/null;
70 events {}
71 http {
72 access_log /dev/stdout;
73 server {
74 listen ${nginxPort};
75 index index.html;
76 location / {
77 root ${nginxWebRoot};
78 }
79 }
80 }
81 '';
82 nginxWebRoot = pkgs.writeTextDir "index.html" ''
83 <html><body><h1>Hello from NGINX</h1></body></html>
84 '';
85 in
86 buildLayeredImage {
87 name = "nginx-container";
88 tag = "latest";
89 contents = [
90 fakeNss
91 pkgs.nginx
92 ];
93
94 extraCommands = ''
95 mkdir -p tmp/nginx_client_body
96
97 # nginx still tries to read this directory even if error_log
98 # directive is specifying another file :/
99 mkdir -p var/log/nginx
100 '';
101
102 config = {
103 Cmd = [ "nginx" "-c" nginxConf ];
104 ExposedPorts = {
105 "${nginxPort}/tcp" = {};
106 };
107 };
108 };
109
110 # 4. example of pulling an image. could be used as a base for other images
111 nixFromDockerHub = pullImage {
112 imageName = "nixos/nix";
113 imageDigest = "sha256:85299d86263a3059cf19f419f9d286cc9f06d3c13146a8ebbb21b3437f598357";
114 sha256 = "19fw0n3wmddahzr20mhdqv6jkjn1kanh6n2mrr08ai53dr8ph5n7";
115 finalImageTag = "2.2.1";
116 finalImageName = "nix";
117 };
118 # Same example, but re-fetches every time the fetcher implementation changes.
119 # NOTE: Only use this for testing, or you'd be wasting a lot of time, network and space.
120 testNixFromDockerHub = pkgs.testers.invalidateFetcherByDrvHash pullImage {
121 imageName = "nixos/nix";
122 imageDigest = "sha256:85299d86263a3059cf19f419f9d286cc9f06d3c13146a8ebbb21b3437f598357";
123 sha256 = "19fw0n3wmddahzr20mhdqv6jkjn1kanh6n2mrr08ai53dr8ph5n7";
124 finalImageTag = "2.2.1";
125 finalImageName = "nix";
126 };
127
128 # 5. example of multiple contents, emacs and vi happily coexisting
129 editors = buildImage {
130 name = "editors";
131 copyToRoot = pkgs.buildEnv {
132 name = "image-root";
133 pathsToLink = [ "/bin" ];
134 paths = [
135 pkgs.coreutils
136 pkgs.bash
137 pkgs.emacs
138 pkgs.vim
139 pkgs.nano
140 ];
141 };
142 };
143
144 # 6. nix example to play with the container nix store
145 # docker run -it --rm nix nix-store -qR $(nix-build '<nixpkgs>' -A nix)
146 nix = buildImageWithNixDb {
147 name = "nix";
148 tag = "latest";
149 copyToRoot = pkgs.buildEnv {
150 name = "image-root";
151 pathsToLink = [ "/bin" ];
152 paths = [
153 # nix-store uses cat program to display results as specified by
154 # the image env variable NIX_PAGER.
155 pkgs.coreutils
156 pkgs.nix
157 pkgs.bash
158 ];
159 };
160 config = {
161 Env = [
162 "NIX_PAGER=cat"
163 # A user is required by nix
164 # https://github.com/NixOS/nix/blob/9348f9291e5d9e4ba3c4347ea1b235640f54fd79/src/libutil/util.cc#L478
165 "USER=nobody"
166 ];
167 };
168 };
169
170 # 7. example of adding something on top of an image pull by our
171 # dockerTools chain.
172 onTopOfPulledImage = buildImage {
173 name = "onTopOfPulledImage";
174 tag = "latest";
175 fromImage = nixFromDockerHub;
176 copyToRoot = pkgs.buildEnv {
177 name = "image-root";
178 pathsToLink = [ "/bin" ];
179 paths = [ pkgs.hello ];
180 };
181 };
182
183 # 8. regression test for erroneous use of eval and string expansion.
184 # See issue #34779 and PR #40947 for details.
185 runAsRootExtraCommands = pkgs.dockerTools.buildImage {
186 name = "runAsRootExtraCommands";
187 tag = "latest";
188 copyToRoot = pkgs.buildEnv {
189 name = "image-root";
190 pathsToLink = [ "/bin" ];
191 paths = [ pkgs.coreutils ];
192 };
193 # The parens here are to create problematic bash to embed and eval. In case
194 # this is *embedded* into the script (with nix expansion) the initial quotes
195 # will close the string and the following parens are unexpected
196 runAsRoot = ''echo "(runAsRoot)" > runAsRoot'';
197 extraCommands = ''echo "(extraCommand)" > extraCommands'';
198 };
199
200 # 9. Ensure that setting created to now results in a date which
201 # isn't the epoch + 1
202 unstableDate = pkgs.dockerTools.buildImage {
203 name = "unstable-date";
204 tag = "latest";
205 copyToRoot = pkgs.buildEnv {
206 name = "image-root";
207 pathsToLink = [ "/bin" ];
208 paths = [ pkgs.coreutils ];
209 };
210 created = "now";
211 };
212
213 # 10. Create a layered image
214 layered-image = pkgs.dockerTools.buildLayeredImage {
215 name = "layered-image";
216 tag = "latest";
217 extraCommands = ''echo "(extraCommand)" > extraCommands'';
218 config.Cmd = [ "${pkgs.hello}/bin/hello" ];
219 contents = [ pkgs.hello pkgs.bash pkgs.coreutils ];
220 };
221
222 # 11. Create an image on top of a layered image
223 layered-on-top = pkgs.dockerTools.buildImage {
224 name = "layered-on-top";
225 tag = "latest";
226 fromImage = layered-image;
227 extraCommands = ''
228 mkdir ./example-output
229 chmod 777 ./example-output
230 '';
231 config = {
232 Env = [ "PATH=${pkgs.coreutils}/bin/" ];
233 WorkingDir = "/example-output";
234 Cmd = [
235 "${pkgs.bash}/bin/bash" "-c" "echo hello > foo; cat foo"
236 ];
237 };
238 };
239
240 # 12 Create a layered image on top of a layered image
241 layered-on-top-layered = pkgs.dockerTools.buildLayeredImage {
242 name = "layered-on-top-layered";
243 tag = "latest";
244 fromImage = layered-image;
245 extraCommands = ''
246 mkdir ./example-output
247 chmod 777 ./example-output
248 '';
249 config = {
250 Env = [ "PATH=${pkgs.coreutils}/bin/" ];
251 WorkingDir = "/example-output";
252 Cmd = [
253 "${pkgs.bash}/bin/bash" "-c" "echo hello > foo; cat foo"
254 ];
255 };
256 };
257
258 # 13. example of running something as root on top of a parent image
259 # Regression test related to PR #52109
260 runAsRootParentImage = buildImage {
261 name = "runAsRootParentImage";
262 tag = "latest";
263 runAsRoot = "touch /example-file";
264 fromImage = bash;
265 };
266
267 # 14. example of 3 layers images This image is used to verify the
268 # order of layers is correct.
269 # It allows to validate
270 # - the layer of parent are below
271 # - the order of parent layer is preserved at image build time
272 # (this is why there are 3 images)
273 layersOrder = let
274 l1 = pkgs.dockerTools.buildImage {
275 name = "l1";
276 tag = "latest";
277 extraCommands = ''
278 mkdir -p tmp
279 echo layer1 > tmp/layer1
280 echo layer1 > tmp/layer2
281 echo layer1 > tmp/layer3
282 '';
283 };
284 l2 = pkgs.dockerTools.buildImage {
285 name = "l2";
286 fromImage = l1;
287 tag = "latest";
288 extraCommands = ''
289 mkdir -p tmp
290 echo layer2 > tmp/layer2
291 echo layer2 > tmp/layer3
292 '';
293 };
294 in pkgs.dockerTools.buildImage {
295 name = "l3";
296 fromImage = l2;
297 tag = "latest";
298 copyToRoot = pkgs.buildEnv {
299 name = "image-root";
300 pathsToLink = [ "/bin" ];
301 paths = [ pkgs.coreutils ];
302 };
303 extraCommands = ''
304 mkdir -p tmp
305 echo layer3 > tmp/layer3
306 '';
307 };
308
309 # 15. Environment variable inheritance.
310 # Child image should inherit parents environment variables,
311 # optionally overriding them.
312 environmentVariablesParent = pkgs.dockerTools.buildImage {
313 name = "parent";
314 tag = "latest";
315 config = {
316 Env = [
317 "FROM_PARENT=true"
318 "LAST_LAYER=parent"
319 ];
320 };
321 };
322
323 environmentVariables = pkgs.dockerTools.buildImage {
324 name = "child";
325 fromImage = environmentVariablesParent;
326 tag = "latest";
327 copyToRoot = pkgs.buildEnv {
328 name = "image-root";
329 pathsToLink = [ "/bin" ];
330 paths = [ pkgs.coreutils ];
331 };
332 config = {
333 Env = [
334 "FROM_CHILD=true"
335 "LAST_LAYER=child"
336 ];
337 };
338 };
339
340 environmentVariablesLayered = pkgs.dockerTools.buildLayeredImage {
341 name = "child";
342 fromImage = environmentVariablesParent;
343 tag = "latest";
344 contents = [ pkgs.coreutils ];
345 config = {
346 Env = [
347 "FROM_CHILD=true"
348 "LAST_LAYER=child"
349 ];
350 };
351 };
352
353 # 16. Create another layered image, for comparing layers with image 10.
354 another-layered-image = pkgs.dockerTools.buildLayeredImage {
355 name = "another-layered-image";
356 tag = "latest";
357 config.Cmd = [ "${pkgs.hello}/bin/hello" ];
358 };
359
360 # 17. Create a layered image with only 2 layers
361 two-layered-image = pkgs.dockerTools.buildLayeredImage {
362 name = "two-layered-image";
363 tag = "latest";
364 config.Cmd = [ "${pkgs.hello}/bin/hello" ];
365 contents = [ pkgs.bash pkgs.hello ];
366 maxLayers = 2;
367 };
368
369 # 18. Create a layered image with more packages than max layers.
370 # coreutils and hello are part of the same layer
371 bulk-layer = pkgs.dockerTools.buildLayeredImage {
372 name = "bulk-layer";
373 tag = "latest";
374 contents = with pkgs; [
375 coreutils hello
376 ];
377 maxLayers = 2;
378 };
379
380 # 19. Create a layered image with a base image and more packages than max
381 # layers. coreutils and hello are part of the same layer
382 layered-bulk-layer = pkgs.dockerTools.buildLayeredImage {
383 name = "layered-bulk-layer";
384 tag = "latest";
385 fromImage = two-layered-image;
386 contents = with pkgs; [
387 coreutils hello
388 ];
389 maxLayers = 4;
390 };
391
392 # 20. Create a "layered" image without nix store layers. This is not
393 # recommended, but can be useful for base images in rare cases.
394 no-store-paths = pkgs.dockerTools.buildLayeredImage {
395 name = "no-store-paths";
396 tag = "latest";
397 extraCommands = ''
398 # This removes sharing of busybox and is not recommended. We do this
399 # to make the example suitable as a test case with working binaries.
400 cp -r ${pkgs.pkgsStatic.busybox}/* .
401
402 # This is a "build" dependency that will not appear in the image
403 ${pkgs.hello}/bin/hello
404 '';
405 };
406
407 nixLayered = pkgs.dockerTools.buildLayeredImageWithNixDb {
408 name = "nix-layered";
409 tag = "latest";
410 contents = [
411 # nix-store uses cat program to display results as specified by
412 # the image env variable NIX_PAGER.
413 pkgs.coreutils
414 pkgs.nix
415 pkgs.bash
416 ];
417 config = {
418 Env = [
419 "NIX_PAGER=cat"
420 # A user is required by nix
421 # https://github.com/NixOS/nix/blob/9348f9291e5d9e4ba3c4347ea1b235640f54fd79/src/libutil/util.cc#L478
422 "USER=nobody"
423 ];
424 };
425 };
426
427 # 21. Support files in the store on buildLayeredImage
428 # See: https://github.com/NixOS/nixpkgs/pull/91084#issuecomment-653496223
429 filesInStore = pkgs.dockerTools.buildLayeredImageWithNixDb {
430 name = "file-in-store";
431 tag = "latest";
432 contents = [
433 pkgs.coreutils
434 pkgs.nix
435 (pkgs.writeScriptBin "myscript" ''
436 #!${pkgs.runtimeShell}
437 cat ${pkgs.writeText "somefile" "some data"}
438 '')
439 ];
440 config = {
441 Cmd = [ "myscript" ];
442 # For some reason 'nix-store --verify' requires this environment variable
443 Env = [ "USER=root" ];
444 };
445 };
446
447 # 22. Ensure that setting created to now results in a date which
448 # isn't the epoch + 1 for layered images.
449 unstableDateLayered = pkgs.dockerTools.buildLayeredImage {
450 name = "unstable-date-layered";
451 tag = "latest";
452 contents = [ pkgs.coreutils ];
453 created = "now";
454 };
455
456 # 23. Ensure that layers are unpacked in the correct order before the
457 # runAsRoot script is executed.
458 layersUnpackOrder =
459 let
460 layerOnTopOf = parent: layerName:
461 pkgs.dockerTools.buildImage {
462 name = "layers-unpack-order-${layerName}";
463 tag = "latest";
464 fromImage = parent;
465 copyToRoot = pkgs.buildEnv {
466 name = "image-root";
467 pathsToLink = [ "/bin" ];
468 paths = [ pkgs.coreutils ];
469 };
470 runAsRoot = ''
471 #!${pkgs.runtimeShell}
472 echo -n "${layerName}" >> /layer-order
473 '';
474 };
475 # When executing the runAsRoot script when building layer C, if layer B is
476 # not unpacked on top of layer A, the contents of /layer-order will not be
477 # "ABC".
478 layerA = layerOnTopOf null "a";
479 layerB = layerOnTopOf layerA "b";
480 layerC = layerOnTopOf layerB "c";
481 in layerC;
482
483 # buildImage without explicit tag
484 bashNoTag = pkgs.dockerTools.buildImage {
485 name = "bash-no-tag";
486 # Not recommended. Use `buildEnv` between copy and packages to avoid file duplication.
487 copyToRoot = pkgs.bashInteractive;
488 };
489
490 # buildLayeredImage without explicit tag
491 bashNoTagLayered = pkgs.dockerTools.buildLayeredImage {
492 name = "bash-no-tag-layered";
493 contents = pkgs.bashInteractive;
494 };
495
496 # buildImage without explicit tag
497 bashNoTagStreamLayered = pkgs.dockerTools.streamLayeredImage {
498 name = "bash-no-tag-stream-layered";
499 contents = pkgs.bashInteractive;
500 };
501
502 # buildLayeredImage with non-root user
503 bashLayeredWithUser =
504 let
505 nonRootShadowSetup = { user, uid, gid ? uid }: with pkgs; [
506 (
507 writeTextDir "etc/shadow" ''
508 root:!x:::::::
509 ${user}:!:::::::
510 ''
511 )
512 (
513 writeTextDir "etc/passwd" ''
514 root:x:0:0::/root:${runtimeShell}
515 ${user}:x:${toString uid}:${toString gid}::/home/${user}:
516 ''
517 )
518 (
519 writeTextDir "etc/group" ''
520 root:x:0:
521 ${user}:x:${toString gid}:
522 ''
523 )
524 (
525 writeTextDir "etc/gshadow" ''
526 root:x::
527 ${user}:x::
528 ''
529 )
530 ];
531 in
532 pkgs.dockerTools.buildLayeredImage {
533 name = "bash-layered-with-user";
534 tag = "latest";
535 contents = [ pkgs.bash pkgs.coreutils ] ++ nonRootShadowSetup { uid = 999; user = "somebody"; };
536 };
537
538 # basic example, with cross compilation
539 cross = let
540 # Cross compile for x86_64 if on aarch64
541 crossPkgs =
542 if pkgs.stdenv.hostPlatform.system == "aarch64-linux" then pkgsCross.gnu64
543 else pkgsCross.aarch64-multiplatform;
544 in crossPkgs.dockerTools.buildImage {
545 name = "hello-cross";
546 tag = "latest";
547 copyToRoot = pkgs.buildEnv {
548 name = "image-root";
549 pathsToLink = [ "/bin" ];
550 paths = [ crossPkgs.hello ];
551 };
552 };
553
554 # layered image where a store path is itself a symlink
555 layeredStoreSymlink =
556 let
557 target = pkgs.writeTextDir "dir/target" "Content doesn't matter.";
558 symlink = pkgs.runCommand "symlink" {} "ln -s ${target} $out";
559 in
560 pkgs.dockerTools.buildLayeredImage {
561 name = "layeredstoresymlink";
562 tag = "latest";
563 contents = [ pkgs.bash symlink ];
564 } // { passthru = { inherit symlink; }; };
565
566 # image with registry/ prefix
567 prefixedImage = pkgs.dockerTools.buildImage {
568 name = "registry-1.docker.io/image";
569 tag = "latest";
570 config.Cmd = [ "${pkgs.hello}/bin/hello" ];
571 };
572
573 # layered image with registry/ prefix
574 prefixedLayeredImage = pkgs.dockerTools.buildLayeredImage {
575 name = "registry-1.docker.io/layered-image";
576 tag = "latest";
577 config.Cmd = [ "${pkgs.hello}/bin/hello" ];
578 };
579
580 # layered image with files owned by a user other than root
581 layeredImageWithFakeRootCommands = pkgs.dockerTools.buildLayeredImage {
582 name = "layered-image-with-fake-root-commands";
583 tag = "latest";
584 contents = [
585 pkgs.pkgsStatic.busybox
586 ];
587 fakeRootCommands = ''
588 mkdir -p ./home/alice
589 chown 1000 ./home/alice
590 ln -s ${pkgs.hello.overrideAttrs (o: {
591 # A unique `hello` to make sure that it isn't included via another mechanism by accident.
592 configureFlags = o.configureFlags or [] ++ [ " --program-prefix=layeredImageWithFakeRootCommands-" ];
593 doCheck = false;
594 })} ./hello
595 '';
596 };
597
598 # tarball consisting of both bash and redis images
599 mergedBashAndRedis = pkgs.dockerTools.mergeImages [
600 bash
601 redis
602 ];
603
604 # tarball consisting of bash (without tag) and redis images
605 mergedBashNoTagAndRedis = pkgs.dockerTools.mergeImages [
606 bashNoTag
607 redis
608 ];
609
610 # tarball consisting of bash and layered image with different owner of the
611 # /home/alice directory
612 mergedBashFakeRoot = pkgs.dockerTools.mergeImages [
613 bash
614 layeredImageWithFakeRootCommands
615 ];
616
617 helloOnRoot = pkgs.dockerTools.streamLayeredImage {
618 name = "hello";
619 tag = "latest";
620 contents = [
621 (pkgs.buildEnv {
622 name = "hello-root";
623 paths = [ pkgs.hello ];
624 })
625 ];
626 config.Cmd = [ "hello" ];
627 };
628
629 helloOnRootNoStore = pkgs.dockerTools.streamLayeredImage {
630 name = "hello";
631 tag = "latest";
632 contents = [
633 (pkgs.buildEnv {
634 name = "hello-root";
635 paths = [ pkgs.hello ];
636 })
637 ];
638 config.Cmd = [ "hello" ];
639 includeStorePaths = false;
640 };
641
642 etc =
643 let
644 inherit (pkgs) lib;
645 nixosCore = (evalMinimalConfig ({ config, ... }: {
646 imports = [
647 pkgs.pkgsModule
648 ../../../nixos/modules/system/etc/etc.nix
649 ];
650 environment.etc."some-config-file" = {
651 text = ''
652 127.0.0.1 localhost
653 ::1 localhost
654 '';
655 # For executables:
656 # mode = "0755";
657 };
658 }));
659 in pkgs.dockerTools.streamLayeredImage {
660 name = "etc";
661 tag = "latest";
662 enableFakechroot = true;
663 fakeRootCommands = ''
664 mkdir -p /etc
665 ${nixosCore.config.system.build.etcActivationCommands}
666 '';
667 config.Cmd = pkgs.writeScript "etc-cmd" ''
668 #!${pkgs.busybox}/bin/sh
669 ${pkgs.busybox}/bin/cat /etc/some-config-file
670 '';
671 };
672
673 # Example export of the bash image
674 exportBash = pkgs.dockerTools.exportImage { fromImage = bash; };
675
676 imageViaFakeChroot = pkgs.dockerTools.streamLayeredImage {
677 name = "image-via-fake-chroot";
678 tag = "latest";
679 config.Cmd = [ "hello" ];
680 enableFakechroot = true;
681 # Crucially, instead of a relative path, this creates /bin, which is
682 # intercepted by fakechroot.
683 # This functionality is not available on darwin as of 2021.
684 fakeRootCommands = ''
685 mkdir /bin
686 ln -s ${pkgs.hello}/bin/hello /bin/hello
687 '';
688 };
689
690 build-image-with-path = buildImage {
691 name = "build-image-with-path";
692 tag = "latest";
693 # Not recommended. Use `buildEnv` between copy and packages to avoid file duplication.
694 copyToRoot = [ pkgs.bashInteractive ./test-dummy ];
695 };
696
697 layered-image-with-path = pkgs.dockerTools.streamLayeredImage {
698 name = "layered-image-with-path";
699 tag = "latest";
700 contents = [ pkgs.bashInteractive ./test-dummy ];
701 };
702
703 build-image-with-architecture = buildImage {
704 name = "build-image-with-architecture";
705 tag = "latest";
706 architecture = "arm64";
707 # Not recommended. Use `buildEnv` between copy and packages to avoid file duplication.
708 copyToRoot = [ pkgs.bashInteractive ./test-dummy ];
709 };
710
711 layered-image-with-architecture = pkgs.dockerTools.streamLayeredImage {
712 name = "layered-image-with-architecture";
713 tag = "latest";
714 architecture = "arm64";
715 contents = [ pkgs.bashInteractive ./test-dummy ];
716 };
717
718 # ensure that caCertificates builds
719 image-with-certs = buildImage {
720 name = "image-with-certs";
721 tag = "latest";
722
723 copyToRoot = pkgs.buildEnv {
724 name = "image-with-certs-root";
725 paths = [
726 pkgs.coreutils
727 pkgs.dockerTools.caCertificates
728 ];
729 };
730
731 config = {
732 };
733 };
734
735 nix-shell-basic = streamNixShellImage {
736 name = "nix-shell-basic";
737 tag = "latest";
738 drv = pkgs.hello;
739 };
740
741 nix-shell-hook = streamNixShellImage {
742 name = "nix-shell-hook";
743 tag = "latest";
744 drv = pkgs.mkShell {
745 shellHook = ''
746 echo "This is the shell hook!"
747 exit
748 '';
749 };
750 };
751
752 nix-shell-inputs = streamNixShellImage {
753 name = "nix-shell-inputs";
754 tag = "latest";
755 drv = pkgs.mkShell {
756 nativeBuildInputs = [
757 pkgs.hello
758 ];
759 };
760 command = ''
761 hello
762 '';
763 };
764
765 nix-shell-pass-as-file = streamNixShellImage {
766 name = "nix-shell-pass-as-file";
767 tag = "latest";
768 drv = pkgs.mkShell {
769 str = "this is a string";
770 passAsFile = [ "str" ];
771 };
772 command = ''
773 cat "$strPath"
774 '';
775 };
776
777 nix-shell-run = streamNixShellImage {
778 name = "nix-shell-run";
779 tag = "latest";
780 drv = pkgs.mkShell {};
781 run = ''
782 case "$-" in
783 *i*) echo This shell is interactive ;;
784 *) echo This shell is not interactive ;;
785 esac
786 '';
787 };
788
789 nix-shell-command = streamNixShellImage {
790 name = "nix-shell-command";
791 tag = "latest";
792 drv = pkgs.mkShell {};
793 command = ''
794 case "$-" in
795 *i*) echo This shell is interactive ;;
796 *) echo This shell is not interactive ;;
797 esac
798 '';
799 };
800
801 nix-shell-writable-home = streamNixShellImage {
802 name = "nix-shell-writable-home";
803 tag = "latest";
804 drv = pkgs.mkShell {};
805 run = ''
806 if [[ "$HOME" != "$(eval "echo ~$(whoami)")" ]]; then
807 echo "\$HOME ($HOME) is not the same as ~\$(whoami) ($(eval "echo ~$(whoami)"))"
808 exit 1
809 fi
810
811 if ! touch $HOME/test-file; then
812 echo "home directory is not writable"
813 exit 1
814 fi
815 echo "home directory is writable"
816 '';
817 };
818
819 nix-shell-nonexistent-home = streamNixShellImage {
820 name = "nix-shell-nonexistent-home";
821 tag = "latest";
822 drv = pkgs.mkShell {};
823 homeDirectory = "/homeless-shelter";
824 run = ''
825 if [[ "$HOME" != "$(eval "echo ~$(whoami)")" ]]; then
826 echo "\$HOME ($HOME) is not the same as ~\$(whoami) ($(eval "echo ~$(whoami)"))"
827 exit 1
828 fi
829
830 if -e $HOME; then
831 echo "home directory exists"
832 exit 1
833 fi
834 echo "home directory doesn't exist"
835 '';
836 };
837
838 nix-shell-build-derivation = streamNixShellImage {
839 name = "nix-shell-build-derivation";
840 tag = "latest";
841 drv = pkgs.hello;
842 run = ''
843 buildDerivation
844 $out/bin/hello
845 '';
846 };
847
848}