Container invocation
The full Docker form is:
mkdir -p manuscrio-outputdocker 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 /outputThe 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.
The flags
Section titled “The flags”--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.
The mounts
Section titled “The mounts”-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:
docker run ... \ -v "$PWD/acme.manuscrio-license:/etc/manuscrio/license:ro" \ manuscrio export /input --output-dir /outputRootless Podman
Section titled “Rootless Podman”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:
mkdir -p manuscrio-outputpodman 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 /outputBoth 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.
Paths are read inside the container
Section titled “Paths are read inside the container”This is the single most common mistake:
# 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.svgThe 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.