Background Agent Docker in Docker

What is the best way to get docker in docker supported for background agents? I have pytests fixtures which leverage testcontainers to spin up services like clickhouse. I would like the background agent to be able to run these tests, but I cannot seem to get docker in docker working since I don’t see how to pass the privileged flag.

What is the recommended path for a devcontainer that supports docker test containers?

Thanks!

4 Likes

Not using docker to provision the background agent, AI can setup docker environment in the background agent.

There should be a way to do this with dockerfile too.

Been trying this too, was able to install Docker via the convenience script, but trying to run the daemon still fails:

The docs (Cursor – Background Agents) mention this though, so not sure what else needs to be done:

The start command can often be skipped. One common case where you want to use it is if your dev environment relies on docker, in which case you would want to put sudo service docker start in the start command.

1 Like

I tried replicating this locally and the only way to avoid the “ulimit: error setting limit” error was to use --privileged and --ulimit nofile=65535:65535 like this:

docker run --privileged --ulimit nofile=65535:65535 -it test bash

I don’t think Cursor’s configuration file allows customizing these options though, so still not sure how to get this to work with background agents.

Did you end up figuring this one out? Figured out how to install docker & docker compose in the first place, but when running service docker start I’m getting the ulimit error you have above.

1 Like

I have the same problem here. My tests depends on using testcontainers to spin-up two ephemeral databases and currently the background agent is unable to run tests. Installing the docker client is simple, but there should be a docker daemon running. Curious about an official solution.

there is a start option in environments json, so you can run docker start.

could you share an example?

1 Like

Sure,

{
  "snapshot": "POPULATED_FROM_SETTINGS",
  "install": "npm install",
  "start": "sudo service docker start",
  "terminals": [
    {
      "name": "Run Next.js",
      "command": "npm run dev"
    },
    {
      "name": "Watch Files",
      "command": "npm run watch"
    }
  ]
}

When I do this, I get

/etc/init.d/docker: No such file or directory

docker: unrecognized service
1 Like

hi @Dan_Claroni this is because you are trying to use a Docker based MCP which requires the installation of docker (another software to run the MCP you want).

Hi everyone. I have a short example that demonstrates Docker-in-Docker working, so I’d like to share it. This gets the Docker daemon running when the task starts, but when I attempted to launch containers in the terminals, they were ignored

FROM ubuntu:25.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
    sudo \
    curl \
    wget \
    ca-certificates \
    gnupg \
    lsb-release \
    && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /etc/apt/keyrings && \
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg

RUN echo \
    "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

RUN apt-get update && apt-get install -y \
    docker-ce \
    docker-ce-cli \
    containerd.io \
    docker-buildx-plugin \
    docker-compose-plugin \
    && rm -rf /var/lib/apt/lists/*

RUN groupadd -f docker

RUN usermod -g docker -G sudo,ubuntu ubuntu && \
    echo "ubuntu ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

WORKDIR /workspace

USER ubuntu

VOLUME /var/lib/docker

CMD ["/bin/bash"]
{
  "build": {
    "context": ".",
    "dockerfile": "Dockerfile"
  },
  "start": "sudo service docker start",
  "terminals": [
    {
      "name": "Run Nginx",
      "command": "docker run -p 8080:80 nginx"
    }
  ]
}

Thanks @laiso for the update and bumping the topic up, will pass it to developers

Cc @andrewh

1 Like

Are there any updates on the Docker-in-Docker agent setup documentation?

Our repository setup includes both Docker and Docker Compose, and despite trying the suggested workarounds, the setup continues to fail.

Additionally, it seems impossible to switch from a snapshot-based setup to a Dockerfile-based one. Regardless of what we try (deleting environment.json, re-adding the Dockerfile, ..), the remote environment seemingly spins up an outdated snapshot.

Edit: added screenshot - Even after removing the json, adding a Dockerfile, restarting everything, Cursor warns about the outdated environment. How can I purge the remote state and initiate a clean setup?

3 Likes

While setting up the environment using the interactive mode I was able to get docker working after running these commands:

#!/bin/bash

# Docker Setup Script for Restricted Environments
# This script fixes Docker permission issues and networking problems
# common in containerized environments or VMs with limited capabilities

echo "🐳 Setting up Docker in restricted environment..."

# Step 1: Add current user to docker group
echo "📝 Adding user to docker group..."
sudo usermod -aG docker $USER

# Step 2: Verify docker group exists and user was added
echo "✅ Verifying docker group membership..."
getent group docker

# Step 3: Kill any existing Docker daemon processes
echo "🛑 Stopping any existing Docker processes..."
sudo pkill dockerd 2>/dev/null || true

# Step 4: Start Docker daemon with restricted networking
echo "🚀 Starting Docker daemon with networking restrictions disabled..."
sudo dockerd --iptables=false --bridge=none > /dev/null 2>&1 &

# Step 5: Wait for Docker daemon to start
echo "⏳ Waiting for Docker daemon to initialize..."
sleep 3

# Step 6: Activate docker group for current session
echo "🔐 Activating docker group for current session..."
newgrp docker << 'EOF'
# Test Docker is working
echo "🧪 Testing Docker functionality..."
docker ps

# Test running a container
echo "🎯 Testing container execution..."
docker run --rm --network=none alpine echo "Docker is working! 🎉"

echo ""
echo "✅ Docker setup complete!"
echo ""
echo "📋 Usage notes:"
echo "   • Use --network=none for containers (networking is disabled)"
echo "   • Example: docker run -d --network=none nginx"
echo "   • Example: docker run --rm --network=none alpine echo 'hello'"
echo ""
echo "🔄 For new terminal sessions, run: newgrp docker"
EOF

echo ""
echo "🎉 Setup complete! Docker should now be working."
echo "   If you're in a new terminal, run: newgrp docker"

I have not been able to get a good solution that automatically runs this at the start.

2 Likes

Bumping this as I’d love to hear an official communication about this - the official docs either would need to be updated, or the feature needs fixing so it works as intended.

5 Likes

Hey cursor team, any updates or suggestions on this? Is there any additional information you would need to debug?

2 Likes

Hey team, any updates on this? The recent features (plan mode, PR summaries, browser automation) are fantastic, but a fully functional background agent mode would really unlock their full potential.

4 Likes

I’m very grateful for @error-404 ‘s script and the other suggestions here . I was able to get my agent setup mostly working based on that.

For anyone else trying to get Docker running with the agent, here’s the process that worked for me.

Step 1: Install Docker

First, I install Docker using the convenience script and add my user to the `docker` group:

curl -fsSL \[https://get.docker.com\](https://get.docker.com) -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
rm get-docker.sh

Step 2: Configure the Docker Daemon

This was the most critical part. Docker needs a specific daemon configuration to work inside the agent environment.

  1. Create .cursor/daemon.json

    I created a daemon.json file in my .cursor directory with the following content:

{
    "iptables": false,
    "bridge": null
}
  1. install

    I wrote a simple install script to copy this config to the right place and start the Docker service.

#!/bin.bash
sudo cp .cursor/daemon.json /etc/docker/daemon.json

sudo service docker start

(Inside this script, I can now run sudo docker ... commands successfully. newgrp was unreliable here.)

  1. Update environment.json

    Finally, I pointed the agent’s install step to this script:

{
    ...
    "snapshot": "redacted",
    "install": ".cursor/install.sh"
    ...
}

Writing the config to /etc/docker/daemon.json was the key. After this, once I’m on the background agent, I just need to run newgrp docker and things work mostly fine.

Important: Network Configuration

I found that all Docker RUN commands needing network access (like `apt install`, `pip install`, etc.) during a build require the host’s network.

  • docker build: Must use docker build --network=host ...

  • docker run/exec: Must use docker run --network=host ...

  • compose.yaml: Use network_mode: host under the service’s key, and network: host under the build key

Remaining Issues

I’m still running into a couple of problems:

  • The agent snapshot doesn’t seem to update after the install step runs.
  • Terminals configured in .cursor/environment.json don’t appear to start (tmux ls shows nothing)
  • Sometimes docker is already running when the install script runs, so sudo service docker start appears to fail. sudo service docker start || true sometimes works. sudo service docker stop/restart fail as they hang indefinitely.

Despite these, I have an agent that works much more closely to my local dev setup now. Hopefully this helps someone out, and that the Cursor team will keep iterating and improving this

9 Likes

I’m new to Cursor and trying to get this to work, but not sure how to pull all this together. Where do the scripts go? Can I build this into a dedicated Docker image? Happy to put in the effort on my end!