How to set up Docker containers for safely running AI agents
Problem
When I started using AI coding agents like Claude, I worried about giving them full access to my computer. What if the agent accidentally deleted important files? What if it accessed my .env files with API keys?
I saw this warning on Reddit:
“I think safe way is to use inside docker container”
But then another user pointed out:
“if you don’t understand security, that environment can still access your network”
So I needed to figure out the right way to set up Docker for AI agent isolation.
Environment
- Docker Desktop 4.x
- macOS Sonoma
- Claude Code CLI
What happened?
Initially, I just ran Claude directly on my machine. It had access to everything:
/home/user/├── .ssh/ # SSH keys├── .env # API keys├── projects/ # Work code├── personal/ # Private documents└── .aws/ # AWS credentialsThis made me nervous. I wanted Claude to help with coding, but not touch my personal files or credentials.
I tried running Claude in a basic Docker container:
docker run -it -v ~/:/workspace python:3.11-slim bashBut this was worse! I mounted my entire home directory, giving Claude access to everything plus the container environment.
How to solve it?
Step 1: Create a minimal Dockerfile
I started by creating a Dockerfile specifically for AI agent work:
FROM python:3.11-slim
WORKDIR /workspace
# Install useful toolsRUN apt-get update && apt-get install -y \ git \ curl \ && rm -rf /var/lib/apt/lists/*
# Create non-root userRUN useradd -m -s /bin/bash agentUSER agent
# Set safe working directoryWORKDIR /workspaceThe key changes from my first attempt:
- Using
python:3.11-sliminstead of full images (smaller attack surface) - Creating a non-root user
agent - Working directory is isolated
Step 2: Build the image
docker build -t claude-sandbox .Step 3: Run with minimal volume mounts
Instead of mounting my home directory, I only mount the specific project:
docker run -it \ -v $(pwd)/my-project:/workspace \ --network none \ claude-sandbox \ bashThe important flags:
-v $(pwd)/my-project:/workspace- Only the project directory, not home--network none- No network access at all
Step 4: Test the isolation
Inside the container, I verified:
agent@container:~$ ls /bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
agent@container:~$ ls /workspace# Only my project files
agent@container:~$ curl google.comcurl: (6) Could not resolve host: google.com# Network blocked - good!When you need network access
Sometimes the AI agent needs to install packages. I use a two-step approach:
Step 1: Build with dependencies
FROM python:3.11-slim
WORKDIR /workspace
# Install dependencies during build (has network)RUN pip install anthropic requests
# Then remove network capabilityWORKDIR /workspaceRUN useradd -m -s /bin/bash agentUSER agentStep 2: Run without network
docker build -t claude-ready -f Dockerfile.with-deps .docker run -it -v $(pwd)/my-project:/workspace --network none claude-ready bashHandling credentials properly
The biggest mistake is storing credentials inside the container. Instead, I use environment variables from the host:
docker run -it \ -v $(pwd)/my-project:/workspace \ -e ANTHROPIC_API_KEY \ --network none \ claude-sandbox \ bashBut wait - if there’s no network, how does Claude API work?
I had to reconsider. For AI agents that need API access:
# Allow only API trafficdocker run -it \ -v $(pwd)/my-project:/workspace \ -e ANTHROPIC_API_KEY \ claude-sandbox \ bashI remove --network none but still:
- No home directory mounted
- No SSH keys accessible
- No AWS credentials mounted
- Only the specific project
The reason
The core security principles I learned:
- Least privilege access: Mount only what’s needed, nothing more
- Network isolation: Use
--network nonewhen possible, or firewall rules - Credential separation: Pass credentials via environment variables, not files
- Non-root user: Run as unprivileged user inside container
- Minimal image: Use slim images to reduce attack surface
Docker containers are NOT virtual machines. They share the kernel with the host. But for file system isolation and limiting what an AI agent can access, they work well.
┌─────────────────────────────────────────┐│ Host Machine ││ ┌─────────────────────────────────┐ ││ │ Docker Container │ ││ │ ┌─────────────────────────┐ │ ││ │ │ /workspace/ │ │ ││ │ │ (only project files) │ │ ││ │ └─────────────────────────┘ │ ││ │ │ ││ │ NO access to: │ ││ │ - ~/.ssh/ │ ││ │ - ~/.aws/ │ ││ │ - ~/personal/ │ ││ └─────────────────────────────────┘ │└─────────────────────────────────────────┘Common mistakes to avoid
I made these mistakes - don’t repeat them:
| Mistake | Why it’s bad | Correct approach |
|---|---|---|
-v ~/:/workspace | Exposes entire home directory | Mount only specific project |
| Running as root | Full control if compromised | Use non-root user |
--network host | Full network access | Use --network none or default bridge |
| Credentials in Dockerfile | Baked into image layers | Pass via -e at runtime |
| Storing .env in project | Agent can read it | Use .dockerignore to exclude |
Summary
In this post, I showed how to set up Docker containers for safely running AI agents. The key points are: mount only the specific project directory, use --network none when possible, run as non-root user, and pass credentials via environment variables instead of files.
Docker containers provide good filesystem isolation for AI agents without the overhead of full virtual machines. But remember - containers share the kernel, so they’re not a complete security solution. For sensitive work, consider additional measures like seccomp profiles or even proper VMs.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Reddit: Running Claude locally
- 👨💻 Docker Documentation - Containers
- 👨💻 Docker Network Configuration
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments