Blog / Tutorials / How to Self-Host OpenHands on a VPS: AI Coding Agent Setup
(last updated: )

How to Self-Host OpenHands on a VPS: AI Coding Agent Setup

OpenHands is an open-source AI coding agent that edits code and runs shell commands in a workspace you control. To self-host it on a VPS, you run its Docker image, connect an LLM through a provider API key or a local OpenAI-compatible endpoint, and put…

11 min read

OpenHands is an open-source AI coding agent that edits code and runs shell commands in a workspace you control. To self-host it on a VPS, you run its Docker image, connect an LLM through a provider API key or a local OpenAI-compatible endpoint, and put HTTPS and an API key in front of the web UI. Treat the server as disposable, because the agent can run anything you could run.

What Is OpenHands and What Can It Do?

OpenHands is an open-source software-development agent: you describe a task in plain language, and it plans the work, edits files and runs commands until the task is done or it gets stuck.

The project started as OpenDevin, an homage to Devin by Cognition, and was renamed when its early contributors formed All Hands AI, the company built to carry the mission on. The code is on GitHub and MIT-licensed.

The self-hosted product is now called Agent Canvas: a web frontend plus an Agent Server backend that runs conversations and tools in a workspace. It runs the OpenHands agent out of the box and can also drive agents such as Claude Code or Codex. The older single-container GUI (image docker.openhands.dev/openhands/openhands, port 3000) is marked deprecated, but many tutorials still describe it, so check the date on anything you follow.

It does its best work on well-scoped tasks with a way to check the result: fix an issue, bump a dependency, write tests. It struggles when the model behind it is weak. The docs state that it “requires a powerful model to work” and that open-weight and local models vary widely in tool-use reliability. Typical symptoms are long waits, poor answers and malformed JSON errors.

OpenHands Requirements: VPS, Docker and LLM Access

The server requirements are modest, because the LLM does the heavy lifting. The table lists what the docs state and says where they are silent.

RequirementWhat the docs sayPractical note
Operating systemUbuntu 24.04 LTS is the reference in the VM guideThe safest choice on a fresh VPS.
CPU and RAM“2 vCPU and 4 GB RAM is enough for a single user” (VM guide, npm install)Parallel sessions need more. Watch docker stats.
DockerDocker with the daemon runningInstall Docker Engine before anything else.
Node.js and uvNode.js 24 or later and uv, for the npm and npx routes onlyNot needed with the Docker image.
DiskNo figure in the docsBudget for the image, the data volume and your repositories.
LLM accessA provider API key, or a local OpenAI-compatible server (Ollama, LM Studio, vLLM, SGLang)Local models need a context window of at least 22,000 tokens.
NetworkUI on port 8000 at /canvas; the Docker quickstart publishes it on 127.0.0.1 onlyKeep it on loopback and add a reverse proxy.

Install OpenHands with Docker on a VPS

Start with a fresh Ubuntu VPS and SSH key login. If Docker is missing, follow our guide to installing Docker on Ubuntu first. Then generate an API key for the UI and start the container:

mkdir -p ~/projects
export LOCAL_BACKEND_API_KEY=”$(openssl rand -hex 32)”
echo “$LOCAL_BACKEND_API_KEY”   # store it in your password manager

docker run -d –name agent-canvas –restart unless-stopped \
  -p 127.0.0.1:8000:8000 \
  -e LOCAL_BACKEND_API_KEY \
  -v openhands-data:/home/openhands/.openhands \
  -v ~/projects:/projects \
  –add-host host.docker.internal:host-gateway \
  ghcr.io/openhands/agent-canvas:latest

This adapts the official quickstart for a server: -d and –restart keep the agent running, you set the key yourself, the port stays on loopback, and the named volume holds settings, secrets and history. The –add-host line only matters for the local-model path below.

We left out AGENT_CANVAS_ALLOW_LAN_SESSION_KEY on purpose: the docs warn that with it on, anyone who can reach the frontend can obtain a session key. The :latest tag moves, so once everything works, pin a release tag from the GitHub releases page.

To test without exposing anything, tunnel the port over SSH, then open http://localhost:8000/canvas and enter the key:

ssh -L 8000:127.0.0.1:8000 you@your-server

For permanent access, terminate TLS at a reverse proxy on the host. The UI streams updates, so the proxy needs WebSocket headers and long timeouts:

sudo apt-get install -y nginx certbot python3-certbot-nginx

# /etc/nginx/sites-available/agent
server {
    server_name agent.example.com;
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection “upgrade”;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

sudo ln -s /etc/nginx/sites-available/agent /etc/nginx/sites-enabled/agent
sudo nginx -t && sudo systemctl reload nginx
sudo certbot –nginx -d agent.example.com –redirect

A word on docker.sock. Older tutorials mount /var/run/docker.sock into the container. Whoever controls that socket controls the host’s Docker daemon, which in practice means root on the host. The current Docker instructions do not mount it. If the agent must run Docker itself, they say to add –privileged instead, which gives the container broad access to the host kernel and weakens isolation. Skip both unless your tasks need containers, and then only on a throwaway server.

Connect OpenHands to a Cloud LLM or a Local Model

The model matters more than the server. Pick a path, then verify it before handing over real work.

  1. Open Settings > LLM in the UI. Direct provider keys go in the Basic tab; local servers and LiteLLM proxies go in Advanced.
  2. Cloud path: choose a provider and model, then paste the API key. Use the strongest model you can afford and set a spending limit on the key.
  3. Local path, step one: run an OpenAI-compatible server on the VPS. For OpenHands with Ollama, the docs set OLLAMA_CONTEXT_LENGTH=32768 and OLLAMA_HOST=0.0.0.0:11434; the default 4,096 context is too small. For vLLM, serve the model with an API key.
  4. Local path, step two: in Advanced, set Custom Model to openai/ plus the served model ID, for example openai/qwen3.6:35b-a3b for Ollama. Set Base URL to http://host.docker.internal:11434/v1. Inside the container, 127.0.0.1 points at the container, not the host.
  5. Mind the ports. The docs’ vLLM example uses port 8000, which collides with Agent Canvas here, so serve vLLM on 8001 and use that in the Base URL. Keep the model port closed to the internet.
  6. Start a new conversation and send a short message. If it answers, the connection works.

Be realistic about a local LLM setup. A coding agent sends long contexts and depends on reliable tool calls, and small models fall over there: stalled steps, loops, broken JSON. The docs suggest Qwen3.6-35B-A3B as the first local model to try, with a GPU of at least 24 GB of VRAM for quantized variants, and warn that local LLMs can have limited functionality. A model that fits in a few gigabytes is fine for experiments, not for work you care about. For the GPU path, see our guides to running gpt-oss-120b on a GPU VPS, or our introduction to Ollama for the simpler route.

Run Your First OpenHands Task: Fix an Issue in a Repository

Keep the first run boring: one repository, one small bug, existing tests.

  • Clone the repository into ~/projects on the VPS, which the container sees as /projects. Use a deploy key or a fine-grained token limited to that single repository.
  • Open the UI and finish the first-time wizard: keep OpenHands as the agent, confirm the backend is connected, and set your LLM.
  • Start a conversation and write the prompt like a good issue: the symptom, the expected behaviour, the file or module, and the command that runs the tests.
  • Watch the first steps. If it loops or reports malformed JSON, switch to a stronger model rather than rewording the prompt.
  • Review the result with git status and git diff, and run the tests yourself.
  • Commit on a branch, push, and open the pull request with your normal Git host so CI and a human reviewer see it before anything merges.

This walkthrough uses plain Git on purpose: pushing the branch yourself keeps your Git credentials out of the agent’s reach.

Secure Your Self-Hosted AI Coding Agent

Agent Canvas protects the backend with one shared API key, LOCAL_BACKEND_API_KEY. That is a gate, not a user system: per-user accounts and SAML SSO appear only under OpenHands Enterprise in the docs. The docs also say the agent server can read and write the host filesystem, run shell commands and reach the network, so harden the VPS:

  • Isolate the box. Use a dedicated VPS with nothing else on it and no production credentials or cloud tokens.
  • Keep port 8000 on 127.0.0.1 and put HTTPS in front with a reverse proxy; the Nginx Proxy Manager how-to covers the container route. Use a long random key, and rotate it if it leaks.
  • Lock the firewall: allow SSH only from your IP or VPN, open 80 and 443 only when a proxy is running, and keep 8000 and your model port closed. Our UFW basics show how to configure UFW.
  • Scope Git access: one repository per token or deploy key, no admin rights, and protected branches.
  • Do not add –privileged or mount docker.sock unless a task needs them.
  • Cap spending on the LLM key and keep it separate from your other projects. The settings volume stores secrets.
  • Review every diff before it merges, and work through the VPS security checklist for SSH, updates and monitoring.

Which VPS Size Does OpenHands Need?

Most of the cost sits in the model, not the app. The table is guidance; only figures marked Docs are official. For larger models, see how much VRAM an LLM needs.

SetupWhere the model runsSizing guidanceProduct line
Hosted API model, one userProvider’s serversDocs: 2 vCPU and 4 GB RAM is enough for one user. Guidance: start at 8 GB for headroom.Cloud VPS with 8 GB of RAM or more
Several parallel sessionsProvider’s serversGuidance: add vCPU and RAM per session; measure first.Cloud VPS with more RAM, or a VDS for steady CPU
Local model on CPUOn the VPS, no GPUGuidance: not recommended; the docs advise a GPU-backed server.Experiments only
Local model on a GPUOn the VPS, GPUDocs: at least 24 GB of VRAM for quantized variants of the suggested 35B-class model.GPU VPS (96 GB of VRAM)

Why Run OpenHands on a Contabo VPS

A coding agent is most useful when it can work for an hour while your laptop is closed. A VPS gives you an always-on box at a fixed monthly server price and keeps repositories, keys and shell access off your own machine. The LLM bill stays variable, so cap it. On the Contabo Cloud VPS line, RAM per Euro is the selling point: a plan with 8 GB of RAM or more leaves room for the app, its sandboxes and a few parallel sessions.

For fully local inference, the Contabo GPU VPS has one dedicated NVIDIA RTX PRO 6000 Blackwell Server Edition with 96 GB of GDDR7 VRAM, 18 vCPU, 96 GB of RAM and 900 GB of NVMe. Per Contabo’s launch post it costs €999 per month excluding VAT. 96 GB is four times the 24 GB the OpenHands docs cite for quantized variants of their suggested local model. Details are in the GPU VPS launch post; check the live product pages for current plans and prices.

FAQ: Self-Hosting OpenHands

What is OpenHands, the open-source agent from All Hands AI?

OpenHands is an open-source AI software-development agent that edits code and runs commands in a workspace. It began as OpenDevin and is backed by All Hands AI. You can self-host it with Docker through Agent Canvas, or use the company’s hosted Cloud offering.

Can OpenHands run with a local LLM?

Yes. Point it at any OpenAI-compatible server, such as Ollama, LM Studio, vLLM or SGLang, using Custom Model openai/<model-id> and a host.docker.internal Base URL. The docs warn that local models vary in tool-use reliability and need a context window of at least 22,000 tokens.

Is it safe to self-host an AI coding agent?

It can be reasonably safe if you contain it, but never risk-free. Use a dedicated VPS, no production credentials, scoped Git tokens, HTTPS with an API key, a tight firewall and no docker.sock mount, and review every diff.

How much RAM does OpenHands need?

The docs say 2 vCPU and 4 GB of RAM is enough for a single user on Ubuntu 24.04. Parallel sessions and sandboxes need more, and a local model needs its own VRAM on top, so size up and measure with docker stats.

Is OpenHands free?

The software is open source under the MIT licence, so it costs nothing to run. You still pay for the server and for LLM usage, which can add up during long agent runs, so set spending limits. OpenHands Cloud is a separate commercial offering.

Disclaimer: Product specifications, features, and prices mentioned in this article are subject to change and may vary by region, billing term, and active promotions. Please check each provider’s or brand’s official website for current figures, pricing, and local currency rates.