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