diff --git a/openhands/data/docker/.gitkeep b/openhands/data/docker/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/openhands/data/docker/.gitkeep @@ -0,0 +1 @@ + diff --git a/openhands/data/openhands/.gitkeep b/openhands/data/openhands/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/openhands/data/openhands/.gitkeep @@ -0,0 +1 @@ + diff --git a/openhands/data/workspace/.gitkeep b/openhands/data/workspace/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/openhands/data/workspace/.gitkeep @@ -0,0 +1 @@ + diff --git a/openhands/docker-compose.yml b/openhands/docker-compose.yml new file mode 100644 index 00000000..cff12fa4 --- /dev/null +++ b/openhands/docker-compose.yml @@ -0,0 +1,51 @@ +version: '3.7' + +services: + app_proxy: + environment: + APP_HOST: openhands_web_1 + APP_PORT: 3000 + + docker: + image: docker:28.0.4-dind@sha256:ddb0033088b4fab74881ade341a582e3c6c8021b82377703ba1a6106bd3ded44 + privileged: true + network_mode: host + stop_grace_period: 1m + restart: on-failure + environment: + DOCKER_ENSURE_BRIDGE: "dind0:10.32.0.1/16" + entrypoint: /entrypoint.sh + command: > + dockerd + --bridge dind0 + --data-root /data/data + --exec-root /data/exec + --host unix:///data/docker.sock + --pidfile /data/docker.pid + volumes: + - ${APP_DATA_DIR}/entrypoint.sh:/entrypoint.sh + - ${APP_DATA_DIR}/data/docker:/data + + web: + image: ghcr.io/all-hands-ai/openhands:0.37.0@sha256:127135dd52b6da5c4e065c5294b499c2d0b9adcef993d674d71bbb55ffbfc27f + stdin_open: true + tty: true + pull_policy: always + healthcheck: + test: timeout 10s bash -c ':> /dev/tcp/127.0.0.1/3000' || exit 1 + interval: 10s + timeout: 5s + retries: 3 + start_period: 90s + environment: + - SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.37-nikolaik + - WORKSPACE_MOUNT_PATH=/opt/workspace_base + - LOG_ALL_EVENTS=true + volumes: + - ${APP_DATA_DIR}/data/docker:/var/run:rw + - ${APP_DATA_DIR}/data/openhands:/.openhands-state:rw + - ${APP_DATA_DIR}/data/workspace:/opt/workspace_base:rw + extra_hosts: + - host.docker.internal:host-gateway + - ${APP_DOMAIN}:host-gateway + restart: on-failure diff --git a/openhands/entrypoint.sh b/openhands/entrypoint.sh new file mode 100755 index 00000000..08740545 --- /dev/null +++ b/openhands/entrypoint.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +# This hack can be removed if https://github.com/docker-library/docker/pull/444 gets merged. + +# Remove docker pidfile if it exists to ensure Docker can start up after a bad shutdown +pidfile="/var/run/docker.pid" +if [[ -f "${pidfile}" ]] +then + rm -f "${pidfile}" +fi + +# Use nftables as the backend for iptables +for command in iptables iptables-restore iptables-restore-translate iptables-save iptables-translate +do + ln -sf /sbin/xtables-nft-multi /sbin/$command +done + +# Ensure that a bridge exists with the given name +ensure_bridge_exists() { + local name="${1}" + local ip_range="${2}" + + # Check if the bridge already exists + if ip link show "${name}" &>/dev/null + then + echo "Bridge '${name}' already exists. Skipping creation." + ip addr show "${name}" + return + fi + + echo "Bridge '${name}' does not exist. Creating..." + ip link add "${name}" type bridge + ip addr add "${ip_range}" dev "${name}" + ip link set "${name}" up + + echo "Bridge '${name}' is now up with IP range '${ip_range}'." + ip addr show "${name}" +} + +if [[ "${DOCKER_ENSURE_BRIDGE}" != "" ]] +then + bridge="${DOCKER_ENSURE_BRIDGE%%:*}" + ip_range="${DOCKER_ENSURE_BRIDGE#*:}" + ensure_bridge_exists "${bridge}" "${ip_range}" +fi + +exec dockerd-entrypoint.sh $@ diff --git a/openhands/umbrel-app.yml b/openhands/umbrel-app.yml new file mode 100644 index 00000000..ff8fdf2f --- /dev/null +++ b/openhands/umbrel-app.yml @@ -0,0 +1,35 @@ +manifestVersion: 1 +id: openhands +name: OpenHands +tagline: A local AI agent for writing and improving code +category: ai +version: "0.37.0" +port: 3993 +description: >- + 👐 OpenHands is a local-first AI development assistant that helps developers automate repetitive programming tasks and concentrate on more meaningful work. It runs entirely on your own Umbrel server and respects your privacy by keeping all operations offline and under your control. OpenHands understands, edits, and improves code independently by using intelligent software agents that analyze your repositories, execute commands, work with files, and follow instructions written in natural language. + + + By having full access to your local codebase and development tools, OpenHands becomes a powerful companion throughout your software projects. Whether you want to refactor existing code, fix bugs, or develop new features, the assistant can suggest and apply changes while always keeping you in the loop. Its modern web interface offers a smooth experience with an integrated code editor and terminal, all running directly on your own hardware without any external dependencies. + + + Bringing OpenHands to Umbrel gives developers a fully autonomous AI assistant that does not rely on cloud services. It is a great solution for privacy-focused individuals, hobby developers, and professionals who want to explore the future of software development with AI. + + + ⚠️ OpenHands needs to download an image when starting the first session, this takes some minutes. Please be patient. +developer: All Hands AI, Inc +website: https://www.all-hands.dev/ +submitter: dennysubke +submission: https://github.com/getumbrel/umbrel-apps/pull/2527 +repo: https://github.com/All-Hands-AI/OpenHands +support: https://github.com/All-Hands-AI/OpenHands/issues +gallery: + - 1.jpg + - 2.jpg + - 3.jpg + - 4.jpg + - 5.jpg +releaseNotes: "" +dependencies: [] +path: "" +defaultUsername: "" +defaultPassword: ""