ToolHive's Kubernetes operator supports readOnlyRootFilesystem: true, but the standalone Docker runtime currently creates MCP workload containers without an equivalent rootfs hardening option.
Problem
For a standalone workload created through thv run/start, Docker HostConfig.ReadonlyRootfs remains false. Permission profiles can constrain mounts, network, capabilities, and privileged mode, but there is no supported CLI/runconfig field for making the container root filesystem read-only.
A post-create Docker override is not durable because ToolHive reconciles/recreates the workload from its stored runconfig.
Proposed behavior
Add an opt-in standalone runtime setting, exposed through CLI + runconfig, that maps to:
HostConfig.ReadonlyRootfs = true
For workloads that need scratch space, support explicit tmpfs entries (for example /tmp) rather than leaving the whole writable layer enabled.
Reconciliation should include the read-only-rootfs/tmpfs settings so an existing writable-root container is recreated when the desired security configuration changes.
Validation
A local proof against the pinned @modelcontextprotocol/server-everything image works with:
- read-only rootfs enabled
/tmp mounted as tmpfs with rw,nosuid,nodev,noexec,size=64m
- non-root user
CapDrop=ALL
- network mode
none
The MCP server remains functional while writes to application/system paths fail as expected.
This would bring standalone Docker deployments closer to the operator's existing security posture without requiring users to introduce Kubernetes solely for immutable-root enforcement.
ToolHive's Kubernetes operator supports
readOnlyRootFilesystem: true, but the standalone Docker runtime currently creates MCP workload containers without an equivalent rootfs hardening option.Problem
For a standalone workload created through
thv run/start, DockerHostConfig.ReadonlyRootfsremains false. Permission profiles can constrain mounts, network, capabilities, and privileged mode, but there is no supported CLI/runconfig field for making the container root filesystem read-only.A post-create Docker override is not durable because ToolHive reconciles/recreates the workload from its stored runconfig.
Proposed behavior
Add an opt-in standalone runtime setting, exposed through CLI + runconfig, that maps to:
For workloads that need scratch space, support explicit tmpfs entries (for example
/tmp) rather than leaving the whole writable layer enabled.Reconciliation should include the read-only-rootfs/tmpfs settings so an existing writable-root container is recreated when the desired security configuration changes.
Validation
A local proof against the pinned
@modelcontextprotocol/server-everythingimage works with:/tmpmounted as tmpfs withrw,nosuid,nodev,noexec,size=64mCapDrop=ALLnoneThe MCP server remains functional while writes to application/system paths fail as expected.
This would bring standalone Docker deployments closer to the operator's existing security posture without requiring users to introduce Kubernetes solely for immutable-root enforcement.