on b1aa805 help sign in
.gitignore+1
since splitsnapshots
unifiedsplit
@@ -1 +1,2 @@
1+image.tar.gz
1result
2result
LICENSEdeleted−21
@@ -1,21 +0,0 @@
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+53−92
@@ -1,117 +1,85 @@
1−# nix-container
1+# container-nix
2
2
3A Nix flake that builds an **OCI image** (via
3A Nix flake that builds an **OCI image** (via
4[`nix2container`](https://github.com/nlewo/nix2container)) for running with
4[`nix2container`](https://github.com/nlewo/nix2container)) for running with
5Apple's [`container`](https://github.com/apple/container) CLI on macOS.
5Apple's [`container`](https://github.com/apple/container) CLI on macOS.
6
6
7It's a plain, single-process image — no NixOS, no systemd — defined in
7It's a plain, single-process image — no NixOS, no systemd — defined in
8−[`flake.nix`](./flake.nix). `c start` drops you into a
8+[`flake.nix`](./flake.nix). The default command is `fish` (with a configured
9−[`herdr`](https://herdr.dev) session whose panes use your host login shell
9+prompt), and the image ships a handful of dev/LLM tools: `git`, `jujutsu`,
10−(detected and bundled by `c init`). You choose what else it ships via a
10+`ripgrep`, `fd`, `jq`, `nodejs`, `python3`, a Rust + C toolchain,
11−per-project `container.nix`.
11+`charmbracelet.crush`, `openssh`, and more.
12
12
13## Prerequisites
13## Prerequisites
14
14
15−- [Nix](https://nixos.org/download/) with flakes enabled.
16−- Apple's [`container`](https://github.com/apple/container) CLI installed, with
15+- Apple's `container` CLI installed, with services started:
17− services started: `container system start` (first run downloads a Linux
16+ `container system start` (first run downloads a Linux kernel).
18− kernel).
17+- A **Linux builder** — the image *contents* are Linux binaries and can't be
19−- A **Linux builder** *only if you use packages that aren't in the binary
18+ built on macOS. `internal.iko.soy` (aarch64-linux) is already configured, so
20− cache*. The image is assembled entirely on macOS — the root filesystem is just
19+ `nix` dispatches to it automatically.
21− a host-built symlink tree over the **substituted** Linux store paths — so a
20+
22− fully-cached package set needs no builder. Compiling a Linux package that
21+## Steps
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
22
51−Your **host login shell** (detected by `c init`, bash fallback), **coreutils**,
23+### 1. Build the image archive
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
24
56−Point at a different file with `-c`/`--config`:
25+`nix run` builds the Linux contents (on the remote builder) and writes a tagged
26+OCI archive locally via `skopeo`. Pass the output path; the image is tagged
27+`nixos-container:latest`.
57
28
58```sh
29```sh
59−nix run github:ilyakooo0/nix-container -- init --config envs/ci.nix
30+nix run . -- image.tar.gz
60```
31```
61
32
62−## Quick start
33+### 2. Load it into `container`
63−
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.
66
34
67```sh
35```sh
68−# build the image, load it, and create the container (named after $PWD):
36+container image load --input image.tar.gz
69−nix run github:ilyakooo0/nix-container -- init
37+```
70
38
71−# start it and attach — drops you into a herdr session:
39+### 3. Create and start the container
72−nix run github:ilyakooo0/nix-container -- start
40+
41+```sh
42+container create --name nixos --ssh -it nixos-container:latest
43+container start -ai nixos
73```
44```
74
45
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
46- `--ssh` forwards your host SSH agent socket into the container (so `git` over
79− SSH works with your keys).
47+ SSH etc. works with your keys).
80−- Add more mounts persistently via `mounts` in `container.nix` (above), or
48+- `-it` / `-ai` give an interactive TTY; `start -ai` attaches to it.
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
49
87−Working from a checkout, [`./c init`](./c) / `./c start` are equivalent — and
50+You land in `fish`. Exit the shell to stop the container.
88−`c` can be symlinked onto your `$PATH` and run from any project.
89
51
90## Re-running after a rebuild
52## Re-running after a rebuild
91
53
92−Just run `init` again — it reloads the image and replaces the existing container
54+`container` keeps the loaded image and the created container, so to pick up a
93−(removing the old one first), so there's nothing to clean up:
55+new build, remove the old ones first:
94
56
95```sh
57```sh
96−nix run github:ilyakooo0/nix-container -- init
58+nix run . -- image.tar.gz # rebuild the archive
59+container rm nixos # remove the old container (stop it first if running)
60+container image rm nixos-container:latest
61+container image load --input image.tar.gz
62+container create --name nixos --ssh -it nixos-container:latest
63+container start -ai nixos
97```
64```
98
65
99−## Customize further
66+## Other image destinations
100
67
101−Fork or clone to change what isn't per-project — `config.cmd`/`env` or the image
68+`nix run .#copyTo` is nix2container's generic skopeo wrapper
102−name — in [`flake.nix`](./flake.nix). The flake also exposes build helpers:
69+(`skopeo copy nix:<image> "$@"`) — the argument is any skopeo destination:
103
70
104−- `lib.<system>.copyWith` → a skopeo copy app for a `{ pkgs, nur }: [ ... ]`
71+```sh
105− function, for building/pushing the image anywhere skopeo can write (e.g. a
72+nix run .#copyTo -- docker://ghcr.io/me/nixos:latest # push to a registry
106− registry):
73+nix run .#copyTo -- docker-daemon:nixos-container:latest # local Docker daemon
74+```
75+
76+## Customize
107
77
108− ```sh
78+Edit the `buildImage` call in [`flake.nix`](./flake.nix):
109− drv=$(nix build --no-link --print-out-paths --impure --expr \
79+
110− '(builtins.getFlake "github:ilyakooo0/nix-container").lib.${builtins.currentSystem}.copyWith (import ./container.nix).packages')
80+- Add packages to `copyToRoot.paths`.
111− $drv/bin/copy-to docker://ghcr.io/me/img:latest
81+- Change the default process via `config.cmd`.
112− ```
82+- Add env vars via `config.env`.
113−- `lib.<system>.mkImage <name> <shell>` → the underlying OCI image (`copyWith`
114− defaults these to `nix-container` / `bash`).
115
83
116The flake uses `flake-utils` over `{aarch64,x86_64}-{darwin,linux}`; the host
84The flake uses `flake-utils` over `{aarch64,x86_64}-{darwin,linux}`; the host
117system maps to the matching Linux target automatically (an Intel Mac builds an
85system maps to the matching Linux target automatically (an Intel Mac builds an
@@ -119,15 +87,8 @@ system maps to the matching Linux target automatically (an Intel Mac builds an
119
87
120## How it works
88## How it works
121
89
122−- **Contents** are Linux store paths — downloaded prebuilt from the binary cache
90+- **Contents** (`copyToRoot`) are built from `pkgsLinux` → the Linux builder.
123− (only built on a Linux builder if not cached).
91+- **Assembly** (`nix2container` + the `skopeo` copy) runs on your Mac, so a
124−- **Assembly** runs entirely on your Mac: `copyToRoot` is a *host-arch* `buildEnv`
92+ single `nix run` produces a loadable archive.
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.
128- Apple's `container` runs each container in its own lightweight Linux VM and
93- Apple's `container` runs each container in its own lightweight Linux VM and
129 consumes standard OCI images — no `--privileged` or systemd needed.
94 consumes standard OCI images — no `--privileged` or systemd needed.
130−
131−## License
132−
133−[MIT](./LICENSE).
c+4−82
@@ -1,94 +1,16 @@
1#!/usr/bin/env fish
1#!/usr/bin/env fish
2# Manage a container named after the current directory.
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
3+# c init [extra create args] create it (e.g. c init -v $PWD:/work)
4−# (config from FILE, default ./container.nix)
5−# c start start it and attach
4+# c start start it and attach
6
5
7set -l name (path basename $PWD)
6set -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
7
13switch $argv[1]
8switch $argv[1]
14 case init
9 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" \
10+ container create --name $name --ssh -it $argv[2..-1] nixos-container:latest
84− --tmpfs /tmp --tmpfs /run --memory 8g --cwd /workspace $mounts $argv \
85− $image /bin/herdr session attach "$name-container"
86 case start
11 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
12 container start -ai $name
91 case '*'
13 case '*'
92− echo "usage: c init [-c FILE] [create args] | start" >&2
14+ echo "usage: c init|start" >&2
93 exit 1
15 exit 1
94end
16end
flake.nix+125−113
@@ -72,127 +72,139 @@
72 # Host package set, for the wrapper app below.
72 # Host package set, for the wrapper app below.
73 pkgsHost = nixpkgs.legacyPackages.${system};
73 pkgsHost = nixpkgs.legacyPackages.${system};
74
74
75− # Default image name (for `copyWith`); `c init` passes a per-directory
75+ # skopeo writes the OCI archive's ref.name from the *destination*
76− # name (`nix-container-<dir>`) to `copyWithShell` instead.
76+ # string, not from the image config — so the wrapper app must spell
77+ # these out, else the archive loads as `untagged`.
77− imageName = "nix-container";
78+ imageName = "nixos-container";
78 imageTag = "latest";
79 imageTag = "latest";
79
80
80− # Build the OCI image (named `name`) from a `{ pkgs, nur }: [ ... ]`
81+ # Fish prompt config, copied from smol-nix's mkSmol.nix. Installed at
81− # package function, for the named shell. The image's `cmd` is herdr
82+ # /root/.config/fish/config.fish (fish reads $HOME/.config/fish).
82− # (the session `c start` attaches to); the shell is the default `$SHELL`
83+ fishConfig = pkgsLinux.writeText "config.fish" ''
83− # (what herdr panes spawn) and is added automatically, so `container.nix`
84+ # No welcome banner.
84− # lists only your extras. Nix (+ CA certs) and the ncurses terminfo
85+ set -g fish_greeting
85− # database are always shipped too. Nothing here is fish-specific: the
86+
86− # TERM fixup happens host-side in `c` (passed via `-e TERM` at create).
87+ # Define the prompt as a function so fish renders it before every
87− mkImage =
88+ # command; at top level it would run once at startup and be ignored.
88− name: shell: packages:
89+ function fish_prompt
89− n2c.buildImage {
90+ set -l nix_shell_info
90− inherit name;
91+ if set -q IN_NIX_SHELL; or set -q IN_NIX_RUN
91− tag = imageTag;
92+ set nix_shell_info ' ❄️'
92− inherit arch;
93+ end
93−
94+
94− # A plain, single-process root filesystem. No NixOS, no systemd.
95+ set -l cwd (prompt_pwd)
95− # buildEnv only *symlinks* paths (never runs them), so build it on
96+
96− # the host arch — the tree is arch-neutral and links the
97+ set -l bookmark_info
97− # (substituted) Linux store paths, sparing the Linux builder.
98+ if jj root 2>/dev/null >/dev/null
98− copyToRoot = pkgsHost.buildEnv {
99+ set -l jj_bookmark (jj log -r 'heads(::@ & bookmarks())' -T 'local_bookmarks ++ "\n"' --no-graph 2>/dev/null | tail -1)
99− name = "root";
100+ if test -n "$jj_bookmark"
100− paths =
101+ set bookmark_info ' ' (set_color brmagenta) $jj_bookmark (set_color normal)
101− packages {
102+ end
102− pkgs = pkgsLinux;
103+ end
103− nur = nurPkgs;
104+
104− }
105+ echo -n -s (set_color $fish_color_cwd) $cwd (set_color normal) $bookmark_info ' 🏗️' $nix_shell_info '> '
105− # The shell (cmd + $SHELL), when it exists in nixpkgs.
106+ end
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− };
163− };
107+ '';
164
108
165− # `nix run . -- init|start` runs the bundled `c` manager script. Its
109+ # Lay the config out at the path fish reads.
166− # `init` builds the image from the project's `container.nix` (via
110+ fishRoot = pkgsLinux.runCommand "fish-config-root" { } ''
167− # `lib.copyWithShell`); the script finds the flake from its own (store)
111+ mkdir -p "$out/root/.config/fish"
168− # location, so this works from a checkout or straight from
112+ cp ${fishConfig} "$out/root/.config/fish/config.fish"
169− # `nix run github:…/nix-container`.
170− cApp = pkgsHost.writeShellScriptBin "c" ''
171− exec ${pkgsHost.fish}/bin/fish ${self}/c "$@"
172 '';
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+ ];
169+ };
170+
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+ };
173 in
198 in
174 {
199 {
175 apps = {
200 apps = {
176− # nix run . -- init|start → build+load+create / start a container
201+ # nix run . -- <path> → OCI archive tagged <name>:<tag>,
202+ # loadable with `container image load -i <path>`.
177− default = flake-utils.lib.mkApp { drv = cApp; };
203+ default = flake-utils.lib.mkApp { drv = copyToOCI; };
178− };
179
204
180− # Build helpers take a `{ pkgs, nur }: [ ... ]` packages function (the
205+ # Generic skopeo passthrough for any other destination, e.g.
181− # `packages` attr of a project's `container.nix`). `c init` uses
206+ # nix run .#copyTo -- docker://ghcr.io/me/img:latest
182− # `copyWithShell` (host shell baked in); `copyWith` is the generic form:
207+ copyTo = flake-utils.lib.mkApp { drv = image.copyTo; };
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;
196 };
208 };
197 }
209 }
198 );
210 );
resultnew file+1
@@ -0,0 +1 @@
1+/nix/store/04m5crcxpbg3fhyzsf8152xl8693qyyi-image-nixos-container.json