Add 03-nix-container

[?]
Mar 21, 2023, 4:53 PM
TEQJC3HX2GJBTJWUGW5FXUSPKTPMSHGHFHJI75WMUPZRTGP6GRZQC

Dependencies

Change contents

  • file addition: 03-nix-container (d--r------)
    [2.2]
  • file addition: flake.nix (----------)
    [0.10]
    # This is a Nix flake
    # It is written in the Nix expression language
    {
    description = "Simple flake for simple libcurl example";
    # nixpkgs is the package repository for the Nix package manager
    inputs.nixpkgs.url = "github:NixOS/nixpkgs";
    outputs = { self, nixpkgs }: let
    # In this simple example we choose to build for "x86_64-linux" only
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
    # Declare our own package as a Nix 'derivation'
    wttr-delft = pkgs.stdenv.mkDerivation rec {
    # Our package name
    name = "wttr-delft";
    # Where the source code lives
    src = builtins.path { path = ../src; name = name; };
    # Dependencies
    buildInputs = [
    pkgs.curl.dev
    ];
    # The source code contains only the C file, so we 'manually' compile
    # Note: If we were using Make/CMake/autoconf, the mkDerivation function
    # could handle those automatically.
    # gcc is available by default in pkgs.stdenv.mkDerivation
    buildPhase = "gcc -lcurl -o wttr-delft ./simple.c";
    # Installing is just copying the executable
    installPhase = "mkdir -p $out/bin; install -t $out/bin wttr-delft";
    };
    # Docker image containing only wttr-delft
    wttr-delft-container = pkgs.dockerTools.buildLayeredImage {
    name = "wttr-delft";
    tag = "nix";
    # created = "now";
    contents = [
    wttr-delft
    ];
    config = {
    Cmd = [
    "${wttr-delft}/bin/wttr-delft"
    ];
    # Needed for curl to work
    Env = [
    "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
    ];
    };
    };
    # Development shell for interacting with containers
    # Based on https://gist.github.com/adisbladis/187204cb772800489ee3dac4acdd9947
    podman-devshell = let
    # Provides a script that copies/creates files that are required for rootless podman
    podmanSetupScript = let
    registriesConf = pkgs.writeText "registries.conf" ''
    [registries.search]
    registries = ['docker.io']
    [registries.block]
    registries = []
    '';
    storageConf = pkgs.writeText "storage.conf" ''
    [storage]
    driver = "overlay"
    # rootless_storage_path="$XDG_DATA_HOME/containers/storage"
    '';
    in pkgs.writeShellScript "podman-setup" ''
    # Dont overwrite customised configuration
    if ! test -f ~/.config/containers/policy.json; then
    echo "Installing missing ~/.config/containers/policy.json"
    install -Dm644 ${pkgs.skopeo.src}/default-policy.json ~/.config/containers/policy.json
    fi
    if ! test -f ~/.config/containers/registries.conf; then
    echo "Installing missing ~/.config/containers/registries.conf"
    install -Dm644 ${registriesConf} ~/.config/containers/registries.conf
    fi
    if ! test -f ~/.config/containers/storage.conf; then
    echo "Installing missing ~/.config/containers/storage.conf"
    install -Dm644 ${storageConf} ~/.config/containers/storage.conf
    fi
    '';
    # Provides a fake "docker" binary mapping to podman
    dockerCompat = pkgs.runCommandNoCC "docker-podman-compat" {} ''
    mkdir -p $out/bin
    ln -s ${pkgs.podman}/bin/podman $out/bin/docker
    '';
    in pkgs.mkShell {
    name = "podman";
    buildInputs = with pkgs; [
    podman # Manage pods, containers and images
    runc # Container runtime
    conmon # Container runtime monitor
    skopeo # Interact with container registry
    slirp4netns # User-mode networking for unprivileged namespaces
    fuse-overlayfs # CoW for images, much faster than default vfs
    dockerCompat # Aliases for docker / podman
    ];
    shellHook = ''
    # Install configuration required for rootless podman
    ${podmanSetupScript}
    if ! grep -q "^''${USER}:" /etc/subuid; then
    echo "No subuid range defined for user, consider running 'sudo usermod --add-subuids 10000-75535 ''${USER}' to allow rootless podman to work"
    fi
    '';
    };
    in
    # These are the flake outputs, i.e. what we can consume
    {
    packages.x86_64-linux = {
    default = wttr-delft;
    container = wttr-delft-container;
    };
    devShells.x86_64-linux = {
    podman = podman-devshell;
    };
    };
    }
  • file addition: flake.lock (----------)
    [0.10]
    {
    "nodes": {
    "nixpkgs": {
    "locked": {
    "lastModified": 1679396235,
    "narHash": "sha256-RjmNVFuZQ2e6u35B98JcY9IzVDtZb3d4QcbtfLtNWkE=",
    "owner": "NixOS",
    "repo": "nixpkgs",
    "rev": "008ce261a7e3c532e792cb8e39482f2cc1b192f5",
    "type": "github"
    },
    "original": {
    "owner": "NixOS",
    "repo": "nixpkgs",
    "type": "github"
    }
    },
    "root": {
    "inputs": {
    "nixpkgs": "nixpkgs"
    }
    }
    },
    "root": "root",
    "version": 7
    }
  • file addition: demo.sh (---r------)
    [0.10]
    #!/usr/bin/env bash
    # shellcheck disable=SC1010,SC2288
    set -Eeuo pipefail
    dir="$(dirname "${BASH_SOURCE[0]}")"
    source "${dir}/../libdemo/libdemo.sh"
    h Putting wttr-delft into a container
    , Expanding on the previous nix flake makes building a OCI compliant \(Docker\) image easy:
    x pygmentize "${dir}/flake.nix"
    h We now choose the \'container\' package we defined:
    x nix build "${dir}#container" -L -o "${dir}/result-container"
    x nix build "${dir}#container" -L -o "${dir}/result-container --rebuild"
    x ls -lhH "${dir}/result-container"
    x nix develop "${dir}#podman" --command "${dir}/demo-inside-nix-develop.sh"
  • file addition: demo-inside-nix-develop.sh (---r------)
    [0.10]
    #!/usr/bin/env bash
    set -Eeuo pipefail
    dir="$(dirname "${BASH_SOURCE[0]}")"
    source "${dir}/../libdemo/libdemo.sh"
    h Now we are inside a development shell that has rootless podman.
    , We can manipulate containers just like docker could.
    n We have added the \'dockerCompat\' package so we can use the \'docker\' command instead of \'podman\'.
    h So we start by loading the container we just made into the registry:
    x docker load -i ./result-container
    h We can see it\'s there:
    x docker image ls | grep "wttr-delft\|^REPOSITORY"
    h And now we can run it:
    x docker run -it localhost/wttr-delft:nix
    h The image is very minimal, e.g. there is no interactive shell:
    f podman run --entrypoint sh -it localhost/wttr-delft:nix
    h We have running containers:
    x podman ps --all --storage | grep "wttr-delft\|^CONTAINER ID"
    h Let\'s kill them and remove them:
    x podman ps --all --storage | tail -n +2 | grep wttr-delft | awk "{print \$1}" | xargs podman rm
    x podman image ls | tail -n +2 | grep wttr-delft | awk "{print \$3}" | xargs podman image rm -f