Skip to main content

langchain-docker-backend

Docker sandbox backend for AI agents — execute code safely in isolated containers.

Installation

pip install langchain-docker-backend

Prerequisites: Docker must be installed and running. The default image below works out of the box — pull it before first use:

docker pull ghcr.io/astral-sh/uv:python3.13-bookworm-slim

💡 Any Docker image works. ghcr.io/astral-sh/uv:python3.13-bookworm-slim is just the default. You can use any image — python:3.13-slim, ubuntu:22.04, node:20, or your own custom image. Pass it via image= to match your runtime needs.

Connecting to Docker

DockerSandbox connects to Docker via docker.from_env(). By default it reads the DOCKER_HOST environment variable, falling back to the local Unix socket (/var/run/docker.sock).

Local Docker (default)

The most common setup — your code runs on the host and connects to the local Docker daemon. No extra configuration needed:

sandbox = DockerSandbox()  # connects to /var/run/docker.sock

Docker-in-Docker

When running the library itself inside a container, there are two approaches:

Approach 1 — Socket mount (Docker outside of Docker)

Mount the host's Docker socket into the container. The container shares the host's Docker daemon — simpler and more lightweight:

docker run -v /var/run/docker.sock:/var/run/docker.sock your-image
# Inside the container — works the same way
sandbox = DockerSandbox()

Note: This gives the container access to the host's Docker daemon. Make sure the security implications are acceptable for your use case.

Approach 2 — True Docker-in-Docker (DinD)

Run a full Docker daemon inside the container using the docker:dind image. Completely isolated from the host's Docker, but requires --privileged:

docker run --privileged docker:dind
# Inside the DinD container — point to the inner daemon
sandbox = DockerSandbox(
    docker_client_kwargs={"base_url": "unix:///var/run/docker.sock"}
)

Note: --privileged grants the container extended Linux capabilities. Prefer the socket mount approach unless you need full isolation between the inner and outer Docker daemons.

Remote Docker

Connect to a Docker daemon on another machine via TCP.

Option 1: Environment variable (recommended)

export DOCKER_HOST=tcp://192.168.1.100:2375
sandbox = DockerSandbox()  # reads DOCKER_HOST automatically

Option 2: Explicit docker_client_kwargs

sandbox = DockerSandbox(
    docker_client_kwargs={"base_url": "tcp://192.168.1.100:2375"}
)

With TLS:

import docker.tls

sandbox = DockerSandbox(
    docker_client_kwargs={
        "base_url": "tcp://192.168.1.100:2376",
        "tls": docker.tls.TLSConfig(
            ca_cert="/path/to/ca.pem",
            client_cert=("/path/to/cert.pem", "/path/to/key.pem"),
        ),
    }
)

Usage

deepagents

Plug DockerSandbox into a deep agent — the agent gets a full set of sandbox tools and runs code in an isolated container:

from deepagents import create_deep_agent
from langchain_anthropic import ChatAnthropic
from langchain_docker_backend import DockerSandbox

sandbox = DockerSandbox()

try:
    agent = create_deep_agent(
        model=ChatAnthropic(model="claude-sonnet-4-6"),
        system_prompt="You are a coding assistant with sandbox access.",
        backend=sandbox,
    )
    result = agent.invoke({
        "messages": [{"role": "user", "content": "Write and run a fizzbuzz script"}]
    })
    print(result)
finally:
    sandbox.close()

LangChain

With LangChain, wire it through FilesystemMiddleware:

from langchain.agents import create_agent
from langchain_anthropic import ChatAnthropic
from deepagents.middleware.filesystem import FilesystemMiddleware
from langchain_docker_backend import DockerSandbox

sandbox = DockerSandbox()

try:
    agent = create_agent(
        model=ChatAnthropic(model="claude-sonnet-4-6"),
        middleware=[FilesystemMiddleware(backend=sandbox)],
    )
    result = agent.invoke({
        "messages": [{"role": "user", "content": "Write a fizzbuzz script and run it"}]
    })
finally:
    sandbox.close()

Direct Usage

Beyond agent use, you can interact with the sandbox directly — execute commands, read and write files, list directories, edit file content.

Pick any image to suit your stack:

sandbox = DockerSandbox(image="python:3.13-slim")      # bare Python
sandbox = DockerSandbox(image="node:20")                # Node.js
sandbox = DockerSandbox(image="ubuntu:22.04")           # Ubuntu
sandbox = DockerSandbox()                               # default (uv + Python 3.13)
from langchain_docker_backend import DockerSandbox

sandbox = DockerSandbox()

try:
    # Execute commands
    result = sandbox.execute("echo 'Hello from Docker!'")
    print(result.output)      # Hello from Docker!
    print(result.exit_code)   # 0

    # Write a file
    sandbox.write("/workspace/test.txt", "Hello, World!")

    # Read it back
    file = sandbox.read("/workspace/test.txt")
    print(file.file_data["content"])  # Hello, World!

    # List a directory
    ls = sandbox.ls("/workspace")
    for entry in ls.entries:
        print(entry["path"], entry.get("is_dir", False))

    # Find and replace
    sandbox.edit("/workspace/test.txt", "Hello", "你好")

    # Upload / download binary files
    sandbox.upload_files([("data.bin", b"\x00\x01\x02")])
    files = sandbox.download_files(["data.bin"])
    print(files[0].content)  # b'\x00\x01\x02'

    # Commands time out
    result = sandbox.execute("sleep 10", timeout=2)
    print(result.exit_code)   # 124
finally:
    sandbox.close()

Network & Hardware Configuration

Network, DNS, GPU and resource settings are applied when the container is created:

from langchain_docker_backend import DockerSandbox

with DockerSandbox(
    network_mode="host",          # "bridge" (Docker default), "host", "none", "container:<id>"
    dns=["1.1.1.1", "8.8.8.8"],   # custom DNS servers
    gpus="all",                   # "all" or a number of GPUs
    container_kwargs={            # any other docker-py containers.run() option
        "mem_limit": "4g",
        "nano_cpus": 2_000_000_000,               # 2 CPUs
        "shm_size": "2g",
        "devices": ["/dev/accel0:/dev/accel0"],   # pass through host devices
    },
) as sandbox:
    sandbox.execute("pip install requests")
  • No internet inside the sandbox? Containers on Docker's default bridge network already have outbound access. If package installs or web requests fail, DNS is the usual cause (e.g. a host using 127.0.0.53 and a network that blocks Docker's 8.8.8.8 fallback) — set dns=[...] to resolvers reachable from your network before reaching for network_mode="host".
  • GPUs require the NVIDIA Container Toolkit on the host. Other accelerators (NPUs, TPUs, ...) can be exposed via container_kwargs={"devices": [...]} or {"device_requests": [...]}.
  • Isolation: network_mode="host", host devices and container_kwargs={"privileged": True} weaken the sandbox boundary. Use network_mode="none" for fully offline agents.

Design

DockerSandbox implements BaseSandbox, which defines a full set of sandbox operations — synchronous and asynchronous — including execute, file reads and writes, directory listing, glob, grep, and more.

When plugged into FilesystemMiddleware or create_deep_agent(backend=...), most operations are exposed as tools that the agent model decides when to invoke: the model autonomously chooses to ls a directory, read_file, write_file, execute a command, etc.

The exception is upload_files and download_files. These remain developer-only — the developer controls what data enters the sandbox and what results to extract, not the model.

API Reference

DockerSandbox

Parameter Type Default Description
image str ghcr.io/astral-sh/uv:python3.13-bookworm-slim Any Docker image (public, private, or custom)
container_name str | None auto-generated Container name
volumes dict {} Volume mounts
working_dir str /workspace Working directory inside container
auto_remove bool True Remove container on close
execute_timeout int 120 Default timeout in seconds
max_output_bytes int 512000 Max output bytes before truncation
docker_client_kwargs dict | None None Extra keyword arguments for docker.from_env() (e.g. base_url, tls)
network_mode str | None None (Docker default bridge) Container network mode: "bridge", "host", "none", "container:<id>"
dns list[str] | None None Custom DNS servers
gpus int | str | None None GPUs to expose: "all" or a positive count (needs NVIDIA Container Toolkit)
container_kwargs dict | None None Extra keyword arguments for client.containers.run() (e.g. mem_limit, nano_cpus, devices, shm_size)

Key Methods

Method Description
execute(command, *, timeout) Run a shell command
write(path, content) Write a text file
read(path) Read a text file
ls(path) List directory contents
edit(path, find, replace) Find and replace in a file
upload_files(files) Upload binary files (tar-based)
download_files(paths) Download binary files (tar-based)
close() Stop and optionally remove container

ExecuteResponse

Field Type Description
output str Combined stdout + stderr
exit_code int Command exit code
truncated bool Whether output was truncated

Metadata

Release files for langchain-docker-backend 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for langchain-docker-backend 1.1.0
File Size Uploaded Provenance Actions
langchain_docker_backend-1.1.0.tar.gz 113.6 kB With provenance Details for langchain_docker_backend-1.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for langchain-docker-backend 1.1.0
File Interpreter ABI Platform Actions
langchain_docker_backend-1.1.0-py3-none-any.whl Python 3 none any Details for langchain_docker_backend-1.1.0-py3-none-any.whl

Total release size: 124.7 kB

Release files / langchain_docker_backend-1.1.0.tar.gz

Download URL langchain_docker_backend-1.1.0.tar.gz
Size 113.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9dca54afd9ce0ae3d698ea3eba2e9f114f0d5360d38af1f80d96fb80feee3cf4
BLAKE2b-256 checksum
How to use checksums
7421fc604da4d3d46682f029c8bcddf45cffa32cab681e2ec94d32fd079f043a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / langchain_docker_backend-1.1.0-py3-none-any.whl

Download URL langchain_docker_backend-1.1.0-py3-none-any.whl
Size 11.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
93e1f28c9f7e2c090e7b7b7d3ff7551f7e63e97456da1041367190ea98898490
BLAKE2b-256 checksum
How to use checksums
bf68e32faf297dc448d55b2f239be9e7addb481c812b7295d4e976943cf3dd08
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for langchain-docker-backend 1.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for langchain_docker_backend-1.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page