From 6cfce64f996fe9ef474d4667fb1f787a3d45a59f Mon Sep 17 00:00:00 2001 From: HuaQiu6659 Date: Tue, 7 Apr 2026 03:32:28 +0000 Subject: [PATCH 1/4] feat: add docker deployment support --- .dockerignore | 18 ++++++++++++ DOCKER.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++ Dockerfile | 38 ++++++++++++++++++++++++ README.md | 22 ++++++++++++++ README_CN.md | 22 ++++++++++++++ docker-compose.yml | 22 ++++++++++++++ 6 files changed, 195 insertions(+) create mode 100644 .dockerignore create mode 100644 DOCKER.md create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cb76a9c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +.git +.github +node_modules/ +frontend/node_modules/ +__pycache__/ +*.pyc +*.pyo +*.pyd +.Python +env/ +venv/ +.venv/ +.env +.openspace/ +frontend/dist/ +showcase/ +gdpval_bench/ +assets/ diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000..5711398 --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,73 @@ +# Docker Deployment for OpenSpace + +This guide provides instructions on how to run OpenSpace in a Docker container. Containerization ensures a consistent environment, making it easy to run the dashboard and backend API without dealing with local Python and Node.js dependencies. + +## Prerequisites + +- [Docker](https://docs.docker.com/get-docker/) +- [Docker Compose](https://docs.docker.com/compose/install/) + +## Quick Start (Docker Compose) + +The easiest way to get OpenSpace running is using `docker-compose`. + +1. **Clone the repository:** + + ```bash + git clone https://github.com/HKUDS/OpenSpace.git + cd OpenSpace + ``` + +2. **Configure Environment Variables:** + + Create a `.env` file in the root directory and add your API keys: + + ```bash + cp .env.example .env + # Edit .env with your favorite editor and set your API keys: + # OPENSPACE_API_KEY=your_key + # OPENAI_API_KEY=your_key + # ANTHROPIC_API_KEY=your_key + ``` + +3. **Build and Run:** + + ```bash + docker-compose up -d --build + ``` + +4. **Access the Dashboard:** + + Open your browser and navigate to [http://localhost:7788](http://localhost:7788). The frontend and backend are both served seamlessly from the same container. + +## Interacting with the CLI + +You can use the container to execute OpenSpace CLI commands. + +**To run a single task using the CLI inside the running container:** + +```bash +docker exec -it openspace openspace --model "anthropic/claude-sonnet-4-5" --query "Analyze the local skills" +``` + +**To download/upload skills:** + +```bash +docker exec -it openspace openspace-download-skill +docker exec -it openspace openspace-upload-skill /app/skills/my-skill +``` + +## Volumes + +The `docker-compose.yml` is configured with two persistent volumes: + +- `openspace-data`: Mounted to `/app/.openspace`, storing the SQLite database (`openspace.db`) containing the skill evolution history and metadata. +- `openspace-skills`: Mounted to `/app/skills`, allowing you to persist downloaded and custom skills across container restarts. + +If you prefer to mount a local directory for your skills so you can edit them directly from your host machine, you can update the `docker-compose.yml` file: + +```yaml + volumes: + - openspace-data:/app/.openspace + - ./my-local-skills:/app/skills +``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..efc952d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +# Stage 1: Build the frontend +FROM node:20-slim AS frontend-builder +WORKDIR /app/frontend +COPY frontend/package.json frontend/package-lock.json* ./ +RUN npm install +COPY frontend/ ./ +RUN npm run build + +# Stage 2: Build the backend and serve +FROM python:3.12-slim +WORKDIR /app + +# Install system dependencies required for python packages and GUI features +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + python3-dev \ + libx11-dev \ + && rm -rf /var/lib/apt/lists/* + +# Copy backend source +COPY . /app/ + +# Install the Python package with linux optional dependencies +RUN pip install --no-cache-dir -e .[linux] + +# Copy built frontend from Stage 1 +COPY --from=frontend-builder /app/frontend/dist /app/frontend/dist + +# Expose the dashboard port +EXPOSE 7788 + +# Set environment variables +ENV HOST=0.0.0.0 +ENV PORT=7788 +ENV OPENSPACE_WORKSPACE=/app + +# Run the dashboard server by default +CMD ["openspace-dashboard", "--host", "0.0.0.0", "--port", "7788"] diff --git a/README.md b/README.md index 871298d..f27bbf2 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ On 50 professional tasks (**📈 [GDPVal Economic Benchmark](#-benchmark-gdpval) - [🤖 Path A: For Your Agent](#-path-a-for-your-agent) - [👤 Path B: As Your Co-Worker](#-path-b-as-your-co-worker) - [📊 Local Dashboard](#-local-dashboard) +- [🐳 Docker Deployment](#-docker-deployment) - [📈 Benchmark: GDPVal](#-benchmark-gdpval) - [📊 Showcase: My Daily Monitor](#-showcase-my-daily-monitor) - [🏗️ Framework](#️-framework) @@ -294,6 +295,27 @@ npm run dev --- +### 🐳 Docker Deployment + +To deploy OpenSpace without worrying about local Python and Node.js dependencies, you can use the official Docker image. We provide a `docker-compose.yml` for an easy, single-command setup. + +```bash +# Clone the repository +git clone https://github.com/HKUDS/OpenSpace.git +cd OpenSpace + +# Setup your API keys +cp .env.example .env +# Edit .env with your LLM API keys + +# Start the container +docker-compose up -d --build +``` + +The OpenSpace Dashboard is now available at [http://localhost:7788](http://localhost:7788). + +For detailed CLI and volume configurations, check out the [Docker Deployment Guide (DOCKER.md)](./DOCKER.md). + ## 📈 Benchmark: GDPVal We evaluate OpenSpace on [GDPVal](https://huggingface.co/datasets/openai/gdpval) — 220 real-world professional tasks spanning 44 occupations — using the [ClawWork](https://github.com/HKUDS/ClawWork) evaluation protocol with identical productivity tools and LLM-based scoring. Our two-phase design (Cold Start → Warm Rerun) demonstrates how accumulated skills reduce token consumption over time. diff --git a/README_CN.md b/README_CN.md index 09aee71..9a08945 100644 --- a/README_CN.md +++ b/README_CN.md @@ -135,6 +135,7 @@ Skill 能够自动学习并持续提升 - [🤖 路径 A:为你的 Agent 接入](#-路径-a为你的-agent-接入) - [👤 路径 B:作为你的 AI 协作者](#-路径-b作为你的-ai-协作者) - [📊 本地仪表盘](#-本地仪表盘) +- [🐳 Docker 容器化部署](#-docker-部署) - [📈 基准测试:GDPVal](#-基准测试gdpval) - [📊 案例展示:My Daily Monitor](#-案例展示my-daily-monitor) - [🏗️ 框架](#️-框架) @@ -294,6 +295,27 @@ npm run dev --- +### 🐳 Docker 容器化部署 + +为了避免配置本地 Python 和 Node.js 环境,你可以使用 Docker 容器化运行 OpenSpace。我们提供了一个 `docker-compose.yml` 用于一键部署。 + +```bash +# 克隆仓库 +git clone https://github.com/HKUDS/OpenSpace.git +cd OpenSpace + +# 配置环境变量 +cp .env.example .env +# 编辑 .env 文件,填入你的 API 密钥 + +# 启动容器 +docker-compose up -d --build +``` + +启动完成后,你可以通过浏览器访问 [http://localhost:7788](http://localhost:7788) 打开 OpenSpace Dashboard。 + +如果需要执行命令行操作或者配置数据卷持久化,请参阅详细的 [Docker 部署指南 (DOCKER.md)](./DOCKER.md)。 + ## 📈 基准测试:GDPVal 我们在 [GDPVal](https://huggingface.co/datasets/openai/gdpval) 上评估 OpenSpace——该数据集包含 220 项真实世界的专业任务,涵盖 44 个职业——采用 [ClawWork](https://github.com/HKUDS/ClawWork) 评测协议,使用相同的生产力工具和基于 LLM 的评分方式。我们的两阶段设计(Cold Start → Warm Rerun)展示了积累的 Skill 如何随时间降低 Token 消耗。 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..899919a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,22 @@ +version: '3.8' + +services: + openspace: + build: + context: . + dockerfile: Dockerfile + container_name: openspace + ports: + - "7788:7788" + volumes: + - openspace-data:/app/.openspace + - openspace-skills:/app/skills + environment: + - OPENSPACE_API_KEY=${OPENSPACE_API_KEY:-} + - OPENAI_API_KEY=${OPENAI_API_KEY:-} + - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} + restart: unless-stopped + +volumes: + openspace-data: + openspace-skills: From 56413592f8703d4f8430a1bbf7c68e72d1ca64ec Mon Sep 17 00:00:00 2001 From: HuaQiu6659 Date: Tue, 7 Apr 2026 03:43:07 +0000 Subject: [PATCH 2/4] fix(docker): add custom LLM provider env variables --- DOCKER.md | 5 +++++ docker-compose.yml | 3 +++ 2 files changed, 8 insertions(+) diff --git a/DOCKER.md b/DOCKER.md index 5711398..91d07c8 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -28,6 +28,11 @@ The easiest way to get OpenSpace running is using `docker-compose`. # OPENSPACE_API_KEY=your_key # OPENAI_API_KEY=your_key # ANTHROPIC_API_KEY=your_key + + # Optionally, configure custom LLM models/providers: + # OPENSPACE_MODEL=deepseek/deepseek-chat + # OPENSPACE_LLM_API_KEY=sk-xxxx + # OPENSPACE_LLM_API_BASE=https://api.deepseek.com/v1 ``` 3. **Build and Run:** diff --git a/docker-compose.yml b/docker-compose.yml index 899919a..b3c8df4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,6 +15,9 @@ services: - OPENSPACE_API_KEY=${OPENSPACE_API_KEY:-} - OPENAI_API_KEY=${OPENAI_API_KEY:-} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} + - OPENSPACE_MODEL=${OPENSPACE_MODEL:-} + - OPENSPACE_LLM_API_KEY=${OPENSPACE_LLM_API_KEY:-} + - OPENSPACE_LLM_API_BASE=${OPENSPACE_LLM_API_BASE:-} restart: unless-stopped volumes: From 166c578f3f3cbe1124d9d69cf00427d66fe33e05 Mon Sep 17 00:00:00 2001 From: Docker_Admin_v1 Date: Tue, 7 Apr 2026 10:42:31 +0000 Subject: [PATCH 3/4] feat(docker): major improvements to docker deployment New files: - .env.example - Comprehensive environment template - docker-compose.prod.yml - Production overrides - docker-compose.override.yml - Development overrides Key improvements: - docker-compose.yml: Configurable port, healthcheck, resource limits, log rotation - Dockerfile: Non-root user, security hardening, better caching - DOCKER.md: Complete rewrite with troubleshooting, backup/restore, monitoring Co-authored-by: Docker_Admin_v1 --- .env.example | 50 +++++++ DOCKER.md | 287 ++++++++++++++++++++++++++++++------ Dockerfile | 43 +++++- docker-compose.override.yml | 22 +++ docker-compose.prod.yml | 22 +++ docker-compose.yml | 53 ++++++- 6 files changed, 423 insertions(+), 54 deletions(-) create mode 100644 .env.example create mode 100644 docker-compose.override.yml create mode 100644 docker-compose.prod.yml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..87b03c3 --- /dev/null +++ b/.env.example @@ -0,0 +1,50 @@ +# OpenSpace Docker Environment Configuration +# Copy this file to .env and customize your settings + +# ==================== Required ==================== +# Generate a secure random key for your OpenSpace instance +# You can generate one with: openssl rand -base64 32 +OPENSPACE_API_KEY=your_openpspace_api_key_here + +# ==================== LLM Providers ==================== +# Choose ONE provider configuration below + +# Option 1: OpenAI (GPT-4, GPT-3.5, etc.) +# OPENAI_API_KEY=sk-... + +# Option 2: Anthropic (Claude) +# ANTHROPIC_API_KEY=sk-ant-... + +# Option 3: StepFun (Step models via OpenRouter) +# Note: Using OpenRouter as the API gateway +OPENSPACE_MODEL=stepfun/step-3.5-flash:free +OPENSPACE_LLM_API_KEY=sk-or-v1-... +OPENSPACE_LLM_API_BASE=https://openrouter.ai/api/v1 + +# Option 4: Custom provider (Local LLM, Together, etc.) +# OPENSPACE_LLM_API_KEY=your_api_key +# OPENSPACE_LLM_API_BASE=https://your-llm-provider.com/v1 +# OPENSPACE_MODEL=your-model-name + +# ==================== Optional ==================== +# Default model to use when not specified in queries +# OPENSPACE_MODEL=claude-3-7-sonnet-latest + +# Enable debug logging (set to 1) +# OPENSPACE_DEBUG=0 + +# ==================== Docker Compose Configuration ==================== +# Override default host port (default: 9001) +# HOST_PORT=9001 + +# Volume type: "named" (Docker-managed) or "bind" (host directory) +# VOLUME_TYPE=named + +# When VOLUME_TYPE=named, these named volumes are used: +# VOLUME_DATA=openspace-data +# VOLUME_SKILLS=openspace-skills + +# When VOLUME_TYPE=bind, create local directories: +# (not set via env, edit docker-compose.yml directly) +# - ./data:/app/.openspace +# - ./skills:/app/skills diff --git a/DOCKER.md b/DOCKER.md index 91d07c8..2cff714 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -4,75 +4,280 @@ This guide provides instructions on how to run OpenSpace in a Docker container. ## Prerequisites -- [Docker](https://docs.docker.com/get-docker/) -- [Docker Compose](https://docs.docker.com/compose/install/) +- [Docker](https://docs.docker.com/get-docker/) (20.10+) +- [Docker Compose](https://docs.docker.com/compose/install/) (v2.0+) ## Quick Start (Docker Compose) The easiest way to get OpenSpace running is using `docker-compose`. -1. **Clone the repository:** +### 1. Clone the Repository - ```bash - git clone https://github.com/HKUDS/OpenSpace.git - cd OpenSpace - ``` +```bash +git clone https://github.com/HKUDS/OpenSpace.git +cd OpenSpace +git checkout feat/docker-deployment +``` -2. **Configure Environment Variables:** - - Create a `.env` file in the root directory and add your API keys: - - ```bash - cp .env.example .env - # Edit .env with your favorite editor and set your API keys: - # OPENSPACE_API_KEY=your_key - # OPENAI_API_KEY=your_key - # ANTHROPIC_API_KEY=your_key - - # Optionally, configure custom LLM models/providers: - # OPENSPACE_MODEL=deepseek/deepseek-chat - # OPENSPACE_LLM_API_KEY=sk-xxxx - # OPENSPACE_LLM_API_BASE=https://api.deepseek.com/v1 - ``` +### 2. Configure Environment Variables -3. **Build and Run:** +```bash +# Copy the example environment file +cp .env.example .env - ```bash - docker-compose up -d --build - ``` +# Edit .env with your configuration +# Required at minimum: +# OPENSPACE_API_KEY=$(openssl rand -base64 32) +# +# Choose and configure ONE LLM provider: +# - OpenAI + OPENAI_API_KEY +# - Anthropic + ANTHROPIC_API_KEY +# - OpenRouter + OPENSPACE_LLM_API_KEY + OPENSPACE_LLM_API_BASE + OPENSPACE_MODEL +``` + +**Environment Variables Reference:** + +| Variable | Required | Description | +|----------|----------|-------------| +| `OPENSPACE_API_KEY` | **Yes** | Secret API key for this OpenSpace instance. Generate with `openssl rand -base64 32` | +| `OPENAI_API_KEY` | No | OpenAI API key (sk-...) | +| `ANTHROPIC_API_KEY` | No | Anthropic API key (sk-ant-...) | +| `OPENSPACE_MODEL` | No | Default model name (e.g., `claude-3-7-sonnet-latest`, `stepfun/step-3.5-flash:free`) | +| `OPENSPACE_LLM_API_KEY` | No | API key for custom LLM provider | +| `OPENSPACE_LLM_API_BASE` | No | Base URL for custom LLM provider (e.g., `https://openrouter.ai/api/v1`) | +| `OPENSPACE_DEBUG` | No | Set to `1` to enable debug logging | +| `HOST_PORT` | No | Host port to expose (default: `9001`) | +| `VOLUME_TYPE` | No | `named` (default) or `bind` for local directories | + +### 3. Build and Run + +```bash +# Standard docker-compose (uses docker-compose.yml) +docker compose up -d --build -4. **Access the Dashboard:** +# For production with stricter resource limits: +# docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build - Open your browser and navigate to [http://localhost:7788](http://localhost:7788). The frontend and backend are both served seamlessly from the same container. +# To stop: +docker compose down -## Interacting with the CLI +# To view logs: +docker compose logs -f openspace + +# To check health status: +docker compose ps +``` + +### 4. Access the Dashboard + +Open your browser and navigate to: + +- **Dashboard:** http://localhost:${HOST_PORT:-9001} +- Health endpoint: http://localhost:${HOST_PORT:-9001}/health + +The frontend and backend are served seamlessly from the same container. + +--- + +## CLI Usage You can use the container to execute OpenSpace CLI commands. -**To run a single task using the CLI inside the running container:** +### Run a Query ```bash -docker exec -it openspace openspace --model "anthropic/claude-sonnet-4-5" --query "Analyze the local skills" +docker exec -it openspace openspace --model "anthropic/claude-sonnet-4.5" --query "Analyze the local skills" ``` -**To download/upload skills:** +### Download/Upload Skills ```bash docker exec -it openspace openspace-download-skill docker exec -it openspace openspace-upload-skill /app/skills/my-skill ``` -## Volumes +### Enter Container Shell + +```bash +docker exec -it openspace bash +``` + +--- -The `docker-compose.yml` is configured with two persistent volumes: +## Volume & Data Management -- `openspace-data`: Mounted to `/app/.openspace`, storing the SQLite database (`openspace.db`) containing the skill evolution history and metadata. -- `openspace-skills`: Mounted to `/app/skills`, allowing you to persist downloaded and custom skills across container restarts. +### Volume Types -If you prefer to mount a local directory for your skills so you can edit them directly from your host machine, you can update the `docker-compose.yml` file: +1. **Named volumes** (default) - Managed by Docker, good for simple deployments + - `openspace-data`: Contains SQLite database (`openspace.db`) and skill history + - `openspace-skills`: Persists downloaded and custom skills + +2. **Bind mounts** - Direct host directory access, better for development + Edit `docker-compose.yml`: + ```yaml + volumes: + - ./data:/app/.openspace + - ./skills:/app/skills + ``` + +### Backup & Restore + +**Backup:** +```bash +# Named volumes +docker run --rm -v openspace-data:/data -v $(pwd):/backup alpine tar czf /backup/openspace-data-$(date +%Y%m%d).tar.gz -C /data . + +# Bind mounts (just copy the directories) +cp -r data skills backup/ +``` + +**Restore:** +```bash +# Named volumes +docker run --rm -v openspace-data:/data -v $(pwd):/backup alpine sh -c "rm -rf /data/* && tar xzf /backup/openspace-data-YYYYMMDD.tar.gz -C /data" + +# Bind mounts +cp -r backup/data backup/skills ./ +``` + +--- + +## Monitoring + +### Health Check + +OpenSpace container includes a health check that pings `/health` endpoint every 30 seconds. Check status: + +```bash +docker compose ps +# Look for "healthy" in the STATUS column +``` + +### Prometheus Metrics + +If you have a Prometheus instance, you can scrape metrics from OpenSpace. Add to your `docker-compose.yml`: ```yaml - volumes: - - openspace-data:/app/.openspace - - ./my-local-skills:/app/skills +services: + openspace: + # Add this label for service discovery + labels: + - "prometheus-job=openspace" ``` + +Then configure Prometheus to scrape `openspace:7788/metrics` (if endpoint is available). + +### Logs + +Logs are configured with rotation (10MB max, 3 files by default). View logs: + +```bash +docker compose logs -f openspace +# Or with timestamps +docker compose logs -f --timestamp openspace +``` + +For centralized logging, consider using Loki/Promtail stack (not included by default). + +--- + +## Troubleshooting + +### Container fails to start + +Check logs: +```bash +docker compose logs openspace +``` + +Common issues: +- **Missing OPENSPACE_API_KEY**: Set it in `.env` file +- **Port already in use**: Change `HOST_PORT` in `.env` or stop the conflicting service +- **Insufficient memory**: Increase Docker memory limit (Settings → Resources) + +### Health check failing + +The health check endpoint `/health` might not be available in older versions. If using a development build, you may need to disable the health check by removing it from `docker-compose.yml`. + +### Permission denied on volumes + +If using bind mounts, ensure the host directories are readable/writable by the container user (UID 1000). Fix with: +```bash +sudo chown -R 1000:1000 data skills +``` + +--- + +## Production Deployment Checklist + +- [ ] Generate a strong `OPENSPACE_API_KEY` and keep it secret +- [ ] Configure SSL/TLS termination (use reverse proxy like nginx or Traefik) +- [ ] Set appropriate resource limits (memory: 2-4G, CPU: 2-4 cores) +- [ ] Enable log rotation and set up log aggregation +- [ ] Configure regular backups of `openspace-data` volume +- [ ] Set up monitoring (Prometheus + Grafana) +- [ ] Use `docker-compose.prod.yml` for additional production settings +- [ ] Restrict access to the API and dashboard via firewall/VPC +- [ ] Keep Docker and base images updated regularly + +--- + +## Advanced Configuration + +### Custom Network + +To integrate with other services on a custom network: + +```yaml +networks: + app-network: + driver: bridge + +services: + openspace: + networks: + - app-network +``` + +### Multi-stage Deployment (with separate frontend/backend) + +For large-scale deployments, you might split frontend and backend services. See `docker-compose.multi.yml` (if available). + +### Environment-Specific Configs + +Use multiple compose files: + +```bash +# Development (with hot-reload, less resource limits) +docker compose -f docker-compose.yml -f docker-compose.override.yml up -d + +# Production (strict limits, optimized) +docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d +``` + +--- + +## Security Notes + +- The Dockerfile creates and uses a non-root user `appuser` (UID 1000) +- `OPENSPACE_API_KEY` should be treated as a secret; rotate periodically +- Network access is limited to what the container needs; avoid `--network host` +- Keep the host and Docker daemon updated to prevent vulnerabilities + +--- + +## Contributing + +Found an issue or want to improve the Docker deployment? PRs welcome! + +Please update: +- `docker-compose.yml` (core config) +- `Dockerfile` (build instructions) +- `DOCKER.md` (this documentation) +- Add/maintain `.env.example` + +--- + +## License + +MIT diff --git a/Dockerfile b/Dockerfile index efc952d..7866016 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,25 @@ # Stage 1: Build the frontend FROM node:20-slim AS frontend-builder WORKDIR /app/frontend + +# Copy package files and install dependencies (cached layer) COPY frontend/package.json frontend/package-lock.json* ./ -RUN npm install +RUN npm ci --only=production + +# Copy source and build COPY frontend/ ./ RUN npm run build -# Stage 2: Build the backend and serve +# Stage 2: Build the backend FROM python:3.12-slim + +# Create a non-root user for security +RUN groupadd -r appuser && useradd -r -g appuser appuser + WORKDIR /app -# Install system dependencies required for python packages and GUI features +# Install system dependencies required for python packages +# Separate apt commands to leverage cache and clean up in same layer RUN apt-get update && apt-get install -y --no-install-recommends \ gcc \ python3-dev \ @@ -18,13 +27,22 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # Copy backend source -COPY . /app/ +COPY --chown=appuser:appuser . /app/ -# Install the Python package with linux optional dependencies -RUN pip install --no-cache-dir -e .[linux] +# Switch to non-root user for pip install (when possible) +# Some packages may need system deps, but we installed them as root above +USER appuser -# Copy built frontend from Stage 1 -COPY --from=frontend-builder /app/frontend/dist /app/frontend/dist +# Install Python package with minimal dependencies (linux extras require additional system deps) +# Use --no-cache-dir to reduce image size +RUN pip install --no-cache-dir -e . + +# Copy built frontend from Stage 1 (needs root to change ownership) +USER root +COPY --from=frontend-builder --chown=appuser:appuser /app/frontend/dist /app/frontend/dist + +# Switch back to non-root user +USER appuser # Expose the dashboard port EXPOSE 7788 @@ -33,6 +51,15 @@ EXPOSE 7788 ENV HOST=0.0.0.0 ENV PORT=7788 ENV OPENSPACE_WORKSPACE=/app +ENV PYTHONUNBUFFERED=1 + +# Create necessary directories with proper permissions +RUN mkdir -p /app/.openspace /app/skills && \ + chmod 700 /app/.openspace /app/skills + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ + CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:7788/health', timeout=5)" || exit 1 # Run the dashboard server by default CMD ["openspace-dashboard", "--host", "0.0.0.0", "--port", "7788"] diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..edbd069 --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,22 @@ +# Development overrides for OpenSpace +# Automatically used by docker-compose up in development + +services: + openspace: + # Mount source code for live editing (requires rebuild on changes) + # volumes: + # - ./openspace:/app/openspace:ro + # - ./frontend:/app/frontend:ro + # Development-friendly resource limits + deploy: + resources: + limits: + memory: 4G # More memory for dev + reservations: + memory: 1G + logging: + options: + max-size: "20m" + max-file: "3" + labels: + - "com.openspace.environment=development" diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..130d9e7 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,22 @@ +# Production-specific overrides for OpenSpace +# Usage: docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d + +services: + openspace: + # Production resource limits + deploy: + resources: + limits: + memory: 4G + cpus: '4.0' + reservations: + memory: 1G + cpus: '1.0' + # More aggressive log rotation for production + logging: + options: + max-size: "50m" + max-file: "5" + labels: + - "com.openspace.environment=production" + - "com.openspace.log-level=info" diff --git a/docker-compose.yml b/docker-compose.yml index b3c8df4..babfcf3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: openspace: build: @@ -7,19 +5,64 @@ services: dockerfile: Dockerfile container_name: openspace ports: - - "7788:7788" + - "${HOST_PORT:-9001}:7788" volumes: - - openspace-data:/app/.openspace - - openspace-skills:/app/skills + # Use bind mounts for easier access, or named volumes for persistence + - ${VOLUME_TYPE:-named}:${VOLUME_DATA:-openspace-data}:/app/.openspace + - ${VOLUME_TYPE:-named}:${VOLUME_SKILLS:-openspace-skills}:/app/skills + # For bind mounts, you would use: + # - ./data:/app/.openspace + # - ./skills:/app/skills environment: + # Required: Generate a secure API key for this instance - OPENSPACE_API_KEY=${OPENSPACE_API_KEY:-} + # Optional: OpenAI API key (if using OpenAI models) - OPENAI_API_KEY=${OPENAI_API_KEY:-} + # Optional: Anthropic API key (if using Claude) - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} + # Optional: Default model to use (e.g., "claude-3-7-sonnet-latest") - OPENSPACE_MODEL=${OPENSPACE_MODEL:-} + # Optional: Custom LLM provider (like OpenRouter, local LLM) - OPENSPACE_LLM_API_KEY=${OPENSPACE_LLM_API_KEY:-} - OPENSPACE_LLM_API_BASE=${OPENSPACE_LLM_API_BASE:-} + # Optional: Set to "1" to enable debug logging + - OPENSPACE_DEBUG=${OPENSPACE_DEBUG:-0} + # Internal config + - HOST=0.0.0.0 + - PORT=7788 + - OPENSPACE_WORKSPACE=/app restart: unless-stopped + # Health check to ensure the service is ready + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:7788/health || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + # Resource limits (adjust based on your needs) + deploy: + resources: + limits: + memory: 2G + cpus: '2.0' + reservations: + memory: 512M + cpus: '0.5' + # Logging configuration to prevent disk fill + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + # Labels for monitoring and identification + labels: + - "com.openspace.service=true" + - "com.openspace.component=api" + - "com.openspace.version=${OPENSPACE_VERSION:-latest}" +# Named volumes for data persistence (used when VOLUME_TYPE=named) volumes: openspace-data: + driver: local openspace-skills: + driver: local From 24b5045a3e876c4b1f4371461d87533b60ffbf42 Mon Sep 17 00:00:00 2001 From: Docker_Admin_v1 Date: Tue, 7 Apr 2026 11:22:59 +0000 Subject: [PATCH 4/4] docs(readme): enhance Docker deployment documentation in both English and Chinese READMEs with comprehensive deployment guides, production config, security details, troubleshooting, and cross-references to DOCKER.md --- README.md | 96 +++++++++++++++++++++++++- README_CN.md | 188 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 271 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index f27bbf2..4921f73 100644 --- a/README.md +++ b/README.md @@ -297,17 +297,107 @@ npm run dev ### 🐳 Docker Deployment -To deploy OpenSpace without worrying about local Python and Node.js dependencies, you can use the official Docker image. We provide a `docker-compose.yml` for an easy, single-command setup. +To deploy OpenSpace without worrying about local Python and Node.js dependencies, you can use Docker containerization. We provide a `docker-compose.yml` for an easy, single-command setup with production-grade features. + +#### Quick Deploy (Development) + +This is the simplest way to get started: ```bash # Clone the repository git clone https://github.com/HKUDS/OpenSpace.git cd OpenSpace -# Setup your API keys +# Configure environment variables cp .env.example .env -# Edit .env with your LLM API keys +# Edit .env to add your LLM API keys + +# Start containers +docker-compose up -d --build + +# Verify status +docker-compose ps +``` + +Once started, access: +- **Dashboard**: http://localhost:7788 +- **API Service**: http://localhost:7777 + +#### Production Deployment + +For production, use `docker-compose.prod.yml` overlay: + +```bash +docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build +docker-compose logs -f +docker stats +``` + +Production features: +- ✅ **Resource limits**: 4 CPU cores, 4GB memory +- ✅ **Log management**: 50MB per file, 5 rotations +- ✅ **Health checks**: Automatic container health detection +- ✅ **Data persistence**: Named volumes or bind mounts + +#### Docker Configuration Details + +**🔒 Security:** +- Non-root user `appuser` runs the container +- Minimal image layers for reduced attack surface + +**📁 Data Volumes:** + +```yaml +volumes: + - .openspace:/app/.openspace # Skill database and embedding cache + - logs:/app/logs # Log persistence +``` + +**🔌 Ports & Services:** + +| Service | Port | Description | +|---------|------|-------------| +| `openspace` (Dashboard) | 7788 | Web UI and API | +| `openspace-cli` | - | CLI tool | + +#### Environment Variables + +See `.env.example` for all options. Key settings: + +```bash +# Required +OPENAI_API_KEY=sk-xxx +OPENSPACE_MODEL=gpt-4o + +# Docker tuning +HOST_PORT=7788 # Frontend port +OPENSPACE_WORKSPACE=/app # Workspace inside container +OPENSPACE_LOG_LEVEL=INFO # Log level + +# Optional (cloud features) +OPENSPACE_API_KEY=sk-xxx +``` + +#### Troubleshooting + +```bash +# View logs +docker-compose logs openspace + +# Check port conflicts +docker-compose port openspace 7788 + +# Enter container +docker-compose exec openspace bash + +# Monitor resources +docker stats openspace +``` +- **Port conflicts:** Select unused port via `HOST_PORT` in `.env`. Run `docker ps` to see used ports. +- **Backup/restore, custom networks, monitoring:** See **[DOCKER.md](./DOCKER.md)** for complete guide. +- **Full configuration:** See **[openspace/config/README.md](./openspace/config/README.md)** +- **Custom skills:** See **[openspace/skills/README.md](./openspace/skills/README.md)** # Start the container docker-compose up -d --build ``` diff --git a/README_CN.md b/README_CN.md index 9a08945..6f09e21 100644 --- a/README_CN.md +++ b/README_CN.md @@ -297,30 +297,198 @@ npm run dev ### 🐳 Docker 容器化部署 -为了避免配置本地 Python 和 Node.js 环境,你可以使用 Docker 容器化运行 OpenSpace。我们提供了一个 `docker-compose.yml` 用于一键部署。 +为了避免配置本地 Python 和 Node.js 环境,你可以使用 Docker 容器化运行 OpenSpace。我们提供了完整的 docker-compose 配置,包含生产级监控、日志轮转、资源限制和健康检查。 + +#### 快速部署(开发环境) + +这是最简单的启动方式,适合开发和快速测试: ```bash -# 克隆仓库 +# 1. 克隆仓库 git clone https://github.com/HKUDS/OpenSpace.git cd OpenSpace -# 配置环境变量 +# 2. 配置环境变量 cp .env.example .env -# 编辑 .env 文件,填入你的 API 密钥 +# 编辑 .env,填入你的 LLM API 密钥 -# 启动容器 +# 3. 启动容器 docker-compose up -d --build + +# 4. 验证状态 +docker-compose ps +``` + +启动成功后,访问: +- **Dashboard**: http://localhost:7788 +- **API 服务**: http://localhost:7777 + +#### 生产部署 + +生产环境建议使用 `docker-compose.prod.yml` 覆盖配置: + +```bash +# 使用生产配置启动 +docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build + +# 查看日志(实时) +docker-compose logs -f + +# 查看资源使用 +docker stats +``` + +生产配置特点: +- ✅ **资源限制严格**:CPU 限制 4 核,内存限制 4G +- ✅ **日志管理**:50MB 每文件,保留 5 个轮转文件 +- ✅ **健康检查**:自动检测容器健康状况 +- ✅ **数据持久化**:使用 Docker named volumes 或 bind mounts + +#### Docker 配置详解 + +我们的 Docker 配置基于最佳实践,包含以下关键特性: + +**🔒 安全性增强:** +- 非 root 用户 `appuser` 运行容器 +- 应用与系统目录分离 +- 最小化镜像层,减少攻击面 + +**💡 资源管理:** +- CPU 和内存限制(可配置) +- 健康检查端点 `/health` +- 合理的重启策略(on-failure) + +**📊 日志管理:** +- JSON 格式日志,便于日志收集系统解析 +- 日志轮转配置,防止磁盘写满 +- 支持 stdout/stderr 分离 + +**📁 数据卷:** + +```yaml +volumes: + - .openspace:/app/.openspace # 技能数据库和 embedding 缓存 + - logs:/app/logs # 日志持久化 + - ./data:/app/data # 可选:自定义数据目录(bind mount) +``` + +**🔌 服务与端口:** + +| 服务 | 端口 | 说明 | +|------|------|------| +| `openspace` (Dashboard) | 7788 | Web UI 和 API 服务 | +| `openspace-cli` | - | CLI 命令行工具 | + +#### 环境变量配置(.env) + +所有配置项说明请参考 `.env.example`: + +```bash +# --- 必填项 --- +OPENAI_API_KEY=sk-xxx # 或使用其他 LLM 提供商 +OPENSPACE_MODEL=gpt-4o # 选择的模型 +# 或使用通用 litellm 格式:OPENSPACE_MODEL=anthropic/claude-3-7-sonnet + +# --- Docker 调优(可选)--- +HOST_PORT=7788 # 前端访问端口,默认 7788 +OPENSPACE_WORKSPACE=/app # 工作区路径(Docker 内) +OPENSPACE_LOG_LEVEL=INFO # 日志级别:DEBUG/INFO/WARNING + +# --- 云端功能(可选)--- +OPENSPACE_API_KEY=sk-xxx # 用于云端技能社区 +``` + +#### 端口管理 + +为避免端口冲突,你可以: +1. 在 `.env` 中修改 `HOST_PORT` 环境变量 +2. 或在 `docker-compose.override.yml` 中覆盖服务配置 +3. 使用 `docker-compose port` 查看实际映射的端口 + +> ⚠️ **注意**:确保所选端口未被其他容器占用。运行 `docker ps` 查看已使用的端口。 + +#### 自定义 Docker 网络(推荐生产使用) + +为提升安全性和隔离性,建议创建自定义网络: + +```bash +# 创建 bridge 网络 +docker network create openspace-network + +# 编辑 docker-compose.yml,在每个服务中添加: +# networks: +# - openspace-network +# +# networks: +# openspace-network: +# driver: bridge +``` + +#### 数据持久化与备份 + +我们的配置使用 Docker volumes 自动持久化数据。备份方法: + +```bash +# 备份技能数据库 +docker run --rm -v openspace_openspace_data:/data -v $(pwd):/backup \ + alpine tar czf /backup/openspace-backup-$(date +%Y%m%d).tar.gz -C /data . + +# 恢复技能数据库 +docker run --rm -v openspace_openspace_data:/data -v $(pwd):/backup \ + alpine sh -c "cd /data && tar xzf /backup/openspace-backup-*.tar.gz" +``` + +#### 监控集成 + +默认配置已包含 Prometheus 监控标签。你可以: +1. 确保 `PROMETHEUS_JOB=openspace` 环境变量已设置 +2. 将以下 job 配置添加到你的 `prometheus.yml`: + +```yaml +scrape_configs: + - job_name: 'openspace' + static_configs: + - targets: ['openspace:7788'] # 使用 Docker 内部服务名 +``` + +#### 故障排查 + +**容器无法启动:** +```bash +# 查看容器日志 +docker-compose logs openspace + +# 检查端口冲突 +docker-compose port openspace 7788 + +# 进入容器调试 +docker-compose exec openspace bash ``` -启动完成后,你可以通过浏览器访问 [http://localhost:7788](http://localhost:7788) 打开 OpenSpace Dashboard。 +**API 密钥问题:** +```bash +# 验证环境变量 +docker-compose exec openspace env | grep -i openai +# 或验证 LLM 配置 +docker-compose exec openspace python -c "from openspace.llm import get_llm; print(get_llm())" +``` -如果需要执行命令行操作或者配置数据卷持久化,请参阅详细的 [Docker 部署指南 (DOCKER.md)](./DOCKER.md)。 +**性能问题:** +```bash +# 查看资源使用 +docker stats openspace + +# 检查数据库大小 +docker-compose exec openspace du -sh /app/.openspace/ +``` -## 📈 基准测试:GDPVal +**端口冲突:** 在 `.env` 中使用 `HOST_PORT` 指定未使用的端口。运行 `docker ps` 查看已占用端口。 -我们在 [GDPVal](https://huggingface.co/datasets/openai/gdpval) 上评估 OpenSpace——该数据集包含 220 项真实世界的专业任务,涵盖 44 个职业——采用 [ClawWork](https://github.com/HKUDS/ClawWork) 评测协议,使用相同的生产力工具和基于 LLM 的评分方式。我们的两阶段设计(Cold Start → Warm Rerun)展示了积累的 Skill 如何随时间降低 Token 消耗。 +**完整备份/恢复、自定义网络、监控集成等详细信息**,请参阅 **[DOCKER.md](./DOCKER.md)**。 -公平基准:OpenSpace 使用 Qwen 3.5-Plus 作为骨干 LLM——与 ClawWork 基线 Agent 完全相同——确保性能差异纯粹来源于 Skill 进化,而非模型能力差异。 +**其他文档:** +- **[环境变量参考](openspace/config/README.md)** — 所有配置选项 +- **[技能系统指南](openspace/skills/README.md)** — 自定义技能公平基准:OpenSpace 使用 Qwen 3.5-Plus 作为骨干 LLM——与 ClawWork 基线 Agent 完全相同——确保性能差异纯粹来源于 Skill 进化,而非模型能力差异。 真实经济价值:任务涵盖构建工资计算器、准备纳税申报表、起草法律备忘录等——这些都是产生真实 GDP 的专业工作,同时从质量和成本效率两个维度进行评估。