OpenHands — the AI agent that codes in the terminal on your behalf
OpenHands is built on a simple architecture: a web server that orchestrates one or more LLM agents, each running inside an ephemeral Docker sandbox. The agent has a shell, filesystem access to the project, a GitHub API connection, and a reasoning loop that alternates between reading code, planning, and executing.
The SWE-bench Verified benchmark measures an agent's ability to resolve real GitHub issues without human assistance. In April 2025, OpenHands paired with Claude Sonnet reached 60.6% on this benchmark in a single trajectory, and 66.4% with five attempts and a critic model. For reference, an experienced junior developer resolves roughly 15 to 20% of these issues — today's agents significantly outperform humans on well-documented tasks.
OpenHands is distributed under the MIT license: you can host it, modify it, and integrate it into your internal tools with no commercial restrictions. The project is actively maintained — v1.23.0 was released on September 23, 2026, featuring remote MCP server support and Git Sync for organization admins.
What OpenHands can do on its own
- Fix a documented bug: the agent reads the GitHub issue, locates the faulty code, writes the fix, runs existing tests, and opens a PR with an explanatory commit message.
- Add a test suite: starting from an uncovered module, the agent generates unit or integration tests aligned with the existing framework (pytest, PHPUnit, Jest…).
- Refactor code: extract a function, rename variables to follow conventions, move a module toward a cleaner architecture.
- Complete documentation: generate or update docstrings, README files, and API usage examples from the source code.
- Analyze an unfamiliar repository: produce a structure report, identify critical dependencies, map data flows between modules.
- Open and describe a pull request: generate the title, the PR body explaining changes, passing tests, and review instructions for the team.
Numbered prerequisites before installation
OpenHands is a lightweight orchestrator, but it spawns sandbox containers per task. Requirements vary based on the chosen LLM backend.
Minimum hardware (cloud API — Claude, GPT-4, Gemini):
- RAM: 4 GB minimum, 8 GB recommended for concurrent tasks
- CPU: 2 vCPU minimum, 4 vCPU for a smooth experience
- Storage: 20 GB free (Docker images + project workspaces)
- OS: Linux with Docker 24+ (Ubuntu 22.04 LTS or Debian 12 recommended)
Hardware if paired with local Ollama LLM:
- RAM: 16 GB minimum (8 GB for a quantized 7B model + 4 GB for the OS + headroom)
- GPU VRAM: optional but strongly recommended — without GPU, inference is 10–30× slower
- Storage: 40 GB free (Ollama models + Docker)
Software versions:
- Docker Engine 24.0 or later (check with docker --version)
- Docker Compose v2 (bundled with Docker Desktop and Docker Engine 24+)
- Linux kernel 5.4+ (required for sandbox isolation namespaces)
Port 3000 must be reachable from your browser or VPN. Never expose it directly to the internet — use an Nginx reverse proxy with HTTPS.
Install OpenHands on a VPS in 8 steps
Install Docker Engine on your VPS
On Ubuntu 22.04 or Debian 12, install Docker with the official script:
curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER newgrp dockerVerify the installation:
docker --version # Docker version 27.x.x docker compose version # Docker Compose version v2.x.xCreate the working directory
Create a dedicated folder for OpenHands and its persistent data:
mkdir -p /opt/openhands/.openhands cd /opt/openhandsThe
.openhandsfolder stores persistent configuration: API keys, conversation history, agent settings.Launch OpenHands with Docker
Start OpenHands with the official command:
docker run -it --rm --pull=always \ -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:latest \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /opt/openhands/.openhands:/.openhands \ -p 127.0.0.1:3000:3000 \ --add-host host.docker.internal:host-gateway \ --name openhands-app \ docker.all-hands.dev/all-hands-ai/openhands:latestThe
--pull=alwaysflag ensures you run the latest stable image. OpenHands is available athttp://localhost:3000.For a permanent deployment (auto-restart), add
--restart unless-stoppedand remove-it --rm.Alternative: deploy with Docker Compose
For simpler management, create a
compose.ymlfile in/opt/openhands:services: openhands: image: docker.all-hands.dev/all-hands-ai/openhands:latest container_name: openhands-app pull_policy: always ports: - "127.0.0.1:3000:3000" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./.openhands:/.openhands extra_hosts: - host.docker.internal:host-gateway restart: unless-stoppedStart the stack:
docker compose up -d docker compose logs -fConfigure the LLM backend in the UI
Open
http://localhost:3000(or your HTTPS domain). On first launch, OpenHands asks for:1. LLM provider: choose
Anthropic,OpenAI,Google, oropenai-compatiblefor Ollama
2. Model:claude-sonnet-4-5(best quality/cost ratio) orclaude-opus-4-5for complex tasks
3. API key: paste your Anthropic or OpenAI keyThese settings are saved to
~/.openhands/config.tomland persist across restarts.Connect OpenHands to GitHub
To let OpenHands clone private repos, read issues, and open PRs, configure a GitHub Personal Access Token:
1. On GitHub: Settings → Developer settings → Personal access tokens → Fine-grained tokens
2. Grant permissions:Contents(read/write),Pull requests(read/write),Issues(read)
3. In the OpenHands UI: Settings → Git → paste the tokenWith this token, simply paste a GitHub issue URL into the task field and OpenHands takes over.
Set up the Nginx reverse proxy with HTTPS
Never expose port 3000 directly. Use Nginx as a reverse proxy:
server { listen 443 ssl; server_name openhands.your-domain.com; ssl_certificate /etc/letsencrypt/live/openhands.your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/openhands.your-domain.com/privkey.pem; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; proxy_read_timeout 600s; } }Obtain the certificate:
certbot --nginx -d openhands.your-domain.comTest with a first task
Open the interface, paste a GitHub issue URL (e.g.
https://github.com/your-org/your-repo/issues/42) into the task field, and click Start.OpenHands will:
1. Read the issue and plan the approach
2. Clone the repository into the sandbox
3. Explore the code, write changes
4. Run the tests (pytest,npm test, etc.)
5. Display a summary and offer to open a PRFollow the execution in real time in the Trajectory tab — every agent action (file read, shell command, code write) is traced.
Configure the AI backend: Claude, GPT-4, or Ollama
OpenHands supports any provider compatible with the OpenAI API, plus native Anthropic, Google, and Azure providers. The model choice is the single biggest factor determining output quality.
Claude Sonnet (Anthropic) — recommended for production
Claude claude-sonnet-4-5 offers a leading quality/cost ratio for agentic software engineering. Its 200,000-token context window lets it analyze large codebases without chunking. Expect a few cents per task depending on complexity. Set LLM_MODEL=anthropic/claude-sonnet-4-5.
Claude Opus (Anthropic) — for complex tasks
claude-opus-4-5 delivers better performance on architectural problems and large-scale refactors, but costs 5–10× more than Sonnet. Reserve it for tasks that exceed Sonnet's capabilities.
Ollama (local LLM) — for full sovereignty
If your code is particularly sensitive or you want zero external dependency, pair OpenHands with Ollama on the same VPS. Set LLM_BASE_URL=http://host.docker.internal:11434 and LLM_MODEL=openai/qwen2.5-coder:32b. The qwen2.5-coder 32B models deliver top open-weights results on coding benchmarks. Downside: CPU inference is 10–30× slower than an API call — expect 1 to 5 minutes per subtask.
Key environment variables:
LLM_MODEL=anthropic/claude-sonnet-4-5
LLM_API_KEY=sk-ant-...
LLM_BASE_URL= # empty for Anthropic, Ollama URL for local
AGENT=CodeActAgent # default agent, best SWE-bench performerSecuring docker.sock — socket proxy and rootless mode. Mounting /var/run/docker.sock inside a container is equivalent to granting full root access to the host machine: any container with access to this socket can create new containers, mount arbitrary volumes, and escalate privileges.
Two approaches to reduce this attack surface:
Option 1 — Socket proxy (Tecnativa/docker-socket-proxy): interpose a proxy that filters Docker API calls. OpenHands only needs POST /containers/create, GET /containers/{id}/json, POST /containers/{id}/start and DELETE /containers/{id}. The socket proxy blocks everything else.
services:
socket-proxy:
image: tecnativa/docker-socket-proxy
environment:
CONTAINERS: 1
POST: 1
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
openhands:
image: docker.all-hands.dev/all-hands-ai/openhands:latest
environment:
- DOCKER_HOST=tcp://socket-proxy:2375
depends_on:
- socket-proxy
restart: unless-stoppedOption 2 — Rootless Docker: run Docker in rootless mode (your system user, not root). The socket is then at /run/user/1000/docker.sock and belongs to your user. Compromising this socket does not escalate beyond that user's privileges. Enable it with dockerd-rootless-setuptool.sh install.
Concrete use cases
Use case 1 — Resolve a documented GitHub issue
Paste the URL of a well-described issue (expected behavior, observed behavior, stack trace if available) into OpenHands. The agent reads the issue, searches the relevant files with grep and the code explorer, writes the fix, runs the test suite, and proposes a PR. For isolated, well-documented bugs, the success rate is high without human intervention.
Use case 2 — Generate tests for an uncovered module
Specify the target: Write unit tests for the module src/payments/stripe.py, aiming for 80% coverage with pytest. Mocks should use unittest.mock. The agent analyzes the module, identifies edge cases, and generates a test suite consistent with existing patterns in the project.
Use case 3 — Analyze an open source repository before forking
Before integrating a dependency or forking a project, ask OpenHands: Analyze the repository https://github.com/org/repo. Identify critical dependencies, tight coupling points, missing tests, and known CVEs in direct dependencies. The agent produces a structured report in a few minutes.
Use case 4 — Update a major dependency
Major version migrations (Django 4 → 5, React 18 → 19, Laravel 10 → 11) touch many files. OpenHands can read the official changelog, identify breaking changes, apply mechanical updates, and rerun tests to identify what still needs manual attention.
Troubleshooting — common errors
permission denied while trying to connect to the Docker daemon socket
The user running OpenHands is not in the docker group. Fix with:
sudo usermod -aG docker $USER && newgrp dockerIf mounting the socket inside a container, verify that the socket's GID matches what OpenHands expects.
Container exited with OOM kill (exit code 137)
The sandbox ran out of memory. Increase available RAM on the VPS or limit concurrent tasks. Add --memory=4g to the sandbox container in the OpenHands configuration.
LLM timeout after 120s
On large codebases, the agent sends large contexts to the LLM. Two solutions: (a) increase LLM_TIMEOUT in the configuration, (b) switch to a model with a larger context window or reduce the task scope.
No such container: openhands-sandbox-xxx
The sandbox container was removed between two actions. This happens when Docker is restarted during a task. Restart the task from the beginning — OpenHands does not resume tasks interrupted by a Docker restart.
Rate limit exceeded (Anthropic/OpenAI)
OpenHands makes many LLM calls on complex tasks. If you hit rate limits, add LLM_NUM_RETRIES=5 and LLM_RETRY_MIN_WAIT=30 to the configuration to let OpenHands retry automatically.
OpenHands vs Codex cloud vs Devin
Scroll the table
| Criterion | OpenHands self-hosted | GitHub Copilot Workspace | Devin (Cognition) |
|---|---|---|---|
| Monthly cost | $0 (+ LLM API cost) | $19/month (Copilot Pro) | $500/month (Team plan) |
| Code sent externally | No (code stays on VPS) | Yes (GitHub/Microsoft) | Yes (Cognition) |
| Configurable LLM backend | Yes (Claude, GPT, Ollama…) | No (Microsoft model) | No (Cognition model) |
| SWE-bench Verified score | 66.4% (5 attempts, Claude) | Not published | ~49% (last publication) |
| License | MIT (open source) | Proprietary | Proprietary (SaaS) |
| VPS required | Yes (4 GB RAM min) | No | No |
| Full autonomy (auto PR) | Yes | Partial | Yes |