From a735166c08e1dc96b153bf182bf929507b73be89 Mon Sep 17 00:00:00 2001 From: Leopere Date: Thu, 12 Feb 2026 13:31:46 -0500 Subject: [PATCH] Initial commit: Clawtainer - Browser-accessible Linux desktop with AI tools Features: - KasmVNC-based desktop environment (Debian Bookworm) - Pre-installed AI coding tools: OpenClaw, Cursor, Antigravity, VS Code - Anthropic Python SDK for Claude API access - OpenClaw gateway auto-starts on port 18789 - Nginx proxy for plain HTTP access (no password, no TLS) - LAN accessible by default - Desktop shortcuts for all tools License: CC Attribution 4.0 - https://colinknapp.com Co-authored-by: Cursor --- .gitignore | 9 +++++ Dockerfile | 86 ++++++++++++++++++++++++++++++++++++++++++++++ LICENSE | 18 ++++++++++ README.md | 76 ++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 30 ++++++++++++++++ nginx.conf | 35 +++++++++++++++++++ 6 files changed, 254 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 nginx.conf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..921e751 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Environment +.env +.env.local + +# Docker volumes +volumes/ + +# Logs +*.log diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7da1682 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,86 @@ +# Kasm workspace with OpenClaw pre-installed +# Gateway runs on port 18789; expose in Kasm Workspace config +FROM kasmweb/debian-bookworm-desktop:1.18.0-rolling-daily + +USER root +ENV HOME=/home/kasm-default-profile +ENV STARTUPDIR=/dockerstartup +ENV INST_SCRIPTS=$STARTUPDIR/install +ENV KASM_SVC_NO_SSL=1 +WORKDIR $HOME + +######### Customize Container Here ########### +# Node 22 (OpenClaw requirement) +RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ + && apt-get install -y nodejs \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# OpenClaw (global install, no interactive prompts) +RUN npm install -g openclaw@latest + +# Pre-create OpenClaw directories with correct ownership (1000:1000 = kasm-user) +RUN mkdir -p $HOME/.openclaw/canvas $HOME/.openclaw/cron $HOME/.openclaw/workspace \ + && chown -R 1000:1000 $HOME/.openclaw + +# Anthropic Python SDK (Claude API) +RUN apt-get update && apt-get install -y python3-pip \ + && pip3 install --break-system-packages anthropic \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Google Antigravity (apt repo) +RUN mkdir -p /etc/apt/keyrings \ + && curl -fsSL https://us-central1-apt.pkg.dev/doc/repo-signing-key.gpg | gpg --dearmor --yes -o /etc/apt/keyrings/antigravity-repo-key.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/antigravity-repo-key.gpg] https://us-central1-apt.pkg.dev/projects/antigravity-auto-updater-dev/ antigravity-debian main" > /etc/apt/sources.list.d/antigravity.list \ + && apt-get update && apt-get install -y antigravity \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Cursor IDE (deb by arch) +RUN ARCH=$(dpkg --print-architecture) \ + && if [ "$ARCH" = "arm64" ]; then CURSOR_URL="https://api2.cursor.sh/updates/download/golden/linux-arm64-deb/cursor/2.4"; else CURSOR_URL="https://api2.cursor.sh/updates/download/golden/linux-x64-deb/cursor/2.4"; fi \ + && curl -fsSL -L -o /tmp/cursor.deb "$CURSOR_URL" \ + && apt-get update && dpkg -i /tmp/cursor.deb || apt-get install -f -y \ + && rm -f /tmp/cursor.deb \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Launcher scripts so desktop can find code/cursor (PATH often minimal when launched from GUI) +RUN echo '#!/bin/sh\nexec /usr/bin/env PATH=/usr/bin:/usr/local/bin:"$PATH" code --no-sandbox "$@"' > /usr/local/bin/launch-vscode \ + && chmod +x /usr/local/bin/launch-vscode \ + && echo '#!/bin/sh\nexec /usr/bin/env PATH=/usr/bin:/usr/local/bin:"$PATH" cursor --no-sandbox "$@"' > /usr/local/bin/launch-cursor \ + && chmod +x /usr/local/bin/launch-cursor + +# Create desktop shortcuts (proper newlines; use launchers for code/cursor) +RUN mkdir -p $HOME/Desktop \ + && printf '%s\n' '[Desktop Entry]' 'Version=1.0' 'Type=Link' 'Name=OpenClaw Control' \ + 'Comment=OpenClaw Gateway Control UI' 'Icon=applications-development' 'URL=http://localhost:18789' \ + > $HOME/Desktop/openclaw-gateway.desktop \ + && printf '%s\n' '[Desktop Entry]' 'Version=1.0' 'Type=Application' 'Name=VS Code' \ + 'Comment=Visual Studio Code Editor' 'Exec=/usr/local/bin/launch-vscode' 'Icon=code' \ + 'Terminal=false' 'Categories=Development;IDE;' \ + > $HOME/Desktop/vscode.desktop \ + && printf '%s\n' '[Desktop Entry]' 'Version=1.0' 'Type=Application' 'Name=Cursor' \ + 'Comment=Cursor AI IDE' 'Exec=/usr/local/bin/launch-cursor' 'Icon=cursor' \ + 'Terminal=false' 'Categories=Development;IDE;' \ + > $HOME/Desktop/cursor.desktop \ + && printf '%s\n' '[Desktop Entry]' 'Version=1.0' 'Type=Application' 'Name=Antigravity' \ + 'Comment=Google Antigravity AI IDE' 'Exec=/usr/bin/antigravity' 'Icon=antigravity' \ + 'Terminal=false' 'Categories=Development;IDE;' \ + > $HOME/Desktop/antigravity.desktop \ + && chmod +x $HOME/Desktop/*.desktop \ + && chown -R 1000:1000 $HOME/Desktop + +# Disable authentication but keep HTTPS +RUN sed -i 's/vncserver/vncserver -SecurityTypes None -DisableBasicAuth 1/g' /dockerstartup/vnc_startup.sh \ + && sed -i 's/kasm_password_file:.*$/kasm_password_file:/g' /usr/share/kasmvnc/kasmvnc_defaults.yaml + +# Auto-start gateway when session starts (--bind lan for browser access) +RUN echo '#!/bin/bash' > $STARTUPDIR/custom_startup.sh \ + && echo '/usr/bin/desktop_ready && openclaw gateway --bind lan --allow-unconfigured &' >> $STARTUPDIR/custom_startup.sh \ + && chmod +x $STARTUPDIR/custom_startup.sh +######### End Customizations ########### + +RUN chown 1000:0 $HOME +RUN $STARTUPDIR/set_user_permission.sh $HOME +ENV HOME /home/kasm-user +WORKDIR $HOME +RUN mkdir -p $HOME && chown -R 1000:0 $HOME +USER 1000 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f5ece80 --- /dev/null +++ b/LICENSE @@ -0,0 +1,18 @@ +Creative Commons Attribution 4.0 International (CC BY 4.0) + +Copyright (c) 2026 Colin Knapp +https://colinknapp.com + +You are free to: +- Share — copy and redistribute the material in any medium or format +- Adapt — remix, transform, and build upon the material for any purpose, even commercially + +Under the following terms: +- Attribution — You must give appropriate credit, provide a link to https://colinknapp.com, + and indicate if changes were made. You may do so in any reasonable manner, but not in any + way that suggests the licensor endorses you or your use. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Full license text: https://creativecommons.org/licenses/by/4.0/legalcode diff --git a/README.md b/README.md new file mode 100644 index 0000000..6718856 --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +# Clawtainer + +Browser-accessible Linux desktop with AI coding tools pre-installed: OpenClaw, VS Code, Cursor, Antigravity, and Anthropic Python SDK. + +## Quick Start + +```bash +git clone git@git.nixc.us:colin/clawtainer.git +cd clawtainer +docker compose up -d +``` + +Access from any device on your LAN: +- **Desktop (VNC)**: `http://YOUR_IP:6901` (no password) +- **OpenClaw Gateway**: `http://YOUR_IP:18789` + +## Run (Docker Compose) + +```bash +docker compose up -d +``` + +- **Desktop**: **http://localhost:6901** (no password required) +- **OpenClaw Control UI**: http://localhost:18789 (token: `clawtainer`) + +The nginx proxy strips TLS from the VNC connection for easy browser access. + +Set OpenClaw token: `OPENCLAW_GATEWAY_TOKEN=mytoken docker compose up -d` + +## Build (standalone) + +```bash +docker build -t clawtainer:local . +``` + +## Kasm Workspaces Setup + +1. Register a new Workspace in Kasm Admin +2. Set **Docker Image** to `clawtainer:local` (or your tagged name) +3. Add port **18789** to the workspace's port configuration +4. Save and launch a session + +## Usage + +After startup, open the desktop at port 6901. Desktop shortcuts are available: +- **OpenClaw Control** - Opens the gateway UI at `http://localhost:18789` +- **VS Code** - Launches Visual Studio Code + +You can also access the Control UI in the in-session browser. Run `openclaw onboard --non-interactive` from the terminal if needed, or paste your token in Settings. + +## What's Included + +**AI Coding Tools:** +- **OpenClaw** - Auto-starts gateway on port 18789 +- **Cursor IDE** - AI-powered code editor +- **Google Antigravity** - Google's AI IDE with Gemini +- **VS Code** - Microsoft Visual Studio Code +- **Anthropic Python SDK** - Claude API access (`pip install anthropic`) + +**Base:** +- Kasm Desktop: `kasmweb/debian-bookworm-desktop:1.18.0-rolling-daily` +- Node: 22 (from NodeSource) +- Python 3 with pip + +**Network:** +- Nginx proxy strips TLS for plain HTTP access +- No password authentication on VNC interface +- LAN accessible by default + +## License + +Creative Commons Attribution 4.0 International (CC BY 4.0) + +Copyright (c) 2026 Colin Knapp - https://colinknapp.com + +See LICENSE file for details. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..6cda35b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,30 @@ +services: + clawtainer: + build: . + image: clawtainer:local + container_name: clawtainer + shm_size: 512m + ports: + - "18789:18789" # OpenClaw gateway Control UI + environment: + OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-clawtainer} + restart: unless-stopped + networks: + - clawtainer-net + + nginx: + image: nginx:alpine + container_name: clawtainer-nginx + ports: + - "6901:80" # HTTP proxy to VNC (no TLS, no password) - LAN accessible + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf:ro + depends_on: + - clawtainer + restart: unless-stopped + networks: + - clawtainer-net + +networks: + clawtainer-net: + driver: bridge diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..070f5eb --- /dev/null +++ b/nginx.conf @@ -0,0 +1,35 @@ +events { + worker_connections 1024; +} + +http { + upstream vnc_backend { + server clawtainer:6901; + } + + server { + listen 80; + server_name _; + + # Increase timeouts for websocket connections + proxy_connect_timeout 7d; + proxy_send_timeout 7d; + proxy_read_timeout 7d; + + location / { + proxy_pass https://vnc_backend; + proxy_ssl_verify off; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # Standard proxy headers + 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 X-Forwarded-Proto $scheme; + } + } +}