Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/claude_isolated/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ def cmd_start(args: argparse.Namespace) -> None:
*[flag for src, dest, mode in volumes for flag in ("-v", f"{src}:{dest}:{mode}")],
]

if args.podman:
run_args += [
"--device", "/dev/fuse",
"--security-opt", "label=disable",
"--security-opt", "unmask=ALL",
]

if wt.is_worktree:
run_args += ["-w", workspace_mount]

Expand Down Expand Up @@ -200,11 +207,14 @@ def cmd_ls(args: argparse.Namespace) -> None:
def main() -> None:
# If first arg isn't a subcommand, treat as default: build + start [prompt]
if not sys.argv[1:] or sys.argv[1] not in SUBCOMMANDS:
prompt = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else ""
# Parse --podman flag from argv before treating rest as prompt
use_podman = "--podman" in sys.argv[1:]
remaining = [a for a in sys.argv[1:] if a != "--podman"]
prompt = " ".join(remaining)
with spinner("Building Containerfile.."):
cmd_build(argparse.Namespace(), silent=True)
print(f'\r✔ Running Claude Code in bypass permissions mode..')
cmd_start(argparse.Namespace(prompt=prompt))
cmd_start(argparse.Namespace(prompt=prompt, podman=use_podman))
return

parser = argparse.ArgumentParser(description="Run Claude Code in isolated Podman containers")
Expand All @@ -215,6 +225,7 @@ def main() -> None:
sub.add_parser("build", help="Build the container image")

p_start = sub.add_parser("start", help="Start a new container")
p_start.add_argument("--podman", action="store_true", help="Enable nested Podman inside the container")
p_start.add_argument("prompt", nargs="?", default="", help="Optional prompt for Claude")

p_stop = sub.add_parser("stop", help="Stop and remove a container")
Expand Down
17 changes: 16 additions & 1 deletion src/claude_isolated/data/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,28 @@ RUN echo "deb http://deb.debian.org/debian sid main" \
&& apt-get install -y --no-install-recommends -t sid git \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user
# Podman-in-Podman: nested rootless container support
RUN apt-get update && apt-get install -y --no-install-recommends \
podman \
fuse-overlayfs \
slirp4netns \
uidmap \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user with subordinate UID/GID ranges for nested podman
RUN useradd -m -d /home/claude -s /bin/bash claude
RUN echo "claude:100000:65536" >> /etc/subuid \
&& echo "claude:100000:65536" >> /etc/subgid
RUN mkdir -p /home/claude/.claude /workspace \
&& chown -R claude:claude /home/claude /workspace

USER claude

# Configure rootless podman storage (fuse-overlayfs inside container)
RUN mkdir -p /home/claude/.config/containers \
&& printf '[storage]\ndriver = "overlay"\n\n[storage.options.overlay]\nmount_program = "/usr/bin/fuse-overlayfs"\n' \
> /home/claude/.config/containers/storage.conf

# Install uv
ARG UV_VERSION=0.10.11
RUN curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh
Expand Down