Skip to content

Container invocation

The full Docker form is:

Terminal window
mkdir -p manuscrio-output
docker run --rm --init --ipc=host \
--user "$(id -u):$(id -g)" \
-v "$PWD/build:/input:ro" \
-v "$PWD/manuscrio-output:/output" \
manuscrio export /input --output-dir /output

The mounts and Manuscrio arguments are shared with Podman, but rootless Podman also needs a user namespace. The rootless Podman form adds --userns=keep-id to Docker’s explicit user mapping.

Everything on this page describes running the image yourself. Other pages write manuscrio …, the npm command, which assembles exactly this from paths on your machine — which is why it takes ./build where the commands here take /input. What each flag is for is the same either way, and worth reading once.

--rm discards the container when the command exits. Manuscrio keeps no state between runs; everything it produces is in the output directory.

--init runs the container under an init process that reaps the browser’s child processes. A rendering run starts and stops Chromium repeatedly, and without this those processes accumulate.

--ipc=host gives Chromium the host’s shared-memory segment instead of the container’s small default allocation. It is the arrangement Chromium’s own guidance recommends for containers, and it is not needed for inspect, which never starts a browser.

--user "$(id -u):$(id -g)" runs the engine as you. Two things depend on it:

  • PDFs land in the output directory owned by you rather than by the image’s own user, which is what lets a later step in the same job read, move, or delete them; and
  • a licence file that belongs to you and is mode 0600 stays readable. Manuscrio treats a licence it cannot read as a failure rather than quietly reverting to Evaluation Mode, so the wrong user turns a valid licence into a failed export.

-v "$PWD/build:/input:ro" mounts the Site Build read-only. Manuscrio works from a temporary staged copy inside the container and never writes to the input, so the read-only flag costs nothing and rules out a whole class of doubt about a directory your build system owns.

-v "$PWD/manuscrio-output:/output" is where PDFs are written. Create it before the run; Docker would otherwise create it as root. Always pass --output-dir /output to match: the default output location is beside the Site Build, which inside the container means the container’s own root directory, and the run would fail trying to write there. This is one of the things the manuscrio command does for you — it creates the directory, mounts it, and passes the option — which is why --output-dir is optional there and mandatory here.

Anything else Manuscrio needs to read — a --logo, a --license — must be mounted too, and the path you pass is the path inside the container, not the one on your machine.

A licence file has a conventional mount point, so the direct command needs no --license option:

Terminal window
docker run ... \
-v "$PWD/acme.manuscrio-license:/etc/manuscrio/license:ro" \
manuscrio export /input --output-dir /output

Podman maps bind-mounted files through a user namespace. Use --userns=keep-id to map your UID and GID, and an explicit --user to override the image’s own USER pwuser:

Terminal window
mkdir -p manuscrio-output
podman run --rm --init --ipc=host \
--userns=keep-id \
--user "$(id -u):$(id -g)" \
-v "$PWD/build:/input:ro" \
-v "$PWD/manuscrio-output:/output" \
manuscrio export /input --output-dir /output

Both flags are required on Podman 5.4 for output on a bind mount to retain the caller’s ownership. Without them a restrictive output directory fails; a more permissive one can succeed but leaves PDFs owned by a subordinate UID rather than by the caller.

Rootful Podman is the Docker case: it does not need keep-id, so use the simpler Docker form above. The manuscrio command asks Podman which it is and supplies the right flags either way.

This is the single most common mistake:

Terminal window
# Wrong: /home/you/brand/logo.svg does not exist inside the container.
docker run ... manuscrio export /input --logo "$PWD/brand/logo.svg"
# Right: mount it, then name the mounted path.
docker run ... -v "$PWD/brand/logo.svg:/brand/logo.svg:ro" \
manuscrio export /input --logo /brand/logo.svg

The mistake is only possible when you write the run yourself. Doing this translation — for the Site Build, the output directory, --logo and --license alike — is most of what the manuscrio command exists for.