diff options
| author | Mike Wild <mike@mikeanthonywild.com> | 2026-08-25 23:04:10 -0500 |
|---|---|---|
| committer | Mike Wild <mike@mikeanthonywild.com> | 2026-08-25 23:04:10 -0500 |
| commit | 025a365a23f5ed2b3df4df71cbff9689575968d9 (patch) | |
| tree | 1a1f93de4163a3a452d0dd4ed4499fe2084d2db7 /README.md | |
| parent | 2a9ca0577ecdbee8b5a4bc8886c112dbc4260eab (diff) | |
Split per-app dataset into OS/data layers, add skiff rebuild
Each app now gets two ZFS datasets - a disposable OS layer
(zroot/skiff/appbase/<app>) cloned from base, and a persistent data
layer (zroot/skiff/appdata/<app>) holding releases/current/env/
meta.json/data.db. `skiff rebuild --app|--all` discards and reclones
the OS layer to pick up an OS/toolchain/config-template upgrade,
guarded by the same snapshot-and-rollback safety net as deploy and
config changes; the data layer is never touched.
Also fixes stale docs (builds already run via jexec inside the jail,
not on the host; --iface already auto-aliases the jail's IP, so the
manual ifconfig step and its troubleshooting entry are gone) found
while updating the same sections for this feature.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 45 |
1 files changed, 37 insertions, 8 deletions
@@ -20,10 +20,10 @@ needs to provide](#what-an-app-needs-to-provide). - `jail_enable="YES"` in `/etc/rc.conf` (`sysrc jail_enable=YES`) - `service jail start`/`restart` refuse to run without it - Whatever toolchain your apps' Makefiles invoke to build - `go`, `python`, - `rustc`, `node`, etc. - installed on the **host** (builds run outside the - jail; see [One-time host setup](#one-time-host-setup)). `make` itself is - already in FreeBSD base (bmake), so it's the one build tool Skiff never - asks you to install. + `rustc`, `node`, etc. - baked into the base jail image (see [One-time host + setup](#one-time-host-setup)); builds run inside the jail via `jexec`, not + on the host itself. `make` itself is already in FreeBSD base (bmake), so + it's the one build tool Skiff never asks you to install. ## One-time host setup @@ -34,16 +34,28 @@ needs to provide](#what-an-app-needs-to-provide). # zfs create -o mountpoint=/skiff/base zroot/skiff/base # bsdinstall jail /skiff/base # zfs snapshot zroot/skiff/base@ready -# zfs create -o mountpoint=/skiff/apps zroot/skiff/apps +# zfs create -o mountpoint=none zroot/skiff/appbase +# zfs create -o mountpoint=none zroot/skiff/appdata +# mkdir -p /skiff/apps ``` `ready` is the snapshot every app's dataset gets cloned from. Re-snapshot under a new tag after patching the base (e.g. `security-2026-08`) and pass `--base-snapshot` to `new-app` to pick it up. -`zroot/skiff/apps` must exist as its own dataset, not a plain directory - -`new-app` clones straight into it (`zroot/skiff/apps/<name>`), and `zfs -clone` requires the parent dataset to already exist. +`zroot/skiff/appbase` and `zroot/skiff/appdata` must each exist as their own +dataset, not a plain directory - `new-app` clones/creates straight into them +(`zroot/skiff/appbase/<name>`, `zroot/skiff/appdata/<name>`), and `zfs +clone`/`zfs create` require the parent dataset to already exist. Their own +mountpoint doesn't matter (`none` is fine) since every per-app dataset sets +its own explicit mountpoint under `/skiff/apps/<name>` - `appbase/<name>` at +`/skiff/apps/<name>` itself (the jail's root), `appdata/<name>` at +`/skiff/apps/<name>/app`. `/skiff/apps` itself is a plain directory, like +`/skiff/repos` - nothing needs to be a dataset at that exact path. + +Keeping the OS layer (`appbase`) and the app's persistent data (`appdata`) +on separate datasets is what lets `skiff rebuild` destroy and reclone the +former without any risk to the latter. ### Repos directory @@ -125,6 +137,23 @@ target** - ZFS can't roll back past one otherwise. Rolling back to an old snapshot permanently discards the ability to return to anything deployed in between; there's no separate "undo the rollback." +### Rebuilding a jail + +``` +# skiff rebuild --app myapp +# skiff rebuild --all +``` + +Discards the app's OS layer (`/etc`, `/usr`, `/bin`, `jail.conf`, the jail's +rc.d script, `dma.conf`) and reclones it fresh from the base image, leaving +`/app` (releases, current, env, `meta.json`, `data.db`) completely +untouched - the two live on separate ZFS datasets. Use this to pick up a +patched/upgraded base image (`--base-snapshot`) on an app that already +exists, or to regenerate stale jail config after a Skiff upgrade, without +touching the app's own data. Guarded exactly like a deploy: the old OS +layer is kept until the rebuilt jail passes its health check, and swapped +back automatically if it doesn't. + ## What an app needs to provide A `Makefile` in the repo root, and nothing else Skiff cares about - no |
