on master help sign in
6 files changed+336−168
since splitsnapshots
unifiedsplit
.gitignore−1 LICENSE+21 README.md+108−41 c+94 flake.nix+113−125 result−1
.gitignore−1
@@ -1,2 +1 @@
1−image.tar.gz
21result
LICENSEnew file+21
@@ -0,0 +1,21 @@
1+MIT License
2+
3+Copyright (c) 2026 iko
4+
5+Permission is hereby granted, free of charge, to any person obtaining a copy
6+of this software and associated documentation files (the "Software"), to deal
7+in the Software without restriction, including without limitation the rights
8+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+copies of the Software, and to permit persons to whom the Software is
10+furnished to do so, subject to the following conditions:
11+
12+The above copyright notice and this permission notice shall be included in all
13+copies or substantial portions of the Software.
14+
15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+SOFTWARE.
README.md+108−41
@@ -1,66 +1,133 @@
1−# container-nix
1+# nix-container
22
33A Nix flake that builds an **OCI image** (via
44[`nix2container`](https://github.com/nlewo/nix2container)) for running with
55Apple's [`container`](https://github.com/apple/container) CLI on macOS.
66
77It's a plain, single-process image — no NixOS, no systemd — defined in
8−[`flake.nix`](./flake.nix). `nix2container` produces a real OCI image directly,
9−so there's no `dockerTools` docker-archive → OCI conversion step.
8+[`flake.nix`](./flake.nix). `c start` drops you into a
9+[`herdr`](https://herdr.dev) session whose panes use your host login shell
10+(detected and bundled by `c init`). You choose what else it ships via a
11+per-project `container.nix`.
12+
13+## Prerequisites
14+
15+- [Nix](https://nixos.org/download/) with flakes enabled.
16+- Apple's [`container`](https://github.com/apple/container) CLI installed, with
17+ services started: `container system start` (first run downloads a Linux
18+ kernel).
19+- A **Linux builder** *only if you use packages that aren't in the binary
20+ cache*. The image is assembled entirely on macOS — the root filesystem is just
21+ a host-built symlink tree over the **substituted** Linux store paths — so a
22+ fully-cached package set needs no builder. Compiling a Linux package that
23+ `cache.nixos.org` doesn't have does, though: use a [remote builder][builders]
24+ or, on Apple Silicon, the `nix-darwin` `linux-builder`.
25+
26+[builders]: https://nix.dev/manual/nix/latest/advanced-topics/distributed-builds
27+
28+## Packages
29+
30+`init` builds the image from a **`container.nix`** in the current directory — an
31+attrset with a `packages` function (`{ pkgs, nur }` returning the package list;
32+`nur` is [NUR](https://github.com/nix-community/NUR), for packages outside
33+nixpkgs) and an optional `mounts` list. It is **required**; there is no default.
34+
35+```nix
36+# ./container.nix
37+{
38+ packages = { pkgs, nur }: with pkgs; [
39+ git
40+ go
41+ nur.repos.charmbracelet.crush
42+ ];
43+ # Extra "host:container" bind mounts, on top of $PWD → /workspace. A leading
44+ # ~/ in the host path expands to $HOME. Optional.
45+ mounts = [
46+ "~/data:/data"
47+ ];
48+}
49+```
50+
51+Your **host login shell** (detected by `c init`, bash fallback), **coreutils**,
52+[**herdr**](https://herdr.dev) (the session `c start` launches), **Nix** itself
53+(with CA certs and `nix-command`/`flakes` enabled, single-user), and the ncurses
54+**terminfo** database are always included — no need to list them.
55+
56+Point at a different file with `-c`/`--config`:
57+
58+```sh
59+nix run github:ilyakooo0/nix-container -- init --config envs/ci.nix
60+```
1061
11−- Image contents: **aarch64-linux** (built on your remote Linux builder).
12−- The image is assembled/copied from your **Mac** (aarch64-darwin), so a single
13− `nix run` does the whole thing.
62+## Quick start
1463
15−## Build & load into Apple `container`
64+No clone needed — `nix run` drives everything. Run it from a project directory
65+that holds a `container.nix`; the container is named after that directory.
1666
1767```sh
18−# Write the image to an OCI archive (runs skopeo locally; builds the
19−# aarch64-linux contents on your remote builder automatically):
20−nix run . -- oci-archive:nixos.tar:nixos-container:latest
21−
22−# Make sure the container services are running (one-time kernel download
23−# on first use), then load and run:
24−container system start
25−container image load -i nixos.tar
26−container run -it nixos-container:latest # default cmd: /bin/bash
27−container run --rm nixos-container:latest /bin/sh -c 'uname -m' # a one-off command
68+# build the image, load it, and create the container (named after $PWD):
69+nix run github:ilyakooo0/nix-container -- init
70+
71+# start it and attach — drops you into a herdr session:
72+nix run github:ilyakooo0/nix-container -- start
2873```
2974
30−Note: Apple's `container run` takes the command **directly after the image** —
31−there is no `--` separator (a `--` is parsed as the executable name). The image
32−sets `config.cmd` (not `entrypoint`), so the command you pass *replaces* the
33−default `/bin/bash` instead of being appended to it.
75+- `init` builds the OCI archive in a temp dir, loads it into `container`,
76+ deletes the temp file, then (re)creates the container. It mounts the current
77+ directory at `/workspace` (the container's working directory).
78+- `--ssh` forwards your host SSH agent socket into the container (so `git` over
79+ SSH works with your keys).
80+- Add more mounts persistently via `mounts` in `container.nix` (above), or
81+ ad-hoc by passing them through to `create` (mounts can only be set at creation):
82+
83+ ```sh
84+ nix run github:ilyakooo0/nix-container -- init -v $HOME/data:/data
85+ ```
86+
87+Working from a checkout, [`./c init`](./c) / `./c start` are equivalent — and
88+`c` can be symlinked onto your `$PATH` and run from any project.
3489
35−The default app is nix2container's generic skopeo wrapper
36−(`skopeo copy nix:<image> "$@"`), so the argument is any skopeo destination —
37−here `oci-archive:<path>:<name>:<tag>`.
90+## Re-running after a rebuild
3891
39−### Other destinations
92+Just run `init` again — it reloads the image and replaces the existing container
93+(removing the old one first), so there's nothing to clean up:
4094
4195```sh
42−nix run . -- docker://ghcr.io/me/nixos:latest # push to a registry
43−nix run .#image.copyToDockerDaemon # local Docker
44−nix run .#image.copyToPodman # local Podman
45−nix run .#image.copyToRegistry # registry (uses image name/tag)
96+nix run github:ilyakooo0/nix-container -- init
4697```
4798
48−## Customize
99+## Customize further
49100
50−Edit the `buildImage` call in [`flake.nix`](./flake.nix):
101+Fork or clone to change what isn't per-project — `config.cmd`/`env` or the image
102+name — in [`flake.nix`](./flake.nix). The flake also exposes build helpers:
51103
52−- Add packages to `copyToRoot.paths`.
53−- Set the process via `config.entrypoint` / `config.cmd`.
54−- Add env vars via `config.env`.
104+- `lib.<system>.copyWith` → a skopeo copy app for a `{ pkgs, nur }: [ ... ]`
105+ function, for building/pushing the image anywhere skopeo can write (e.g. a
106+ registry):
55107
56−The flake is structured with `flake-utils` over `{aarch64,x86_64}-{darwin,linux}`;
57−the host system maps to the matching Linux target automatically (e.g. an Intel
58−Mac builds an `amd64` image), so there's nothing to change per-arch.
108+ ```sh
109+ drv=$(nix build --no-link --print-out-paths --impure --expr \
110+ '(builtins.getFlake "github:ilyakooo0/nix-container").lib.${builtins.currentSystem}.copyWith (import ./container.nix).packages')
111+ $drv/bin/copy-to docker://ghcr.io/me/img:latest
112+ ```
113+- `lib.<system>.mkImage <name> <shell>` → the underlying OCI image (`copyWith`
114+ defaults these to `nix-container` / `bash`).
59115
60−## Notes
116+The flake uses `flake-utils` over `{aarch64,x86_64}-{darwin,linux}`; the host
117+system maps to the matching Linux target automatically (an Intel Mac builds an
118+`amd64` image), so there's nothing to change per-arch.
61119
62−- Building Linux container contents on macOS requires a Linux builder. Yours is
63− already configured (`internal.iko.soy`, aarch64-linux), so `nix run` picks it
64− up automatically.
120+## How it works
121+
122+- **Contents** are Linux store paths — downloaded prebuilt from the binary cache
123+ (only built on a Linux builder if not cached).
124+- **Assembly** runs entirely on your Mac: `copyToRoot` is a *host-arch* `buildEnv`
125+ symlink tree over those Linux paths (symlinks are arch-neutral), and
126+ `nix2container` + `skopeo` package it — so for a cached set, `init` produces a
127+ loadable Linux image with no Linux build at all.
65128- Apple's `container` runs each container in its own lightweight Linux VM and
66129 consumes standard OCI images — no `--privileged` or systemd needed.
130+
131+## License
132+
133+[MIT](./LICENSE).
cnew file+94
@@ -0,0 +1,94 @@
1+#!/usr/bin/env fish
2+# Manage a container named after the current directory.
3+# c init [-c FILE] [extra create args] build + load the image, then (re)create it
4+# (config from FILE, default ./container.nix)
5+# c start start it and attach
6+
7+set -l name (path basename $PWD)
8+# The flake lives next to this script (resolve symlinks so it works from $PATH too).
9+set -l flake (path dirname (path resolve (status filename)))
10+# Per-directory image ref this script loads and runs (archive tag + `create`).
11+set -l image "nix-container-$name:latest"
12+
13+switch $argv[1]
14+ case init
15+ # -c/--config overrides the default ./container.nix; leftover args (e.g.
16+ # mounts) are forwarded to `container create`.
17+ argparse --ignore-unknown 'c/config=' -- $argv[2..-1]
18+ or exit 1
19+ set -l config container.nix
20+ if set -q _flag_config
21+ set config $_flag_config
22+ end
23+
24+ if not test -e $config
25+ echo "c: config file not found: $config" >&2
26+ echo " create one ('{ packages = { pkgs, nur }: [ ... ]; mounts = [ ]; }') or pass -c FILE" >&2
27+ exit 1
28+ end
29+
30+ # Host login shell (by name): added to the image automatically and baked
31+ # in as the cmd + default $SHELL (what herdr panes etc. spawn), so it
32+ # needn't be listed in container.nix. Falls back to bash.
33+ set -l shell bash
34+ test -n "$SHELL"; and set shell (path basename $SHELL)
35+
36+ # Build an image with the config's `packages` (plus the shell) into a
37+ # temp dir, load it, then clean up.
38+ set -l tmp (mktemp -d)
39+ set -l archive $tmp/image.tar.gz
40+ set -lx NIX_CONTAINER_CONFIG (path resolve $config)
41+ set -l expr "(builtins.getFlake \"$flake\").lib.\${builtins.currentSystem}.copyWithShell \"nix-container-$name\" \"$shell\" (import (/. + builtins.getEnv \"NIX_CONTAINER_CONFIG\")).packages"
42+ set -l copyer (nix build --impure --no-link --print-out-paths --expr "$expr")
43+ set -l rc $status
44+ if test $rc -eq 0
45+ $copyer/bin/copy-to "oci-archive:$archive:$image"
46+ set rc $status
47+ end
48+ if test $rc -eq 0
49+ container image load --input $archive
50+ set rc $status
51+ end
52+
53+ rm -rf $tmp
54+ test $rc -eq 0; or exit $rc
55+
56+ # Mount the project at /workspace (the default cwd), plus any extra
57+ # mounts from the config (`mounts = [ "host:container" … ]`). A leading
58+ # ~/ in the host path expands to $HOME (nix leaves it literal).
59+ set -l mounts -v "$PWD:/workspace"
60+ for m in (nix eval --impure --raw --expr "builtins.concatStringsSep \"\n\" ((import (/. + builtins.getEnv \"NIX_CONTAINER_CONFIG\")).mounts or [])")
61+ set -a mounts -v (string replace -r '^~/' "$HOME/" -- $m)
62+ end
63+
64+ # TERM to bake into the container env (`-e TERM`): the runtime hands the
65+ # `start -ai` session a bare "xterm", so set the host's real terminal,
66+ # mapped to an entry the bundled ncurses ships — Ghostty reports
67+ # "xterm-ghostty", which ncurses ships as "ghostty" — falling back to
68+ # xterm-256color for an empty or bare-"xterm" value.
69+ set -l term xterm-256color
70+ if test "$TERM" = xterm-ghostty
71+ set term ghostty
72+ else if test -n "$TERM"; and test "$TERM" != xterm
73+ set term $TERM
74+ end
75+
76+ # Replace any existing container of the same name, then create it running
77+ # herdr in a session named after the project (`<dir>-container`). This
78+ # overrides the image's default plain-herdr cmd; `c start` attaches to it.
79+ container rm --force $name 2>/dev/null
80+ # The image only lays down /bin and /etc, so /tmp and /run don't exist;
81+ # without them anything that writes temp files (herdr, build tools, …)
82+ # fails with ENOENT. Mount writable tmpfs at both.
83+ container create --name $name --ssh -it -e "TERM=$term" \
84+ --tmpfs /tmp --tmpfs /run --memory 8g --cwd /workspace $mounts $argv \
85+ $image /bin/herdr session attach "$name-container"
86+ case start
87+ # Start the container and attach to its cmd (herdr). TERM was baked into
88+ # the container env at create time (`-e TERM`), which survives this path.
89+ # Exiting herdr (PID1) stops the container; `c start` boots it again.
90+ container start -ai $name
91+ case '*'
92+ echo "usage: c init [-c FILE] [create args] | start" >&2
93+ exit 1
94+end
flake.nix+113−125
@@ -72,139 +72,127 @@
7272 # Host package set, for the wrapper app below.
7373 pkgsHost = nixpkgs.legacyPackages.${system};
7474
75− # skopeo writes the OCI archive's ref.name from the *destination*
76− # string, not from the image config — so the wrapper app must spell
77− # these out, else the archive loads as `untagged`.
78− imageName = "nixos-container";
75+ # Default image name (for `copyWith`); `c init` passes a per-directory
76+ # name (`nix-container-<dir>`) to `copyWithShell` instead.
77+ imageName = "nix-container";
7978 imageTag = "latest";
8079
81− # Fish prompt config, copied from smol-nix's mkSmol.nix. Installed at
82− # /root/.config/fish/config.fish (fish reads $HOME/.config/fish).
83− fishConfig = pkgsLinux.writeText "config.fish" ''
84− # No welcome banner.
85− set -g fish_greeting
86−
87− # Define the prompt as a function so fish renders it before every
88− # command; at top level it would run once at startup and be ignored.
89− function fish_prompt
90− set -l nix_shell_info
91− if set -q IN_NIX_SHELL; or set -q IN_NIX_RUN
92− set nix_shell_info ' ❄️'
93− end
94−
95− set -l cwd (prompt_pwd)
96−
97− set -l bookmark_info
98− if jj root 2>/dev/null >/dev/null
99− set -l jj_bookmark (jj log -r 'heads(::@ & bookmarks())' -T 'local_bookmarks ++ "\n"' --no-graph 2>/dev/null | tail -1)
100− if test -n "$jj_bookmark"
101− set bookmark_info ' ' (set_color brmagenta) $jj_bookmark (set_color normal)
102− end
103− end
104−
105− echo -n -s (set_color $fish_color_cwd) $cwd (set_color normal) $bookmark_info ' 🏗️' $nix_shell_info '> '
106− end
107− '';
108−
109− # Lay the config out at the path fish reads.
110− fishRoot = pkgsLinux.runCommand "fish-config-root" { } ''
111− mkdir -p "$out/root/.config/fish"
112− cp ${fishConfig} "$out/root/.config/fish/config.fish"
113− '';
114−
115− image = n2c.buildImage {
116− name = imageName;
117− tag = imageTag;
118− inherit arch;
119−
120− # A plain, single-process root filesystem. No NixOS, no systemd.
121− copyToRoot = pkgsLinux.buildEnv {
122− name = "root";
123− paths = with pkgsLinux; [
124− bashInteractive
125− fish
126− fishRoot
127− openssh
128− coreutils-full
129− btop
130− jujutsu
131− zellij
132− micro
133− helix
134− nurPkgs.repos.charmbracelet.crush
135−
136− # LLM tools
137− git
138− ripgrep
139− fd
140− jq
141− curl
142− wget
143− gnused
144− gnugrep
145− gawk
146− findutils
147− gnutar
148− gzip
149− unzip
150− less
151− which
152− tree
153− nodejs
154− python3
155−
156− # rust
157− rustc
158− cargo
159− rustfmt
160− clippy
161−
162− # C toolchain — rustc links final binaries through `cc`/`ld`.
163− gcc # provides cc/gcc; pulls in binutils (ld) via its closure
164− ];
165− pathsToLink = [
166− "/bin"
167− "/root"
168− ];
80+ # Build the OCI image (named `name`) from a `{ pkgs, nur }: [ ... ]`
81+ # package function, for the named shell. The image's `cmd` is herdr
82+ # (the session `c start` attaches to); the shell is the default `$SHELL`
83+ # (what herdr panes spawn) and is added automatically, so `container.nix`
84+ # lists only your extras. Nix (+ CA certs) and the ncurses terminfo
85+ # database are always shipped too. Nothing here is fish-specific: the
86+ # TERM fixup happens host-side in `c` (passed via `-e TERM` at create).
87+ mkImage =
88+ name: shell: packages:
89+ n2c.buildImage {
90+ inherit name;
91+ tag = imageTag;
92+ inherit arch;
93+
94+ # A plain, single-process root filesystem. No NixOS, no systemd.
95+ # buildEnv only *symlinks* paths (never runs them), so build it on
96+ # the host arch — the tree is arch-neutral and links the
97+ # (substituted) Linux store paths, sparing the Linux builder.
98+ copyToRoot = pkgsHost.buildEnv {
99+ name = "root";
100+ paths =
101+ packages {
102+ pkgs = pkgsLinux;
103+ nur = nurPkgs;
104+ }
105+ # The shell (cmd + $SHELL), when it exists in nixpkgs.
106+ ++ pkgsLinux.lib.optional (pkgsLinux ? ${shell}) pkgsLinux.${shell}
107+ ++ [
108+ pkgsLinux.nix
109+ pkgsLinux.cacert
110+ # Basic userland (ls, cat, cp, sleep, …) so the container is
111+ # usable out of the box and tools that shell out don't fail.
112+ pkgsLinux.coreutils-full
113+ # Networking glue glibc needs: /etc/nsswitch.conf (+passwd,
114+ # group) so DNS/host lookups resolve, and /etc/protocols,
115+ # /etc/services. Without these, hostname resolution fails.
116+ pkgsLinux.fakeNss
117+ pkgsLinux.iana-etc
118+ # The terminfo database (+ tput/clear/reset) so TUIs find the
119+ # entry for whatever TERM `c` passes in and render correctly.
120+ pkgsLinux.ncurses
121+ # The session `c start` always launches.
122+ pkgsLinux.herdr
123+ ];
124+ # Link all of /etc so the above files (nsswitch.conf, protocols,
125+ # services, passwd, group, ssl certs) are present.
126+ pathsToLink = [
127+ "/bin"
128+ "/etc"
129+ ];
130+ };
131+
132+ initializeNixDatabase = true;
133+
134+ config = {
135+ # `cmd` (not `entrypoint`): the default command, *replaced* by any
136+ # command passed to `container run/create`. Plain herdr here;
137+ # `c init` overrides it with `herdr session attach <dir>-container` so
138+ # the session is named per project. `c start` attaches via
139+ # `container start -ai`; exiting herdr (PID1) stops the container.
140+ cmd = [ "/bin/herdr" ];
141+ env = [
142+ "PATH=/bin"
143+ "HOME=/root"
144+ # Default shell for tools that spawn one (herdr panes, etc.).
145+ "SHELL=/bin/${shell}"
146+ # Marker so shells/scripts can detect they're in here.
147+ "NIX_CONTAINER=1"
148+ # Advertise truecolor for 24-bit-aware tools; `c` passes the
149+ # resolved TERM via -e (the runtime would otherwise force xterm).
150+ "COLORTERM=truecolor"
151+ # A UTF-8 locale so tools handle multibyte/wide characters
152+ # correctly. glibc ships C.UTF-8 built in, so this needs no
153+ # locale-archive.
154+ "LANG=C.UTF-8"
155+ # CA trust for every TLS client (curl/git/…) and Nix.
156+ "SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt"
157+ "NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt"
158+ # Make the bundled Nix usable: flake commands on, and
159+ # single-user (no daemon/nixbld).
160+ "NIX_CONFIG=experimental-features = nix-command flakes\nbuild-users-group =\nsandbox = false"
161+ ];
162+ };
169163 };
170164
171− initializeNixDatabase = true;
172−
173− config = {
174− # `cmd` (not `entrypoint`): it's the default command and is
175− # *replaced* by `container run … -- <cmd>`. An entrypoint would be
176− # prepended instead, so `run … -- /bin/sh` would become
177− # `/bin/bash /bin/sh` and fail with "cannot execute binary file".
178− cmd = [ "/bin/fish" ];
179− env = [
180− "PATH=/bin"
181− # fish reads its prompt from $HOME/.config/fish/config.fish.
182− "HOME=/root"
183− ];
184− };
185− };
186−
187− # `nix run . -- <path>` writes an OCI archive tagged
188− # <imageName>:<imageTag>. The raw `image.copyTo` is a passthrough
189− # (`skopeo copy nix:<image> "$@"`), so an `oci-archive:<path>` with no
190− # ref loads as `untagged`; this bakes the ref into the destination.
191− copyToOCI = pkgsHost.writeShellApplication {
192− name = "copy-to-oci";
193− text = ''
194− out="''${1:-image.tar}"
195− exec ${image.copyTo}/bin/copy-to "oci-archive:$out:${imageName}:${imageTag}"
196− '';
197− };
165+ # `nix run . -- init|start` runs the bundled `c` manager script. Its
166+ # `init` builds the image from the project's `container.nix` (via
167+ # `lib.copyWithShell`); the script finds the flake from its own (store)
168+ # location, so this works from a checkout or straight from
169+ # `nix run github:…/nix-container`.
170+ cApp = pkgsHost.writeShellScriptBin "c" ''
171+ exec ${pkgsHost.fish}/bin/fish ${self}/c "$@"
172+ '';
198173 in
199174 {
200175 apps = {
201− # nix run . -- <path> → OCI archive tagged <name>:<tag>,
202− # loadable with `container image load -i <path>`.
203− default = flake-utils.lib.mkApp { drv = copyToOCI; };
176+ # nix run . -- init|start → build+load+create / start a container
177+ default = flake-utils.lib.mkApp { drv = cApp; };
178+ };
204179
205− # Generic skopeo passthrough for any other destination, e.g.
206− # nix run .#copyTo -- docker://ghcr.io/me/img:latest
207− copyTo = flake-utils.lib.mkApp { drv = image.copyTo; };
180+ # Build helpers take a `{ pkgs, nur }: [ ... ]` packages function (the
181+ # `packages` attr of a project's `container.nix`). `c init` uses
182+ # `copyWithShell` (host shell baked in); `copyWith` is the generic form:
183+ # (builtins.getFlake "github:…/nix-container")
184+ # .lib.<system>.copyWith (import ./container.nix).packages
185+ lib = {
186+ inherit mkImage;
187+ # Build the image's `copyTo` script (a skopeo-copy wrapper) from a
188+ # `{ pkgs, nur }: [ ... ]` function, named `imageName`. Defaults the
189+ # shell (cmd + $SHELL) to bash; use `copyWithShell` to pick another.
190+ copyWith = packages: (mkImage imageName "bash" packages).copyTo;
191+ # Like `copyWith`, but for the given image `name` and shell — `c init`
192+ # passes `nix-container-<dir>` and the host login shell, which is added
193+ # to the image and used as cmd + $SHELL without being listed in
194+ # `container.nix`.
195+ copyWithShell = name: shell: packages: (mkImage name shell packages).copyTo;
208196 };
209197 }
210198 );
resultdeleted−1
@@ -1 +0,0 @@
1−/nix/store/04m5crcxpbg3fhyzsf8152xl8693qyyi-image-nixos-container.json