diff --git a/src/docker-run.js b/src/docker-run.js index 39ca043..2cb9aac 100644 --- a/src/docker-run.js +++ b/src/docker-run.js @@ -10,6 +10,8 @@ * - `--rm -i` (always disposable, interactive stdin) * - `--network none`, unless `networkNeeded` (i.e. `--node-modules` is set) * - `--read-only` root filesystem + a `/tmp` tmpfs mount + * - `-e HOME=/tmp`, so tools needing a writable `$HOME` (config/cache dirs) + * land on the writable `/tmp` tmpfs instead of the read-only rootfs * - `--cap-drop=ALL` * - `--security-opt=no-new-privileges` * @@ -35,6 +37,7 @@ function buildRunArgs(image, { networkNeeded, volumeName }) { const args = ["run", "--rm", "-i"]; if (!networkNeeded) args.push("--network", "none"); args.push("--read-only", "--tmpfs", "/tmp", "--cap-drop=ALL", "--security-opt=no-new-privileges"); + args.push("-e", "HOME=/tmp"); if (networkNeeded) { // --node-modules runs a real `npm install`, which needs a writable cache // dir; point it at the /tmp tmpfs since the root filesystem is read-only. diff --git a/test/unit/docker-run.unit.test.js b/test/unit/docker-run.unit.test.js index f6177a1..dcbae48 100644 --- a/test/unit/docker-run.unit.test.js +++ b/test/unit/docker-run.unit.test.js @@ -45,6 +45,8 @@ test("unit: buildRunArgs applies --network none by default and sandboxing flags" "/tmp", "--cap-drop=ALL", "--security-opt=no-new-privileges", + "-e", + "HOME=/tmp", "some-image" ]); }); @@ -58,6 +60,7 @@ test("unit: buildRunArgs omits --network none when networkNeeded (e.g. --node-mo args.includes("npm_config_cache=/tmp/.npm-cache"), "npm cache must be redirected off the read-only rootfs" ); + assert.ok(args.includes("HOME=/tmp"), "HOME must be redirected off the read-only rootfs"); }); test("unit: buildRunArgs mounts a named volume, never a bind mount, when volumeName is given", () => { @@ -65,6 +68,7 @@ test("unit: buildRunArgs mounts a named volume, never a bind mount, when volumeN const volumeIndex = args.indexOf("-v"); assert.ok(volumeIndex !== -1); assert.equal(args[volumeIndex + 1], `node-red-cli-userdir-abc:${CONTAINER_USER_DIR}`); + assert.ok(args.includes("HOME=/tmp")); }); test("unit: volumeNameFor is deterministic for the same --user-dir path", () => {