pi-microsandbox 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -39,34 +39,39 @@ Keep your everyday defaults in global config and project-specific settings in
39
39
  variables and session overrides let you adjust a particular run without
40
40
  rewriting the project's setup.
41
41
 
42
- The agent gets an environment built for the job. You don't have to make the
43
- same decisions every time you start it.
42
+ The agent gets an environment built for the job. Image cohorts built from this
43
+ version include Docker Engine 29.8.0, Buildx 0.37.1, and Compose 5.5.1. The
44
+ daemon and its containers run inside the microVM; pi-microsandbox never connects them to the
45
+ host Docker socket. You don't have to make the same decisions every time you
46
+ start it.
44
47
 
45
48
  [Configure your project's sandbox →](docs/configuration.md)
46
49
 
47
50
  ## Get started
48
51
 
49
- You'll need Pi, **Node.js 22.19.0+**, and either an Apple Silicon Mac or Linux
50
- with accessible KVM. Installation also needs Python and a C/C++ build toolchain;
51
- keep lifecycle scripts and optional dependencies enabled.
52
+ You'll need Pi, **Node.js 22.19.0+**, and one of the supported host targets:
53
+ Apple Silicon macOS (`darwin-arm64`), GNU Linux x86_64
54
+ (`linux-x64-gnu`), or GNU Linux arm64 (`linux-arm64-gnu`). Live sandboxes also
55
+ need host virtualization support. The POSIX lock addon is bundled and installs
56
+ without lifecycle scripts or a compiler.
52
57
  [Full requirements and installation help →](docs/getting-started.md)
53
58
 
54
- Install the Microsandbox CLI first:
59
+ Install pi-microsandbox:
55
60
 
56
61
  ```sh
57
- curl -fsSL https://install.microsandbox.dev | sh
62
+ pi install npm:pi-microsandbox
58
63
  ```
59
64
 
60
- For alternate installation methods and any Microsandbox-specific setup,
61
- runtime, or troubleshooting details, use the official
62
- [Microsandbox documentation](https://docs.microsandbox.dev/). The documentation
63
- in this repository covers the Pi integration.
64
-
65
- Then install pi-microsandbox:
65
+ That command also installs the pinned Microsandbox SDK, CLI, and matching
66
+ platform runtime. A separate Microsandbox installation is not required on a
67
+ supported host. Keep npm optional dependencies enabled so npm installs the
68
+ platform package.
66
69
 
67
- ```sh
68
- pi install npm:pi-microsandbox
69
- ```
70
+ If the platform package is unavailable, you can provide a standalone `msb`
71
+ binary with `MSB_PATH`. See the official
72
+ [Microsandbox documentation](https://docs.microsandbox.dev/) for standalone
73
+ installation and runtime troubleshooting. The documentation in this repository
74
+ covers the Pi integration.
70
75
 
71
76
  From a Git repository, start Pi with its own isolated workspace:
72
77
 
package/docs/commands.md CHANGED
@@ -23,8 +23,9 @@ The extension registers `/msb`:
23
23
  /msb help
24
24
  ```
25
25
 
26
- `/msb status` reports the full sandbox name, mode, image, PID, age, branch/SHA,
27
- and retained volume metadata when available. Six-character IDs in UI text are
26
+ `/msb status` reports the full sandbox name, mode, image, PID, age, Docker
27
+ mode/readiness/version/storage driver, branch/SHA, and retained volume metadata
28
+ when available. Six-character IDs in UI text are
28
29
  display abbreviations only. `/msb prune` walks all SDK list pages and reports
29
30
  removed, kept, and error entries; **volumes are never pruned**.
30
31
 
@@ -15,9 +15,11 @@ The following is a small project example:
15
15
  ```toml
16
16
  # .pi-msb.toml
17
17
  mode = "git"
18
- image = "ghcr.io/hcohe/pi-microsandbox:1.0.0@sha256:00ea1e0911189815614e8a8eee36d1fd64f0f1edb39492e0bda9f273c834e59f"
18
+ image = "ghcr.io/hcohe/pi-microsandbox:1.1.0@sha256:ab4e99d4232f827b3f295ff3210437e01446dbb672ef0d0c78358566170ac86c"
19
19
  pull_policy = "if-missing"
20
20
  bootstrap_tools = "auto"
21
+ cpus = 4
22
+ memory_mib = 8192
21
23
  idle_timeout_sec = 600
22
24
  fallback_mode = "block"
23
25
  show_footer = true # Default; set false to hide the MSB footer status.
@@ -26,6 +28,10 @@ show_footer = true # Default; set false to hide the MSB footer status.
26
28
  mode = "default" # default | open | allowlist | deny
27
29
  allow_dns = true
28
30
 
31
+ [docker]
32
+ mode = "auto" # auto | require | disabled
33
+ startup_timeout_ms = 15000
34
+
29
35
  # Project secrets should use references, not literals.
30
36
  [[secrets]]
31
37
  env = "NPM_TOKEN"
@@ -50,17 +56,40 @@ Important configuration behavior:
50
56
  contents, custom image workflows, and the required guest commands.
51
57
  `bootstrap_tools = "auto"` probes those commands and uses noninteractive
52
58
  `apt-get` under the configured network policy when a custom image is missing
53
- them. `false` blocks with the missing command list instead.
59
+ them. `false` blocks with the missing command list instead. New sandboxes use
60
+ 4 CPUs and 8192 MiB by default; set `cpus` and `memory_mib` lower if the host
61
+ cannot support that allocation.
62
+ - `docker.mode = "auto"` starts the guest daemon when the image has Docker and
63
+ reports `missing` for older or custom images without it. `"require"` blocks
64
+ sandbox preparation if Docker is absent or cannot start. `"disabled"` leaves
65
+ the installed daemon stopped. `startup_timeout_ms` must be an integer from 1
66
+ through 300000. Readiness is pinned to the managed guest Unix socket and
67
+ ignores inherited Docker client endpoint settings. Docker state stays on the
68
+ disposable guest root filesystem. Small builds should have at least 1 GiB; larger Compose stacks usually need
69
+ 2 GiB or more.
54
70
  - `network.mode = "default"` leaves the SDK's default policy in place. `open`
55
71
  allows all network traffic, including private/host access; `allowlist` is
56
72
  default-deny with configured host/DNS rules; `deny` disables networking.
57
73
  Published ports default to loopback unless a bind address is specified.
74
+ Nested containers remain subject to this outer policy. A Docker `-p` mapping
75
+ exposes a port only inside the microVM. Host access also needs a matching
76
+ `network.publish_ports` entry created with the sandbox, for example
77
+ `publish_ports = ["127.0.0.1:8080:8080"]` together with `docker run -p
78
+ 0.0.0.0:8080:8080 ...`. Docker's random host-port form cannot create that
79
+ outer mapping.
58
80
  - Secrets require a non-empty `allow_hosts` list. `$ENV:NAME` and `$FILE:path`
59
81
  references are resolved only while constructing the SDK builder. Effective
60
- config, warnings, errors, and `/msb config` redact literal values.
82
+ config, warnings, errors, and `/msb config` redact literal values. Process
83
+ control variables such as `DOCKER_HOST`, `DOCKER_CONTEXT`, `PATH`,
84
+ `BASH_ENV`, and `LD_PRELOAD` cannot be forwarded with `host_env` or injected
85
+ as secrets.
61
86
  - Directory/file mounts have absolute guest paths. Project mounts outside the
62
87
  repository must be read-only unless a global/session policy authorizes the
63
- write. Mounts may not overlap or shadow the project mount or reserved `/tmp`.
88
+ write. Mounts may not overlap or shadow the project mount, reserved `/tmp`,
89
+ protected guest system trees such as `/usr`, `/bin`, `/proc`, and `/sys`, or
90
+ Docker runtime paths such as `/run`, `/var/run`, and `/var/lib/docker`.
91
+ Host mount sources are canonicalized before use; socket targets, including
92
+ Docker sockets reached through symlink aliases, are rejected.
64
93
  - The legacy `host_ro_allowlist` is converted to canonical read-only mounts and
65
94
  emits a deprecation warning.
66
95
 
@@ -71,6 +100,8 @@ PI_MSB_DISABLE=1 # explicit host/off mode
71
100
  PI_MSB_MODE=none # nested scalar example
72
101
  PI_MSB_PULL_POLICY=always # recheck mutable custom image tags on creation
73
102
  PI_MSB_NETWORK__MODE=deny # nested environment key
103
+ PI_MSB_DOCKER__MODE=require # require a working guest Docker daemon
104
+ PI_MSB_DOCKER__STARTUP_TIMEOUT_MS=30000
74
105
  PI_MSB_FALLBACK_MODE=host # opt into automatic host fallback
75
106
  PI_MSB_SHOW_FOOTER=false # hide the MSB status from Pi's footer
76
107
  PI_MSB_ROUTE_TOOLS='read,write' # POSIX delimiter for simple arrays
@@ -12,19 +12,87 @@ To test from source without installing the npm package globally:
12
12
  git clone https://github.com/hcohe/pi-microsandbox.git
13
13
  cd pi-microsandbox
14
14
 
15
- # fs-ext must compile during installation; do not use --ignore-scripts.
16
- npm ci
15
+ npm ci --ignore-scripts=true
17
16
  npm run typecheck
18
17
  npm test
19
18
  npm run smoke # extension-load smoke; no sandbox starts
20
19
  npm run check # all three commands above
21
20
  npm audit --omit=dev
22
- npm pack --dry-run --json
23
21
  ```
24
22
 
25
23
  The smoke and unit tests do not require KVM, image pulls, or a live sandbox.
26
24
  The boot-speed check and live matrix below are explicit VM tests.
27
25
 
26
+ To test the current extension and default image together, run:
27
+
28
+ ```sh
29
+ just dev
30
+ ```
31
+
32
+ `dev-flock` builds and smoke-tests the native owner-lock addon for the current
33
+ host. `dev-image` builds the current `default` variant as
34
+ `pi-microsandbox-dev:local` and imports it into Microsandbox's separate image
35
+ cache. `dev` runs both prerequisites, then starts Pi with this checkout's
36
+ extension explicitly loaded alongside your normal discovered extensions. It
37
+ forces the local image with `pull_policy = "never"`, requires Docker, and uses
38
+ 4 CPUs and 8192 MiB. Docker caching keeps repeat builds short
39
+ when image inputs have not changed. Pass Pi arguments directly, for example:
40
+
41
+ ```sh
42
+ just dev --continue
43
+ just dev "Run docker info and report the storage driver"
44
+ ```
45
+
46
+ Run `just dev-image` by itself when you only need to refresh the local image.
47
+
48
+ ### Bundled flock addon
49
+
50
+ Consumers receive prebuilt lock addons and do not need native build tools. Only
51
+ contributors building or changing the addon need Python, a C compiler, and the
52
+ platform build tools used by node-gyp (`make` on GNU Linux or Xcode command-line
53
+ tools on macOS). On one of the three supported targets, run:
54
+
55
+ ```sh
56
+ npm ci --ignore-scripts=true
57
+ npm run build:flock
58
+ npm run smoke:flock
59
+ npm run check
60
+ ```
61
+
62
+ The build writes
63
+ `native/flock/prebuilds/<target>/flock.node` for the current target. These
64
+ outputs are ignored by Git and must not be committed. CI builds
65
+ `darwin-arm64`, `linux-x64-gnu`, and `linux-arm64-gnu` separately on native
66
+ runners, then loads the same binary under Node 22.19.0 and Node 24.
67
+
68
+ ### Assemble a package from CI artifacts
69
+
70
+ A complete package needs all three `flock-<target>` artifacts from one CI run.
71
+ Download each artifact into one empty artifact root, create a staging checkout
72
+ from the same commit's Git archive, then give both paths to the assembler:
73
+
74
+ ```sh
75
+ run_id=GITHUB_ACTIONS_RUN_ID
76
+ mkdir -p .tmp
77
+ artifact_root="$(mktemp -d "$PWD/.tmp/flock-artifacts.XXXXXX")"
78
+ staging="$(mktemp -d "$PWD/.tmp/package-staging.XXXXXX")"
79
+ pack_dir="$(mktemp -d "$PWD/.tmp/package-pack.XXXXXX")"
80
+
81
+ for target in darwin-arm64 linux-x64-gnu linux-arm64-gnu; do
82
+ gh run download "$run_id" --name "flock-$target" --dir "$artifact_root"
83
+ done
84
+
85
+ git archive HEAD | tar -x -C "$staging"
86
+ npm run assemble:package -- "$artifact_root" "$staging"
87
+ pack_json="$(npm pack "$staging" --json --pack-destination "$pack_dir")"
88
+ tarball="$(node -e 'const value=JSON.parse(process.argv[1]); const results=Array.isArray(value)?value:Object.values(value); if(results.length!==1) throw new Error(`expected one pack result, got ${results.length}`); process.stdout.write(results[0].filename)' "$pack_json")"
89
+ npm run package-smoke -- "$pack_dir/$tarball"
90
+ ```
91
+
92
+ Use artifacts built from the same commit as `HEAD`. The assembler rejects
93
+ missing, extra, or symlinked artifacts and keeps generated binaries out of the
94
+ source checkout.
95
+
28
96
  ## Boot speed regression test
29
97
 
30
98
  With [`just`](https://just.systems/) installed, measure the awaited sandbox boot
@@ -71,14 +139,20 @@ Without that variable the script prints a `SKIP` line for every scenario and
71
139
  exits successfully; this skip path does not validate virtualization. If
72
140
  virtualization is unavailable, it prints the reason and skips the matrix rather
73
141
  than reporting false failures. Set `PI_MSB_LIVE_IMAGE` to select the main live
74
- test image; the default is `ghcr.io/hcohe/pi-microsandbox:latest`.
142
+ test image; the default is `ghcr.io/hcohe/pi-microsandbox:latest`. The main
143
+ scenarios use `pull_policy = "always"` by default. To test an image already
144
+ imported with `msb load`, set `PI_MSB_LIVE_PULL_POLICY=never`; do not use that
145
+ override as evidence for a published image.
75
146
  The prepared-image scenario boots all six latest variant tags under
76
147
  `network.mode = "deny"` with bootstrap disabled. Set
77
148
  `PI_MSB_LIVE_PREPARED_IMAGES` to a comma-separated image cohort, or use the
78
149
  legacy singular `PI_MSB_LIVE_PREPARED_IMAGE` to test one image. The live matrix
79
150
  uses `pull_policy = "always"` intentionally so mutable development tags cannot
80
- remain stale on the self-hosted runner. Review the output to confirm that all 16 scenarios report
81
- `PASS`, not `SKIP`.
151
+ remain stale on the self-hosted runner. Review the output to confirm that every scenario reports `PASS`, not `SKIP`.
152
+ Docker release validation must cover daemon readiness, bridge DNS and HTTPS,
153
+ user-defined networking, Buildx, Compose, idle wake, double port publishing,
154
+ and nested-container enforcement for deny and allowlist policies. A skipped
155
+ Docker scenario is not release evidence.
82
156
 
83
157
  ## Image development
84
158
 
@@ -89,7 +163,17 @@ variant's mutable latest tag and a commit-specific tag. Release builds pin the
89
163
  Ubuntu image digest and one dated apt snapshot for all variants, while published
90
164
  images restore normal apt sources for project use. See [Images](images.md#add-a-language-variant)
91
165
  for the modular installer and verifier architecture, contribution rules, and
92
- local validation commands.
166
+ local validation commands. Docker changes must also pass:
167
+
168
+ ```sh
169
+ node scripts/image-variants.mjs matrix
170
+ shellcheck -e SC1091 default-image/install/*.sh default-image/verify/*.sh
171
+ ```
172
+
173
+ The common image verifier checks Docker Engine 29.8.0, containerd 2.3.4, runc
174
+ 1.5.1, Buildx 0.37.1, Compose 5.5.1, and Ubuntu's iptables-nft/nftables tools.
175
+ Docker daemon and nested-container behavior require the live microVM matrix;
176
+ they cannot be validated during a Dockerfile build.
93
177
 
94
178
  ## Releases
95
179
 
@@ -98,7 +182,11 @@ canonical changelog. The first npm publication is a human-run local publish of
98
182
  the reviewed tarball with interactive npm 2FA. Subsequent releases publish
99
183
  directly to npm with OIDC only after a maintainer publishes the matching GitHub
100
184
  Release and approves the protected `npm` GitHub Environment. Release automation
101
- must not use a long-lived npm token.
185
+ must not use a long-lived npm token. Release CI builds every flock artifact from
186
+ the release commit, assembles a temporary staging tree, records each binary's
187
+ SHA-256, smoke-tests the exact tarball on every supported target, and packs only
188
+ once. The publish job downloads and publishes those verified bytes without
189
+ repacking.
102
190
 
103
191
  The sandbox image workflow publishes all six AMD64 and ARM64 variants to
104
192
  `ghcr.io/hcohe/pi-microsandbox`. An `image-vX.Y.Z` Git tag publishes the
@@ -9,27 +9,26 @@ require one of these hosts:
9
9
 
10
10
  | Host | Architecture | Virtualization requirement |
11
11
  | --- | --- | --- |
12
- | macOS | Apple Silicon (arm64) | Apple virtualization support available to the process |
13
- | Linux | x86_64 or arm64 (GNU) | KVM enabled, with `/dev/kvm` accessible to the process |
14
-
15
- Windows and Intel macOS are not supported by pi-microsandbox. The upstream
16
- microsandbox runtime has preview Windows support, but this package deliberately
17
- declares only macOS and Linux. A Linux container or virtual machine also needs
18
- KVM passthrough or nested virtualization; many hosted environments do not
19
- provide it. Package loading and non-live tests do not require virtualization.
20
-
21
- Installation must run lifecycle scripts and include optional dependencies:
22
-
23
- - `fs-ext@2.1.1` compiles a native node-gyp module. Install Python and a working
24
- C/C++ build toolchain (`xcode-select --install` on macOS, or a compiler,
25
- `make`, and Python 3 on Linux).
26
- - `microsandbox@0.6.16` installs its matching native addon and runtime binaries
27
- through an optional platform package. Do not use `--ignore-scripts` or omit
28
- optional dependencies when installing pi-microsandbox.
29
-
30
- If the platform package is missing, reinstall with optional dependencies
31
- enabled, install the matching microsandbox platform package, or set `MSB_PATH`
32
- to a working `msb` binary. These alternatives do not remove the host
12
+ | macOS | Apple Silicon (`darwin-arm64`) | Apple virtualization support available to the process |
13
+ | GNU Linux | x86_64 (`linux-x64-gnu`) or arm64 (`linux-arm64-gnu`) | KVM enabled, with `/dev/kvm` accessible to the process |
14
+
15
+ Windows, Intel macOS, and musl Linux are not supported by pi-microsandbox. The
16
+ upstream microsandbox runtime has preview Windows support, but this package
17
+ deliberately supports only the three targets above. A Linux container or
18
+ virtual machine also needs KVM passthrough or nested virtualization; many hosted
19
+ environments do not provide it. Package loading and non-live tests do not
20
+ require virtualization.
21
+
22
+ pi-microsandbox includes a prebuilt POSIX lock addon for each supported target.
23
+ It is loaded lazily when an owner lock is first needed. Consumer installation
24
+ does not compile native code or require Python, a C/C++ toolchain, or npm
25
+ lifecycle scripts; installation with scripts disabled is supported.
26
+
27
+ Keep optional dependencies enabled. `microsandbox@0.6.16` supplies its CLI,
28
+ native addon, and runtime binaries through an optional platform package. If that
29
+ platform package is missing, reinstall with optional dependencies enabled,
30
+ install the matching Microsandbox platform package, or set `MSB_PATH` to a
31
+ working standalone `msb` binary. These alternatives do not remove the host
33
32
  virtualization requirement.
34
33
 
35
34
  ## Install
@@ -40,6 +39,11 @@ Install the package for the current user with Pi:
40
39
  pi install npm:pi-microsandbox
41
40
  ```
42
41
 
42
+ This is the only package installation step on a supported host. The dependency
43
+ includes the Microsandbox SDK and CLI; its matching optional platform package
44
+ includes the host runtime. You do not need to run the standalone Microsandbox
45
+ installer first.
46
+
43
47
  Before starting a sandbox, review [configuration](configuration.md) and choose a
44
48
  [published variant or custom image](images.md) if the versioned default image
45
49
  does not fit the project.
package/docs/images.md CHANGED
@@ -15,7 +15,7 @@ Push an exact `image-vVERSION` Git tag to publish a release cohort. Package
15
15
 
16
16
  | Variant | Contents | Release tag | Latest tag |
17
17
  | --- | --- | --- | --- |
18
- | `base` | Required guest commands and CA certificates, without a language toolchain | `base-VERSION` | `base-latest` |
18
+ | `base` | Required guest commands, CA certificates, Docker 29.8.0, Buildx 0.37.1, and Compose 5.5.1; no language toolchain | `base-VERSION` | `base-latest` |
19
19
  | `node` | Base plus Node.js 24.21.0, npm, pnpm 12.3.4, Yarn 1.22.22, and native addon build support | `node-VERSION` | `node-latest` |
20
20
  | `python` | Base plus Ubuntu Python 3, pip, uv/uvx 0.12.12, and native extension build support | `python-VERSION` | `python-latest` |
21
21
  | `rust` | Base plus Rust 1.98.0, Cargo, rustup, and native dependency build support | `rust-VERSION` | `rust-latest` |
@@ -23,8 +23,12 @@ Push an exact `image-vVERSION` Git tag to publish a release cohort. Package
23
23
  | `default` | Base plus the Node.js, Python, Rust, and Go modules above | `VERSION` | `latest` |
24
24
 
25
25
  The base contract includes `bash`, `sh`, `git`, `rg`, `file`, `cat`, `mkdir`,
26
- `rm`, and the other core commands used by the image verification scripts. CA
27
- certificates support HTTPS Git operations.
26
+ `rm`, Docker Engine and CLI 29.8.0, containerd 2.3.4, runc 1.5.1, Buildx
27
+ 0.37.1, Compose 5.5.1, and the Ubuntu iptables-nft and nftables tools. CA
28
+ certificates support HTTPS Git operations. Docker is part of the common base
29
+ rather than a language toolchain, so all six variants built from this version
30
+ contain it. The extension's digest-pinned default changes only after that cohort
31
+ has been published and verified.
28
32
 
29
33
  Select a variant in trusted project configuration:
30
34
 
@@ -46,10 +50,10 @@ an updated mutable tag, or `"never"` to require a cached local image.
46
50
  [`default-image/variants.json`](../default-image/variants.json) is the single
47
51
  source of variant composition and tag names. The workflow passes each entry's
48
52
  toolchain list to one generic
49
- [`default-image/Dockerfile`](../default-image/Dockerfile). Modular
50
- `default-image/install/<language>.sh` and
51
- `default-image/verify/<language>.sh` scripts install and exercise each selected
52
- language.
53
+ [`default-image/Dockerfile`](../default-image/Dockerfile). The common Docker installer runs before the modular
54
+ `default-image/install/<language>.sh` scripts. The corresponding common
55
+ verifier checks Docker and its CLI plugins in every variant; language verifiers
56
+ then exercise each selected toolchain.
53
57
 
54
58
  The `default` variant runs the same Node.js, Python, Rust, and Go modules as the
55
59
  individual variants. It does not have a duplicate package list. This keeps an
@@ -63,7 +67,11 @@ can install current packages at runtime.
63
67
  ## Build a custom image
64
68
 
65
69
  A custom image must provide `bash`, `sh`, `git`, `rg`, `file`, `cat`, `mkdir`,
66
- and `rm`. Install CA certificates if the guest will use Git over HTTPS. With
70
+ and `rm`. Docker is optional for custom images. The default `docker.mode =
71
+ "auto"` records it as missing and continues; use `docker.mode = "require"` when
72
+ the image contract must include a working daemon. pi-microsandbox does not
73
+ install Docker during sandbox startup. Install CA certificates if the guest
74
+ will use Git over HTTPS. With
67
75
  `bootstrap_tools = "auto"`, pi-microsandbox can install missing required
68
76
  commands through `apt-get` when the network policy permits it. A prepared image
69
77
  is required when bootstrap is disabled or package repositories are unavailable.
package/docs/safety.md CHANGED
@@ -19,11 +19,31 @@ The default is fail-closed:
19
19
  after a sandbox failure and is shown as `MSB host fallback`.
20
20
  - A project cannot replace another process's sandbox: ownership is a
21
21
  non-blocking kernel `flock` acquired before any sandbox or volume mutation.
22
- Stale sandbox pruning never removes volumes.
23
-
24
- The extension entry point does not import the native SDK. Unsupported hosts can
25
- still load Pi and remain blocked or explicitly off. pi-microsandbox currently supports
26
- macOS Apple Silicon and Linux with KVM; Windows is not supported.
22
+ The small bundled POSIX addon is loaded lazily, has no install script, and
23
+ never falls back to a racy PID check. Stale sandbox pruning never removes
24
+ volumes.
25
+
26
+ The extension entry point does not import the native SDK or load the flock
27
+ addon. Unsupported hosts can still load Pi and remain blocked or explicitly
28
+ off. pi-microsandbox supports Apple Silicon macOS and GNU Linux x86_64 or arm64
29
+ with KVM; Windows, Intel macOS, and musl Linux are not supported.
30
+
31
+ ## Docker inside the guest
32
+
33
+ The Docker daemon runs inside the microVM and listens only on the guest Unix
34
+ socket. Access to that socket is root-equivalent inside the guest, not on the
35
+ host. Readiness probes explicitly select that socket and reject unverified
36
+ socket ownership. Docker and process-control environment variables are cleared
37
+ for preparation, and configuration cannot forward them. Mounts that shadow
38
+ protected guest executables or Docker runtime paths are rejected. The extension never mounts the host Docker
39
+ socket, starts a host daemon, or copies host Docker configuration and registry
40
+ credentials into the guest.
41
+
42
+ A container can still reach anything already mounted into the microVM. In
43
+ `direct` mode that includes the host project directory; in Git mode it includes
44
+ the retained workspace; explicitly configured mounts are visible too. Treat a
45
+ Dockerfile or Compose file as guest-root code and use read-only mounts where
46
+ possible. Container egress remains behind the Microsandbox network policy.
27
47
 
28
48
  ## Host-read exceptions
29
49
 
package/docs/storage.md CHANGED
@@ -15,6 +15,20 @@
15
15
  routed edits modify the live host directory. `none` is useful for testing path
16
16
  behavior and starts empty; it is not a retained workspace.
17
17
 
18
+ ## Inner Docker state
19
+
20
+ Docker stores images, layers, containers, and build cache under
21
+ `/var/lib/docker` on the sandbox root filesystem. It uses the `vfs` storage
22
+ driver because nested overlay filesystems and project-backed mounts cannot be
23
+ assumed to support `overlay2`. This state disappears when the sandbox is
24
+ removed. It is not written to the project mount or retained Git volume, and
25
+ separate sessions do not share an inner Docker cache.
26
+
27
+ A stopped sandbox may retain that state until it is restarted or removed, but a
28
+ retained Git workspace does not preserve it. Do not move Docker's data root
29
+ onto the Git volume. A persistent Docker cache would need a separate managed
30
+ volume and cleanup policy.
31
+
18
32
  ## Git and retained volumes
19
33
 
20
34
  Git mode never bind-mounts the host checkout. On boot, pi-microsandbox captures the
@@ -17,4 +17,28 @@
17
17
  command list or allow the configured network policy to reach the package
18
18
  repositories. Deny mode cannot bootstrap an image missing those commands.
19
19
 
20
+ ## Docker daemon problems
21
+
22
+ `/msb status` shows the configured Docker mode, readiness, server version, and
23
+ storage driver. Inside an active sandbox, start or recheck the daemon with:
24
+
25
+ ```sh
26
+ pi-msb-docker-start 15000
27
+ docker info
28
+ ```
29
+
30
+ Startup logs are guest-local at `/var/log/pi-msb-dockerd.log`. Check the network
31
+ prerequisites with `iptables --version` (it should report `nf_tables`), `nft
32
+ --version`, and `sysctl net.ipv4.ip_forward` (it should be `1`). The daemon uses
33
+ `vfs`; slower builds and higher disk use are expected compared with `overlay2`.
34
+ Increase `memory_mib` or `docker.startup_timeout_ms` if startup is killed or
35
+ large builds run out of memory. Small builds should have at least 1 GiB and
36
+ larger Compose stacks should have 2 GiB or more; the default is 8 GiB.
37
+
38
+ A published container port needs two mappings. Configure the outer
39
+ `network.publish_ports` mapping before sandbox creation, then use Docker `-p`
40
+ inside the guest. A Docker mapping by itself is not reachable from the host.
41
+ Pull and container-egress failures under `deny` or `allowlist` are expected;
42
+ do not bypass the outer policy or mount the host Docker socket as a workaround.
43
+
20
44
  For installation prerequisites, see [installation and requirements](getting-started.md). To test a live sandbox from source, see the [live test matrix](development.md#live-test-matrix).
@@ -198,6 +198,11 @@ function fullState(state: RuntimeState): string {
198
198
  lines.push(`Image: ${info.image}`);
199
199
  lines.push(`PID: ${info.pid}`);
200
200
  lines.push(`Age: ${displayTime(info.createdAt)}`);
201
+ lines.push(`Docker mode: ${info.docker.mode}`);
202
+ lines.push(`Docker readiness: ${info.docker.readiness}`);
203
+ if (info.docker.version) lines.push(`Docker version: ${info.docker.version}`);
204
+ if (info.docker.storageDriver) lines.push(`Docker storage driver: ${info.docker.storageDriver}`);
205
+ if (info.docker.reason) lines.push(`Docker reason: ${info.docker.reason}`);
201
206
  if (info.seedBranch) lines.push(`Branch: ${info.seedBranch}`);
202
207
  if (info.seedSha) lines.push(`Seed SHA: ${info.seedSha}`);
203
208
  if (info.volumeName) lines.push(`Retained volume: ${info.volumeName}`);