Skip to main content
nono and containers (Docker, Podman, etc.) provide different isolation models. This guide helps you choose the right tool for your use case.

Quick Comparison

AspectnonoDocker Container
Startup time~0ms~100-500ms
Setup requiredNoneDockerfile, daemon
Filesystem modelPath-level allow/denySeparate filesystem
Works on host filesYes (directly)Requires volume mounts
Credential protectionAutomatic blocklistManual (don’t mount)
Network isolationOn/offFull namespace
Resource limitsNoYes (cgroups)
Process isolationNoYes (PID namespace)

When to Use nono

nono excels when you need:

Zero-Latency Startup

# Instant startup - no container overhead
nono run --allow . -- claude-code

# Compare to Docker
docker run -v $(pwd):/work -it my-agent  # 100-500ms+ overhead per invocation

Direct Access to Your Working Directory

AI coding agents need to read and modify your actual source files. With nono, this works naturally:
# Agent can edit files in current directory
nono run --allow . -- aider
With Docker, you need will need to create volume mounts and set permission issues:
# Volume mounts can cause UID/GID mismatches
docker run -v $(pwd):/work -u $(id -u):$(id -g) my-agent

Automatic Credential Protection

nono blocks sensitive paths by default, even if you allow a parent directory:
# Allows ~/projects but still blocks ~/.ssh, ~/.aws, etc.
nono run --allow ~/projects -- agent
With Docker, you must be careful not to mount sensitive directories:
# Easy to accidentally expose secrets
docker run -v $HOME:/home/user my-agent  # Dangerous!

Zero Configuration

nono requires no setup - just install and run:
brew install nono
nono run --allow . -- my-agent
Docker requires:
  • Docker daemon running
  • Dockerfile for custom images
  • Understanding of volumes, networks, users
  • Image pulls and builds

When to Use Containers

Containers are better when you need:

Full Environment Isolation

If the agent needs specific system libraries, language runtimes, or tools:
FROM python:3.11
RUN pip install numpy pandas tensorflow
nono runs in your existing environment - it doesn’t provide a separate runtime.

Resource Limits

Containers can limit CPU, memory, and I/O:
docker run --memory=2g --cpus=1 my-agent
nono does not limit resources. A runaway agent can consume all available CPU/memory.

Process Isolation

Containers have separate PID namespaces - processes inside can’t see or signal host processes:
# Inside container, can only see container processes
docker run my-agent ps aux  # Shows only container processes
nono shares the host PID namespace - the sandboxed process can see (but not necessarily interact with) other processes.

Reproducible Environments

For CI/CD or sharing exact environments:
# Same environment everywhere
docker run my-org/agent:v1.2.3 -- run-tests

Using Both Together

For maximum security, combine nono with containers:
# Dockerfile
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y nono
ENTRYPOINT ["nono", "run", "--allow", "/work"]
# Defense in depth: container + nono
docker run -v $(pwd):/work my-nono-agent -- claude-code
This gives you:
  • Container’s namespace isolation
  • Container’s resource limits
  • nono’s path-level filesystem control
  • nono’s automatic credential blocking

Threat Model Comparison

What nono Protects Against

  • Reading/writing files outside allowed paths
  • Accessing credentials (~/.ssh, ~/.aws, etc.)
  • Running blocked commands (rm, dd, etc.)
  • Network access (when blocked)

What Containers Protect Against

  • All of the above (but with a fair amount of configuration)
  • Process visibility and signaling
  • Resource exhaustion (with limits)
  • Environment contamination

What Neither Protects Against

  • Kernel vulnerabilities
  • Side-channel attacks
  • Prompt Injection (which no one can fully prevent)
  • Social engineering (agent convinces you to run dangerous command)

Performance Comparison

Startup Time

# nono: instant
time nono run --allow . -- echo hello
# real    0m0.005s

# Docker (warm, image cached)
time docker run alpine echo hello
# real    0m0.350s

# Docker (cold, needs pull)
time docker run alpine echo hello
# real    0m2.500s

Memory Overhead

  • nono: ~0 MB (just applies sandbox and execs)
  • Docker: ~10-50 MB per container (runtime overhead)

Disk Usage

  • nono: ~2 MB binary
  • Docker: 100 MB+ per image (varies widely)

Migration Guide

From Docker to nono

If you’re currently using Docker just for sandboxing:
# Before: Docker
docker run -v $(pwd):/work -w /work python:3.11 python script.py

# After: nono (uses your installed Python)
nono run --allow . -- python script.py

Decision Flowchart

Do you need a different OS to the host?
├── Yes → Use containers
└── No

    Do you need resource limits (CPU/memory)?
    ├── Yes → Use containers (or both)
    └── No

        Do you need process isolation?
        ├── Yes → Use containers (or both)
        └── No

            Is startup time critical?
            ├── Yes → Use nono
            └── No

                Do you need path-level filesystem control?
                ├── Yes → Use nono (or both)
                └── No → Either works

Summary

Use CaseRecommendation
AI coding agents (Claude, Aider, etc.)nono
CI/CD pipelinesContainers
Interactive developmentnono
Untrusted code executionBoth
Reproducible environmentsContainers
Quick sandboxing, zero setupnono
Resource-limited executionContainers
Maximum securityBoth

Next Steps