at 23.11-beta 848 lines 23 kB view raw
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}