How to Configure User Namespaces for Containers in act Using the `--userns` Flag

The --userns flag in act forwards Docker's user-namespace option directly to the Docker Engine, allowing containers to run with custom UID/GID mappings when the daemon is configured for user-namespace remapping.

The nektos/act tool lets you run GitHub Actions workflows locally by spinning up Docker containers that replicate the GitHub-hosted runner environment. When you need to control user namespace isolation for these containers—either to enable additional security through remapped UIDs or to run with the host's namespace—the --userns flag bridges the gap between act's CLI and Docker's underlying user-namespace support.

How the --userns Flag Works in act

Unlike act's own configuration, the --userns flag is a pass-through mechanism. It does not modify the host UID/GID mapping itself; instead, it validates the mode and injects it into Docker's container creation parameters. The implementation spans the CLI definition, runner configuration, and container execution layers.

CLI Flag Definition in cmd/root.go

The flag is registered in the root command where act parses global options. In cmd/root.go at lines 90-93, the code defines a string flag that captures the user's input:

rootCmd.Flags().StringVar(&input.usernsMode, "userns", "", "user namespace to use")

This stores the raw string value (such as "host" or "private") into the Input struct for later processing.

Deprecation Warning Handling

When the flag is invoked, act emits a deprecation notice. The source at cmd/root.go lines 595-596 logs a warning that this option is deprecated, though it continues to function for backward compatibility.

Runner Configuration Propagation

The input value travels from the CLI layer into the runner's execution context. In pkg/runner/runner.go at line 45, the RunContext configuration includes a dedicated field:

UsernsMode string // user namespace to use

This ensures the user namespace setting persists through the job execution lifecycle and reaches the container package where Docker API calls are constructed.

Docker CLI Option Conversion in docker_cli.go

Before act can create a container, it must convert the string input into a Docker API-compatible type. In pkg/container/docker_cli.go at lines 501-503, the code validates and casts the mode:

usernsMode := container.UsernsMode(copts.usernsMode)

If the supplied mode is not recognized by Docker (for example, an invalid string), this conversion triggers an error: "--userns: invalid USER mode". Once validated, the mode is injected into the container configuration at lines 659-660:

UsernsMode: usernsMode,

Container Creation in docker_run.go

The final hand-off occurs in pkg/container/docker_run.go at lines 466-467, where act constructs the actual Docker API request. The UsernsMode field from the input struct is cast again and passed to the container configuration:

UsernsMode: container.UsernsMode(input.UsernsMode),

This maps directly to Docker's --userns runtime option, ensuring the container launches with the requested namespace isolation.

Prerequisites for Configuring User Namespaces

Before using --userns with act, your environment must support user namespace remapping at the Docker daemon level.

  • Docker Engine 1.13 or later: User namespace support was introduced in Docker 1.13. Verify your version with docker version.
  • Daemon --userns-remap configuration: The Docker daemon must be explicitly configured with user namespace remapping (e.g., --userns-remap=default or a specific user:group mapping). Without this, the --userns flag has no effect regardless of the value passed to act.
  • Rootless Docker compatibility: While rootless Docker inherently uses user namespaces, the --userns flag still functions as a passthrough to the runtime configuration.

Practical Usage Examples

To run a workflow with the host's user namespace (no UID remapping), invoke act with the flag set to host:

act -j myjob --userns=host

To run with a private user namespace, which requires the Docker daemon to have --userns-remap enabled:

act -j myjob --userns=private

If you omit the flag, containers inherit the default namespace behavior defined by your Docker daemon configuration. Both commands translate to Docker run invocations similar to:

docker run --userns=host ...
docker run --userns=private ...

Summary

  • The --userns flag in nektos/act forwards the user namespace mode directly to Docker without modifying host UID/GID mappings.
  • Source implementation spans cmd/root.go (flag definition), pkg/runner/runner.go (configuration storage), pkg/container/docker_cli.go (validation and option building), and pkg/container/docker_run.go (API execution).
  • Validation occurs in docker_cli.go, which returns an error if Docker does not recognize the supplied mode.
  • Deprecation warning is emitted when the flag is used, though functionality remains intact.
  • Daemon requirement: Docker must be configured with --userns-remap for the flag to produce meaningful isolation.

Frequently Asked Questions

What does the --userns flag do in act?

The --userns flag tells act to pass a specific user namespace mode (host, private, or custom) to the Docker Engine when creating workflow containers. This allows you to control whether the container runs with the host's user identity or a remapped UID/GID namespace, provided your Docker daemon supports user namespace remapping.

Why do I get an error when using --userns?

If you see "--userns: invalid USER mode", the string you provided is not recognized by Docker's container.UsernsMode type. Valid values are typically host (no remapping) or private (requires daemon remapping). Additionally, if the container fails to start with permission errors, your Docker daemon likely lacks the --userns-remap configuration required for private namespaces.

Is the --userns flag deprecated in act?

Yes. According to the source in cmd/root.go lines 595-596, act logs a deprecation warning when you use --userns. Despite this warning, the flag remains functional and continues to forward the user namespace setting to Docker as implemented in pkg/container/docker_cli.go and pkg/container/docker_run.go.

Do I need rootless Docker to use user namespaces?

No. Rootless Docker already operates within a user namespace, but you can still use --userns with standard Docker daemons as long as they are configured with --userns-remap. The flag is runtime-agnostic; it merely passes the configuration to whichever Docker endpoint act is targeting.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →