signalk-container 1.8.0 → 1.8.1

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
@@ -20,7 +20,10 @@ Instead of each plugin implementing its own container orchestration, they delega
20
20
  - **SELinux support** -- `:Z` volume flags for Podman bind mounts on Fedora/RHEL; named volumes are handled correctly (`:Z` is not applied)
21
21
  - **Per-volume host-source policy** -- volumes accept `{ source, ifMissing: "skip" | "abort" }` for user-managed (USB drives, NFS) or deployment-required (TLS certs) mounts. Plugins subscribe to `onVolumeIssue` events for `'skipped'`, `'aborted'`, and `'recovered'` actions; signalk-container auto-recreates the container when a previously-missing source reappears. See the [developer guide](doc/plugin-developer-guide.md#optional-and-required-volumes).
22
22
  - **Container log streaming** -- click **Logs** on any managed-container card to open a live-streaming popup of the container's stdout+stderr (combined, the same shape `podman logs <name>` produces). Plugin authors can also wire `onContainerLog` in `ensureRunning` options to forward the same stream into their plugin's `app.debug` channel — visible in the Signal K server log when debug is enabled. Multiple subscribers share a single underlying tail process. See the [developer guide](doc/plugin-developer-guide.md#streaming-container-logs-into-your-plugins-debug-channel).
23
+ - **Host-UID ownership alignment** -- managed containers run by default under the Signal K host user's UID/GID (via `--user host:host` on Docker/rootful Podman, `--userns=keep-id` on rootless Podman). Files created on bind mounts are owned by the same identity that runs Signal K, with no `chmod` sweeps. Override per container via `ContainerConfig.user` for images with a non-root `USER` directive, or `user: false` to opt out. See the [developer guide](doc/plugin-developer-guide.md#host-uid-ownership).
24
+ - **Image compliance probes** -- `containers.doctor.imageRunsAsUser(image, user?)` runs the image under the live UID mapping and verifies it can write `/tmp` as the host caller. Surfaces UID-compatibility problems _before_ a container wedges in a restart loop. See the [developer guide](doc/plugin-developer-guide.md#containersdoctorimagerunsasuserimage-user-promiseimageproberesult).
23
25
  - **Podman image qualification** -- automatically prefixes `docker.io/` for short image names
26
+ - **Docker `host.containers.internal` parity** -- signalk-container adds the `host-gateway` mapping for Docker automatically (Podman has it natively). User-supplied `extraHosts` overrides are respected.
24
27
  - **Cross-plugin API** -- other plugins use `globalThis.__signalk_containerManager`
25
28
 
26
29
  ## Config Panel
@@ -144,28 +147,30 @@ See [doc/plugin-developer-guide.md](doc/plugin-developer-guide.md) for the full
144
147
  | `resolveSignalkDataMount()` | Resolve the volume name or host path that backs `app.getDataDirPath()` in the current deployment; returns `null` if the runtime is not yet initialised |
145
148
  | `resolveHostPath(absPath)` | Translate an arbitrary absolute path into the `{ source, subPath }` pair the runtime needs to mount it; handles bare-metal, bind, and named-volume topologies |
146
149
  | `resolveContainerAddress(name, port)` | Return the `host:port` string to reach `port` on a managed container from the SignalK process; call after `ensureRunning()` with `signalkAccessiblePorts` set |
150
+ | `doctor.imageRunsAsUser(image, user?)` | Probe whether `image` runs cleanly under the host-UID mapping signalk-container will emit (1.8.0+). Never throws — returns `{ ok, output, error? }` |
147
151
 
148
152
  ## REST Endpoints
149
153
 
150
154
  All mounted at `/plugins/signalk-container/api/`:
151
155
 
152
- | Method | Path | Description |
153
- | ------ | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
154
- | GET | `/runtime` | Detected runtime info |
155
- | GET | `/containers` | List managed containers |
156
- | GET | `/containers/:name/state` | Container state |
157
- | POST | `/containers/:name/start` | Start a stopped container |
158
- | POST | `/containers/:name/stop` | Stop a running container |
159
- | POST | `/containers/:name/remove` | Stop and remove a container |
160
- | GET | `/containers/:name/logs?tail=N&since=ts` | Last N lines of the container's combined stdout+stderr log (one-shot). `tail` defaults 200, max 10000 |
161
- | GET | `/containers/:name/logs/stream` | Server-Sent Events stream of live log lines. Closes when the container is removed or the client disconnects |
162
- | POST | `/prune` | Prune dangling images |
163
- | GET | `/updates` | List last update-check results |
164
- | GET | `/updates/:pluginId` | Last update-check result for one plugin |
165
- | POST | `/updates/:pluginId/check` | Force a fresh update check (HTTP 200 even when offline) |
166
- | GET | `/containers/:name/resources` | Effective resource limits + user override |
167
- | POST | `/containers/:name/resources` | Apply new resource limits (live or recreate). Body is a `ContainerResourceLimits` diff against the consumer plugin's default. |
168
- | DELETE | `/containers/:name/resources` | Clear any user override and restore the consumer plugin's pristine default limits to the running container. |
156
+ | Method | Path | Description |
157
+ | ------ | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
158
+ | GET | `/runtime` | Detected runtime info |
159
+ | GET | `/containers` | List managed containers |
160
+ | GET | `/containers/:name/state` | Container state |
161
+ | POST | `/containers/:name/start` | Start a stopped container |
162
+ | POST | `/containers/:name/stop` | Stop a running container |
163
+ | POST | `/containers/:name/remove` | Stop and remove a container |
164
+ | GET | `/containers/:name/logs?tail=N&since=ts` | Last N lines of the container's combined stdout+stderr log (one-shot). `tail` defaults 200, max 10000 |
165
+ | GET | `/containers/:name/logs/stream` | Server-Sent Events stream of live log lines. Closes when the container is removed or the client disconnects |
166
+ | POST | `/prune` | Prune dangling images |
167
+ | GET | `/updates` | List last update-check results |
168
+ | GET | `/updates/:pluginId` | Last update-check result for one plugin |
169
+ | POST | `/updates/:pluginId/check` | Force a fresh update check (HTTP 200 even when offline) |
170
+ | GET | `/containers/:name/resources` | Effective resource limits + user override |
171
+ | POST | `/containers/:name/resources` | Apply new resource limits (live or recreate). Body is a `ContainerResourceLimits` diff against the consumer plugin's default. |
172
+ | DELETE | `/containers/:name/resources` | Clear any user override and restore the consumer plugin's pristine default limits to the running container. |
173
+ | POST | `/doctor/image` | Probe whether an image runs cleanly under the live host-UID mapping. Body: `{ image, tag?, user? }`. Never 5xx for a failed probe — `{ ok: false, error }` is a successful response (1.8.0+). |
169
174
 
170
175
  ## Configuration
171
176
 
@@ -493,7 +498,9 @@ network namespace. This affects:
493
498
  (add it externally or via the same compose file)
494
499
  - `host.containers.internal` from spawned containers points to the host
495
500
  itself, not the Signal K container — use Signal K's container name
496
- for direct communication
501
+ for direct communication. signalk-container 1.8.0+ adds this hostname
502
+ to Docker containers automatically (Podman already provides it); set
503
+ `ContainerConfig.extraHosts` to override it or to add other hostnames.
497
504
 
498
505
  ### Recommended setup
499
506
 
package/dist/types.d.ts CHANGED
@@ -204,19 +204,17 @@ export interface ContainerConfig {
204
204
  * identity on the host — no recursive `chmod` sweeps needed.
205
205
  *
206
206
  * - omitted (default): emit a uid mapping that aligns the in-container
207
- * process with the host caller. Under rootless Podman this means
208
- * `--userns=keep-id:uid=<inImageUid>,gid=<inImageGid>`; under Docker
209
- * and rootful Podman it means `--user <hostUid>:<hostGid>`. The
210
- * `inImageUid`/`inImageGid` default to 0 (i.e. the image's root)
207
+ * process with the host caller. Rootless Podman uses user-namespace
208
+ * remapping; Docker and rootful Podman use direct UID/GID translation.
209
+ * The `inImageUid`/`inImageGid` default to 0 (i.e. the image's root)
211
210
  * unless the consumer sets them to match the image's `USER`.
212
211
  * - `{ inImageUid, inImageGid }`: same logic but with explicit
213
212
  * in-image UID/GID. Use this when the image declares a non-root
214
- * `USER` (e.g. `USER 1001`) so the keep-id mapping picks the right
215
- * starting point for translation.
216
- * - `false`: opt out. No `--user` / `--userns` flag emitted. The
217
- * container runs with whatever the image's `USER` directive
218
- * specifies. Use when the image requires root or manages its own
219
- * user model.
213
+ * `USER` (e.g. `USER 1001`) so the rootless-Podman remap picks the
214
+ * right starting point for translation.
215
+ * - `false`: opt out. No uid-mapping flag emitted. The container
216
+ * runs with whatever the image's `USER` directive specifies.
217
+ * Use when the image requires root or manages its own user model.
220
218
  *
221
219
  * Mirrors `ContainerJobConfig.user` so the same translator drives both
222
220
  * long-running managed containers and one-shot helper jobs.
@@ -339,13 +337,11 @@ export interface ContainerJobConfig {
339
337
  * files written into bind-mounted output dirs land owned by the
340
338
  * host signalk-server process, not by an unrelated container UID.
341
339
  *
342
- * The auto path emits the right flag form per runtime:
343
- * - Docker (any flavour) and rootful Podman: `--user <hostUID>:<hostGID>`
344
- * - Rootless Podman: `--userns=keep-id:uid=<inImageUID>,gid=<inImageGID>`
345
- *
346
- * (The two forms achieve the same end via different mechanisms.
347
- * `--userns=keep-id` is rootless-Podman-only — it errors out under
348
- * rootful — which is why the runtime detection matters.)
340
+ * The auto path picks the right mechanism per runtime: Docker (any
341
+ * flavour) and rootful Podman use direct UID/GID translation; rootless
342
+ * Podman uses user-namespace remapping. The two forms achieve the same
343
+ * end via different mechanisms, which is why the runtime detection
344
+ * matters (the rootless-Podman flag errors out under rootful Podman).
349
345
  *
350
346
  * - Default (`undefined`): auto-align using `process.getuid()` /
351
347
  * `process.getgid()`, assuming the image's USER directive is
@@ -770,9 +766,8 @@ export interface ContainerManagerApi {
770
766
  export interface DoctorApi {
771
767
  /**
772
768
  * Run `image:tag` under the same uid mapping `ensureRunning` would
773
- * use (`--user host:host` on Docker / rootful Podman, `--userns=
774
- * keep-id` on rootless Podman, none on opt-out) and verify that the
775
- * container can `touch /tmp/x` as the host caller.
769
+ * use for this `user` value and verify that the container can
770
+ * `touch /tmp/x` as the host caller.
776
771
  *
777
772
  * Returns `{ ok: true }` when the probe exits 0 and prints `"ok"`.
778
773
  * Never throws — failure modes (non-zero exit, exec error, missing
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -324,6 +324,8 @@ Volumes accept either a bare host-path string (auto-create — runtime creates t
324
324
 
325
325
  For opt-in digest pinning, pass `digest` (`sha256:<64-hex>`) on the config and `pluginId` / `pluginVersion` on the options — see [Image Pinning Manifest](#image-pinning-manifest).
326
326
 
327
+ `ContainerConfig.user` controls the host-UID mapping for files the container creates on bind mounts — see [Host-UID Ownership](#host-uid-ownership). `ContainerConfig.extraHosts` lets you add hostname → IP entries to `/etc/hosts`; signalk-container automatically maps `host.containers.internal` to `host-gateway` on Docker (Podman has it natively), and a user value passed in `extraHosts` is respected as an override.
328
+
327
329
  ```typescript
328
330
  await containers.ensureRunning("my-db", {
329
331
  image: "postgres",
@@ -560,6 +562,121 @@ const history = await containers.manifest.getContainerHistory("questdb");
560
562
 
561
563
  Returns `[]` if the container has no manifest entry (e.g. it predates the manifest layer or `ensureRunning` has never been called for it in this Signal K session).
562
564
 
565
+ ### `containers.doctor.imageRunsAsUser(image, user?): Promise<ImageProbeResult>`
566
+
567
+ Probe whether `image` can run cleanly under the host-UID mapping signalk-container will emit for managed containers — i.e. that `/tmp` is writable for the host caller and the image doesn't depend on a writable `~/.<x>` or a root-only path. Use this _before_ adopting an unfamiliar image, instead of debugging a wedged container after the fact.
568
+
569
+ The probe starts the image with the same `--user` / `--userns` flags `ensureRunning` would emit for the given `user` value, executes `touch /tmp/x && echo ok`, and reports the result. Never throws — non-zero exit, missing binary, and exec failures all surface as `{ ok: false, error }`.
570
+
571
+ ```typescript
572
+ const probe = await containers.doctor.imageRunsAsUser("myorg/worker:1.2.3");
573
+ if (!probe.ok) {
574
+ app.setPluginError(`image not UID-compatible: ${probe.error}`);
575
+ app.debug(probe.output); // combined stdout/stderr from the probe run
576
+ }
577
+ ```
578
+
579
+ Pass `user` to test a specific mapping — e.g. an image whose `USER` directive sets `1001`:
580
+
581
+ ```typescript
582
+ await containers.doctor.imageRunsAsUser("myorg/worker:1.2.3", {
583
+ inImageUid: 1001,
584
+ inImageGid: 1001,
585
+ });
586
+ ```
587
+
588
+ Returns `{ ok: true, output: "ok\n" }` on success; `{ ok: false, output, error }` on failure. Available in signalk-container 1.8.0+.
589
+
590
+ ---
591
+
592
+ ## Host-UID Ownership
593
+
594
+ Managed containers run by default under the **Signal K host user's UID/GID**, so files the container creates on bind-mounted host paths are owned by the same identity that runs Signal K. No recursive `chmod` sweeps, no "root-owned files in `~/.signalk`" surprises.
595
+
596
+ How the translator achieves that varies by runtime:
597
+
598
+ | Runtime | Mechanism |
599
+ | ---------------------------- | -------------------------------------------------------------------------------------- |
600
+ | Rootless Podman | User-namespace remapping that translates the in-image UID/GID back to the host caller. |
601
+ | Docker (rootless or rootful) | Direct UID/GID translation — the in-container process runs as the host caller's IDs. |
602
+ | Rootful Podman | Same direct UID/GID translation as Docker. |
603
+ | Windows | No translation — Docker Desktop handles UID/GID mapping internally. |
604
+
605
+ Consumer plugins do not have to call anything special — the default mapping just works for the typical case (image runs as root, container writes files that Signal K then reads). The exact CLI flags emitted for each runtime are an implementation detail of `userMappingFlags` in `src/runtime.ts`; consult it (and the matching tests) if you need to see the literal form for a given variant.
606
+
607
+ ### When to set `ContainerConfig.user`
608
+
609
+ Only when the image declares a **non-root `USER`** directive. The `inImageUid` / `inImageGid` defaults are `0` (root); for an image with `USER 1001` you must tell the translator so the keep-id mapping picks the right starting point:
610
+
611
+ ```typescript
612
+ await containers.ensureRunning("my-worker", {
613
+ image: "ghcr.io/myorg/worker", // image declares USER 1001
614
+ tag: "1.2.3",
615
+ user: { inImageUid: 1001, inImageGid: 1001 },
616
+ // ...
617
+ });
618
+ ```
619
+
620
+ Get this wrong and rootless Podman will translate the in-image UID to the wrong host UID; the container will look fine until it writes a file and you discover the bind-mounted host path is owned by some random subuid.
621
+
622
+ ### Opting out: `user: false`
623
+
624
+ Pass `false` if the image must run as root (or manages its own user model entirely) and you don't need host-aligned ownership on bind mounts:
625
+
626
+ ```typescript
627
+ await containers.ensureRunning("legacy-worker", {
628
+ image: "legacy/needs-root",
629
+ tag: "v1",
630
+ user: false, // no --user, no --userns
631
+ // ...
632
+ });
633
+ ```
634
+
635
+ The container then runs with whatever the image's `USER` directive specifies, with no flag emitted by signalk-container.
636
+
637
+ ### Image requirements for UID-aligned containers
638
+
639
+ An image that signalk-container starts under the default ownership mapping must:
640
+
641
+ - **Run cleanly as a non-root UID** passed via the runtime's user/userns mechanism. The image cannot assume root privileges for setup; anything that needs root must happen at build time.
642
+ - **Have a writable `HOME` for the runtime UID.** Image entrypoints that touch `~/.config` or any dotfile in `$HOME` fail otherwise. The right pattern is a dedicated non-root user with its own home directory created at build time (see the Dockerfile example below). When you can't change the user — e.g. an upstream image that hardcodes `HOME=/root` — set `ENV HOME=/tmp` (or another per-UID-writable path) in a thin wrapper image instead. Do not work around this by making `/root` world-writable; that erases the security boundary the dedicated user provides.
643
+ - **Have a writable `/tmp` for the runtime UID.** Default `1777` is fine; the doctor probe checks exactly this.
644
+ - **Not depend on root-only paths at runtime.** `/root`, ownership of `/var/run`, `chown` on bind-mounted host paths in the entrypoint — all break under the mapping.
645
+ - **Not call `chmod` or `chown` against host-mounted paths in its entrypoint.** The whole point of the UID alignment is that files are already correctly owned at creation; an entrypoint that re-asserts ownership is fighting the model and will silently no-op on FAT/exFAT/NTFS bind sources anyway.
646
+
647
+ If you control the image's Dockerfile, the cleanest pattern is a dedicated non-root user with a real home directory:
648
+
649
+ ```dockerfile
650
+ RUN useradd -m -u 1001 -s /bin/sh worker
651
+ USER worker
652
+ ```
653
+
654
+ Then declare `user: { inImageUid: 1001, inImageGid: 1001 }` on the `ContainerConfig` so the rootless-Podman remap picks the right starting point.
655
+
656
+ If you're adopting a third-party image and it doesn't meet these criteria, options in rough order of preference:
657
+
658
+ 1. Run the doctor probe (next subsection) to confirm the breakage and the failure mode.
659
+ 2. File an upstream fix if the image is maintained — most popular images are happy to accept a non-root patch.
660
+ 3. Use `user: false` to opt out of the mapping (the image runs as root, files on bind mounts are owned by root on the host — back to the pre-1.8.0 behavior).
661
+ 4. Build a thin wrapper image that fixes the ownership requirements at build time.
662
+
663
+ ### Verifying compatibility ahead of time
664
+
665
+ Before adopting an unfamiliar image, run `containers.doctor.imageRunsAsUser(image, user?)` (see API reference above). It catches the common failure modes (`/tmp` not writable for the host UID, image entrypoint touches `~` and `$HOME` isn't writable for that UID) up-front, instead of leaving you to debug a container stuck in a restart loop with a cryptic error.
666
+
667
+ ### `ContainerJobConfig.user`
668
+
669
+ `runJob` accepts the same `user` field with identical semantics. Both code paths share the flag translator, so a probe that passes for `ensureRunning` also passes for `runJob`.
670
+
671
+ ### Reading the resolved host identity
672
+
673
+ `getRuntime()` returns `hostUser: { uid, gid } | null` (null on Windows). Most plugins don't need it — the translator handles the mapping internally — but it's available for diagnostics:
674
+
675
+ ```typescript
676
+ const rt = containers.getRuntime();
677
+ app.debug(`Signal K runs as ${rt?.hostUser?.uid}:${rt?.hostUser?.gid}`);
678
+ ```
679
+
563
680
  ---
564
681
 
565
682
  ## Image Pinning Manifest
@@ -948,6 +1065,11 @@ interface ContainerConfig {
948
1065
  tag: string;
949
1066
  digest?: string; // "sha256:<64-hex>" — pulls `image@digest`
950
1067
  updateChannel?: string; // "tag:<pattern>" | "tag:latest" | "digest:explicit"
1068
+ extraHosts?: Record<string, string>; // hostname → IP or "host-gateway"
1069
+ // Host-UID mapping. Omit for the default (align with Signal K host user,
1070
+ // assuming the image runs as root). Set { inImageUid, inImageGid } when
1071
+ // the image declares a non-root USER. Set false to opt out entirely.
1072
+ user?: { inImageUid?: number; inImageGid?: number } | false;
951
1073
  // ...remaining fields (ports, volumes, env, networkMode, command, resources, ...)
952
1074
  }
953
1075
  interface ConsumerManifest {
@@ -981,7 +1103,11 @@ interface HistoryEntry {
981
1103
  triggeredBy?: string;
982
1104
  }
983
1105
  interface ContainerManagerApi {
984
- getRuntime: () => { runtime: string; version: string } | null;
1106
+ getRuntime: () => {
1107
+ runtime: string;
1108
+ version: string;
1109
+ hostUser?: { uid: number; gid: number } | null; // null on Windows
1110
+ } | null;
985
1111
  whenReady: () => Promise<void>;
986
1112
  ensureRunning: (
987
1113
  name: string,
@@ -1037,6 +1163,12 @@ interface ContainerManagerApi {
1037
1163
  list: () => Promise<ConsumerManifest[]>;
1038
1164
  getContainerHistory: (containerName: string) => Promise<HistoryEntry[]>;
1039
1165
  };
1166
+ doctor: {
1167
+ imageRunsAsUser: (
1168
+ image: string,
1169
+ user?: { inImageUid?: number; inImageGid?: number } | false,
1170
+ ) => Promise<{ ok: boolean; output: string; error?: string }>;
1171
+ };
1040
1172
  }
1041
1173
  ```
1042
1174
 
@@ -1123,6 +1255,8 @@ if (isContainerized()) {
1123
1255
  // - host runtime must be exposed (docker.sock + binary)
1124
1256
  // - spawned containers are siblings, not nested
1125
1257
  // - host.containers.internal points to the actual host
1258
+ // (signalk-container 1.8.0+ adds this mapping for Docker too;
1259
+ // Podman has it natively)
1126
1260
  // - shared networks need explicit setup
1127
1261
  }
1128
1262
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-container",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "description": "Shared container runtime management (Podman/Docker) for Signal K plugins",
5
5
  "keywords": [
6
6
  "signalk-node-server-plugin",