Spaces:
Running
Running
Upload 5 files
Browse files- Dockerfile +33 -30
- README.md +24 -62
- build_wasm.sh +41 -0
- nginx.conf +56 -0
- start.sh +13 -10
Dockerfile
CHANGED
|
@@ -7,11 +7,9 @@ ENV HOME=/home/user
|
|
| 7 |
ENV PATH=$HOME/.local/bin:$PATH
|
| 8 |
|
| 9 |
# Install essential system packages and build tools
|
| 10 |
-
# -
|
| 11 |
-
# -
|
| 12 |
-
# -
|
| 13 |
-
# - vim, nano: Text editors
|
| 14 |
-
# - python3: For auth proxy
|
| 15 |
RUN apt-get update && apt-get install -y \
|
| 16 |
curl \
|
| 17 |
wget \
|
|
@@ -27,47 +25,52 @@ RUN apt-get update && apt-get install -y \
|
|
| 27 |
pkg-config \
|
| 28 |
python3 \
|
| 29 |
python3-pip \
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
| 31 |
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
| 32 |
|
| 33 |
# Install ttyd (Web Terminal)
|
| 34 |
RUN wget https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.x86_64 -O /usr/bin/ttyd \
|
| 35 |
&& chmod +x /usr/bin/ttyd
|
| 36 |
|
| 37 |
-
#
|
| 38 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
RUN useradd -m -u 1000 user && \
|
| 40 |
echo 'user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
| 41 |
|
| 42 |
-
# Set
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
-
# Switch to
|
|
|
|
| 46 |
USER user
|
| 47 |
|
| 48 |
-
#
|
| 49 |
-
|
| 50 |
-
RUN pip3 install --break-system-packages \
|
| 51 |
-
fastapi \
|
| 52 |
-
uvicorn[standard] \
|
| 53 |
-
httpx \
|
| 54 |
-
websockets \
|
| 55 |
-
authlib \
|
| 56 |
-
itsdangerous \
|
| 57 |
-
jinja2 \
|
| 58 |
-
python-multipart \
|
| 59 |
-
aiofiles
|
| 60 |
-
|
| 61 |
-
# Copy Authentication Proxy files
|
| 62 |
-
COPY --chown=user:user auth_proxy.py .
|
| 63 |
COPY --chown=user:user start.sh .
|
| 64 |
-
COPY --chown=user:user
|
| 65 |
|
| 66 |
-
|
| 67 |
-
RUN chmod +x start.sh
|
| 68 |
|
| 69 |
# Expose port 7860 (Standard for Hugging Face Spaces)
|
| 70 |
EXPOSE 7860
|
| 71 |
|
| 72 |
-
# Start
|
| 73 |
CMD ["./start.sh"]
|
|
|
|
| 7 |
ENV PATH=$HOME/.local/bin:$PATH
|
| 8 |
|
| 9 |
# Install essential system packages and build tools
|
| 10 |
+
# - nginx: Web server for static files (WASM) and reverse proxy
|
| 11 |
+
# - apache2-utils: For htpasswd (Basic Auth)
|
| 12 |
+
# - emscripten dependencies: python3, cmake, git, xz-utils
|
|
|
|
|
|
|
| 13 |
RUN apt-get update && apt-get install -y \
|
| 14 |
curl \
|
| 15 |
wget \
|
|
|
|
| 25 |
pkg-config \
|
| 26 |
python3 \
|
| 27 |
python3-pip \
|
| 28 |
+
nginx \
|
| 29 |
+
apache2-utils \
|
| 30 |
+
xz-utils \
|
| 31 |
+
bzip2 \
|
| 32 |
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
| 33 |
|
| 34 |
# Install ttyd (Web Terminal)
|
| 35 |
RUN wget https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.x86_64 -O /usr/bin/ttyd \
|
| 36 |
&& chmod +x /usr/bin/ttyd
|
| 37 |
|
| 38 |
+
# Install Emscripten (EMSDK)
|
| 39 |
+
# We install it to /opt/emsdk and make it available for all users
|
| 40 |
+
WORKDIR /opt
|
| 41 |
+
RUN git clone https://github.com/emscripten-core/emsdk.git
|
| 42 |
+
cd emsdk && \
|
| 43 |
+
./emsdk install latest && \
|
| 44 |
+
./emsdk activate latest && \
|
| 45 |
+
chmod -R 777 /opt/emsdk
|
| 46 |
+
|
| 47 |
+
# Add Emscripten to PATH for all users
|
| 48 |
+
ENV PATH="/opt/emsdk:/opt/emsdk/upstream/emscripten:${PATH}"
|
| 49 |
+
|
| 50 |
+
# Create a non-root user 'user' (UID 1000)
|
| 51 |
RUN useradd -m -u 1000 user && \
|
| 52 |
echo 'user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
| 53 |
|
| 54 |
+
# Set up Nginx directories and permissions
|
| 55 |
+
RUN mkdir -p /var/www/html/game && \
|
| 56 |
+
chown -R user:user /var/www/html && \
|
| 57 |
+
chown -R user:user /var/log/nginx && \
|
| 58 |
+
chown -R user:user /var/lib/nginx && \
|
| 59 |
+
chown -R user:user /etc/nginx
|
| 60 |
|
| 61 |
+
# Switch to non-root user
|
| 62 |
+
WORKDIR $HOME
|
| 63 |
USER user
|
| 64 |
|
| 65 |
+
# Copy configuration files
|
| 66 |
+
COPY --chown=user:user nginx.conf /etc/nginx/nginx.conf
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
COPY --chown=user:user start.sh .
|
| 68 |
+
COPY --chown=user:user build_wasm.sh .
|
| 69 |
|
| 70 |
+
RUN chmod +x start.sh build_wasm.sh
|
|
|
|
| 71 |
|
| 72 |
# Expose port 7860 (Standard for Hugging Face Spaces)
|
| 73 |
EXPOSE 7860
|
| 74 |
|
| 75 |
+
# Start services
|
| 76 |
CMD ["./start.sh"]
|
README.md
CHANGED
|
@@ -14,7 +14,7 @@ license: mit
|
|
| 14 |
|
| 15 |
此环境配置了 `sudo` 权限,方便你在运行时安装所需的软件(如 OpenClaw)。
|
| 16 |
|
| 17 |
-
**新特性:支持
|
| 18 |
|
| 19 |
## 🚀 快速开始
|
| 20 |
|
|
@@ -27,81 +27,43 @@ license: mit
|
|
| 27 |
6. 点击 **Create Space**。
|
| 28 |
|
| 29 |
### 2. 上传文件
|
| 30 |
-
将本仓库中的所有文件(
|
| 31 |
|
| 32 |
### 3. 配置鉴权环境变量 (重要!)
|
| 33 |
-
在 Space 的 **Settings** -> **Variables and secrets** 中添加以下环境变量。
|
| 34 |
-
|
| 35 |
-
| 变量名 | 描述 |
|
| 36 |
-
|--------|------|------|
|
| 37 |
-
| `
|
| 38 |
-
| `
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
| `GOOGLE_CLIENT_ID` | (可选) Google OAuth Client ID | `123456...apps.googleusercontent.com` |
|
| 42 |
-
| `GOOGLE_CLIENT_SECRET` | (可选) Google OAuth Client Secret | `GOCSPX-...` |
|
| 43 |
-
|
| 44 |
-
**如何获取 OAuth Client ID/Secret:**
|
| 45 |
-
|
| 46 |
-
* **GitHub**:
|
| 47 |
-
1. 访问 [GitHub Developer Settings](https://github.com/settings/developers)。
|
| 48 |
-
2. New OAuth App。
|
| 49 |
-
3. **Homepage URL**: `https://<你的用户名>-<你的Space名>.hf.space` (例如 `https://user-my-vps.hf.space`)。
|
| 50 |
-
4. **Authorization callback URL**: `https://<你的用户名>-<你的Space名>.hf.space/oauth2/callback`。
|
| 51 |
-
|
| 52 |
-
* **Google (YouTube)**:
|
| 53 |
-
1. 访问 [Google Cloud Console](https://console.cloud.google.com/apis/credentials)。
|
| 54 |
-
2. 创建凭据 -> OAuth 客户端 ID -> Web 应用。
|
| 55 |
-
3. **已获授权的 JavaScript 来源**: `https://<你的用户名>-<你的Space名>.hf.space`
|
| 56 |
-
4. **已获授权的重定向 URI**: `https://<你的用户名>-<你的Space名>.hf.space/api/auth/callback`。
|
| 57 |
|
| 58 |
### 4. 访问 VPS
|
| 59 |
配置好环境变量后,Space 会自动重启。
|
| 60 |
-
点击 **App** 标签页,
|
| 61 |
|
| 62 |
## 🛠️ 功能特性
|
| 63 |
-
- **
|
| 64 |
-
- **
|
| 65 |
-
- **
|
| 66 |
-
- **
|
| 67 |
-
- **安全鉴权**: 采用透明令牌代理(Transparent Token Proxy),支持 GitHub 和 Google (YouTube) OAuth 登录。
|
| 68 |
-
- **安全加固**: `ttyd` 仅监听本地地址(127.0.0.1),强制所有外部流量经过鉴权。
|
| 69 |
-
|
| 70 |
-
## 🎮 如何运行 OpenClaw
|
| 71 |
|
| 72 |
-
|
| 73 |
|
| 74 |
-
|
| 75 |
-
在终端中运行以下命令安装编译 OpenClaw 所需的库:
|
| 76 |
|
| 77 |
```bash
|
| 78 |
-
#
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
# 安装 SDL2 及相关依赖 (OpenClaw 核心需求)
|
| 82 |
-
sudo apt-get install -y \
|
| 83 |
-
libsdl2-dev \
|
| 84 |
-
libsdl2-image-dev \
|
| 85 |
-
libsdl2-mixer-dev \
|
| 86 |
-
libsdl2-ttf-dev \
|
| 87 |
-
libxml2-dev \
|
| 88 |
-
zlib1g-dev
|
| 89 |
```
|
| 90 |
|
| 91 |
-
|
| 92 |
-
```bash
|
| 93 |
-
# 克隆 OpenClaw 仓库
|
| 94 |
-
git clone https://github.com/pjasicek/OpenClaw.git
|
| 95 |
-
cd OpenClaw
|
| 96 |
-
|
| 97 |
-
# 创建构建目录
|
| 98 |
-
mkdir build && cd build
|
| 99 |
|
| 100 |
-
#
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
```
|
| 104 |
|
| 105 |
## ⚠️ 安全警告
|
| 106 |
- 此 VPS 拥有 root 权限,请勿在其中存储敏感密钥。
|
| 107 |
-
- 请务必设置
|
|
|
|
| 14 |
|
| 15 |
此环境配置了 `sudo` 权限,方便你在运行时安装所需的软件(如 OpenClaw)。
|
| 16 |
|
| 17 |
+
**新特性:支持 WebAssembly (WASM) 编译环境与 Nginx 静态服务。**
|
| 18 |
|
| 19 |
## 🚀 快速开始
|
| 20 |
|
|
|
|
| 27 |
6. 点击 **Create Space**。
|
| 28 |
|
| 29 |
### 2. 上传文件
|
| 30 |
+
将本仓库中的所有文件(`Dockerfile`, `README.md`, `start.sh`, `nginx.conf`, `build_wasm.sh`)上传到你的 Space 仓库中。
|
| 31 |
|
| 32 |
### 3. 配置鉴权环境变量 (重要!)
|
| 33 |
+
在 Space 的 **Settings** -> **Variables and secrets** 中添加以下环境变量,用于设置登录的用户名和密码。
|
| 34 |
+
|
| 35 |
+
| 变量名 | 描述 | 默认值 |
|
| 36 |
+
|--------|------|--------|
|
| 37 |
+
| `TTYD_USER` | 登录用户名 | `admin` |
|
| 38 |
+
| `TTYD_PASSWORD` | 登录密码 | `admin123456` |
|
| 39 |
+
|
| 40 |
+
**⚠️ 警告**: 请务必修改默认密码,否则所有人都能访问你的 VPS!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
|
| 42 |
### 4. 访问 VPS
|
| 43 |
配置好环境变量后,Space 会自动重启。
|
| 44 |
+
点击 **App** 标签页,输入用户名密码即可进入终端。
|
| 45 |
|
| 46 |
## 🛠️ 功能特性
|
| 47 |
+
- **Web 终端**: 访问根路径 `/`,使用 `ttyd` 管理 VPS。
|
| 48 |
+
- **WASM 游戏预览**: 访问 `/game`,预览编译好的 WebAssembly 游戏(需先编译)。
|
| 49 |
+
- **WASM 编译环境**: 预装 Emscripten (emsdk),随时准备编译 C++ 项目。
|
| 50 |
+
- **Nginx 反代**: 统一管理路由和 Basic Auth 鉴权,稳定可靠。
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
+
## 🎮 如何编译 OpenClaw 为 WASM
|
| 53 |
|
| 54 |
+
这是一个高级任务。环境已经准备好,你可以尝试在终端中运行以下命令:
|
|
|
|
| 55 |
|
| 56 |
```bash
|
| 57 |
+
# 运行辅助构建脚本
|
| 58 |
+
./build_wasm.sh
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
```
|
| 60 |
|
| 61 |
+
如果编译成功,访问 `https://<你的Space地址>/game` 即可看到游戏界面。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
+
### 注意事项
|
| 64 |
+
- **图形界面限制**: 直接运行 `./OpenClaw` 可能会报错 `Could not initialize SDL: No available video device`,因�� Space 没有连接显示器。
|
| 65 |
+
- **持久化存储**: Hugging Face Spaces 重启后,非 `/data` 目录下的文件会丢失。建议将重要数据保存在 `/data` 目录(如果启用了 Persistent Storage)或使用 Git 同步代码。
|
|
|
|
| 66 |
|
| 67 |
## ⚠️ 安全警告
|
| 68 |
- 此 VPS 拥有 root 权限,请勿在其中存储敏感密钥。
|
| 69 |
+
- 请务必设置强密码。
|
build_wasm.sh
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
# 这是一个辅助脚本,用于在终端中手动编译 OpenClaw 为 WASM
|
| 4 |
+
# 用法: ./build_wasm.sh
|
| 5 |
+
|
| 6 |
+
# 确保 Emscripten 环境已激活
|
| 7 |
+
source "/opt/emsdk/emsdk_env.sh"
|
| 8 |
+
|
| 9 |
+
echo "Downloading OpenClaw source..."
|
| 10 |
+
git clone https://github.com/pjasicek/OpenClaw.git
|
| 11 |
+
cd OpenClaw
|
| 12 |
+
|
| 13 |
+
# 简单的 Hello World 验证 (可选)
|
| 14 |
+
# echo "int main() { return 0; }" > test.c
|
| 15 |
+
# emcc test.c -o test.html
|
| 16 |
+
|
| 17 |
+
# OpenClaw 编译尝试 (这只是一个起点,通常需要修改源码)
|
| 18 |
+
# 注意: OpenClaw 依赖 SDL2, SDL2_image, SDL2_mixer, SDL2_ttf
|
| 19 |
+
# Emscripten 内置了 SDL2 (-s USE_SDL=2),但其他库需要 port
|
| 20 |
+
|
| 21 |
+
mkdir -p build_wasm
|
| 22 |
+
cd build_wasm
|
| 23 |
+
|
| 24 |
+
echo "Configuring CMake for WASM..."
|
| 25 |
+
emcmake cmake .. \
|
| 26 |
+
-DPLATFORM=EMSCRIPTEN \
|
| 27 |
+
-DCMAKE_BUILD_TYPE=Release
|
| 28 |
+
|
| 29 |
+
echo "Building..."
|
| 30 |
+
emmake make -j$(nproc)
|
| 31 |
+
|
| 32 |
+
# 如果编译成功,将结果复制到 Nginx 目录
|
| 33 |
+
if [ -f "OpenClaw.html" ]; then
|
| 34 |
+
echo "Build successful! Deploying to /var/www/html/game..."
|
| 35 |
+
cp OpenClaw.html /var/www/html/game/index.html
|
| 36 |
+
cp OpenClaw.js /var/www/html/game/
|
| 37 |
+
cp OpenClaw.wasm /var/www/html/game/
|
| 38 |
+
cp OpenClaw.data /var/www/html/game/ 2>/dev/null || true
|
| 39 |
+
else
|
| 40 |
+
echo "Build failed or output file not found."
|
| 41 |
+
fi
|
nginx.conf
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
worker_processes auto;
|
| 2 |
+
pid /tmp/nginx.pid;
|
| 3 |
+
include /etc/nginx/modules-enabled/*.conf;
|
| 4 |
+
|
| 5 |
+
events {
|
| 6 |
+
worker_connections 768;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
http {
|
| 10 |
+
sendfile on;
|
| 11 |
+
tcp_nopush on;
|
| 12 |
+
types_hash_max_size 2048;
|
| 13 |
+
include /etc/nginx/mime.types;
|
| 14 |
+
default_type application/octet-stream;
|
| 15 |
+
|
| 16 |
+
# Logging to stdout/stderr for Docker
|
| 17 |
+
access_log /dev/stdout;
|
| 18 |
+
error_log /dev/stderr;
|
| 19 |
+
|
| 20 |
+
# Temp paths for non-root user
|
| 21 |
+
client_body_temp_path /tmp/client_body;
|
| 22 |
+
proxy_temp_path /tmp/proxy;
|
| 23 |
+
fastcgi_temp_path /tmp/fastcgi;
|
| 24 |
+
uwsgi_temp_path /tmp/uwsgi;
|
| 25 |
+
scgi_temp_path /tmp/scgi;
|
| 26 |
+
|
| 27 |
+
server {
|
| 28 |
+
listen 7860;
|
| 29 |
+
|
| 30 |
+
# Basic Auth Configuration
|
| 31 |
+
auth_basic "Restricted Access";
|
| 32 |
+
auth_basic_user_file /etc/nginx/.htpasswd;
|
| 33 |
+
|
| 34 |
+
# 1. Terminal (ttyd) - Root Path
|
| 35 |
+
location / {
|
| 36 |
+
proxy_pass http://127.0.0.1:7681;
|
| 37 |
+
proxy_http_version 1.1;
|
| 38 |
+
proxy_set_header Upgrade $http_upgrade;
|
| 39 |
+
proxy_set_header Connection "upgrade";
|
| 40 |
+
proxy_set_header Host $host;
|
| 41 |
+
proxy_set_header X-Real-IP $remote_addr;
|
| 42 |
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
| 43 |
+
proxy_set_header X-Forwarded-Proto $scheme;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
# 2. Game (WASM) - /game Path
|
| 47 |
+
location /game {
|
| 48 |
+
alias /var/www/html/game;
|
| 49 |
+
index index.html;
|
| 50 |
+
|
| 51 |
+
# WASM specific headers
|
| 52 |
+
add_header Cross-Origin-Opener-Policy same-origin;
|
| 53 |
+
add_header Cross-Origin-Embedder-Policy require-corp;
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
}
|
start.sh
CHANGED
|
@@ -1,16 +1,19 @@
|
|
| 1 |
#!/bin/bash
|
| 2 |
|
| 3 |
-
#
|
| 4 |
-
|
| 5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
# -W: 允许写入
|
| 7 |
echo "Starting ttyd on 127.0.0.1:7681..."
|
| 8 |
ttyd -p 7681 -i 127.0.0.1 -W bash &
|
| 9 |
|
| 10 |
-
#
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
# 启动鉴权代理
|
| 14 |
-
echo "Starting Auth Proxy on port 7860..."
|
| 15 |
-
# 使用 uvicorn 启动,监听所有 IP (0.0.0.0) 以便 HF 访问
|
| 16 |
-
uvicorn auth_proxy:app --host 0.0.0.0 --port 7860
|
|
|
|
| 1 |
#!/bin/bash
|
| 2 |
|
| 3 |
+
# 获取环境变量
|
| 4 |
+
USER=${TTYD_USER:-"admin"}
|
| 5 |
+
PASSWORD=${TTYD_PASSWORD:-"admin123456"}
|
| 6 |
+
|
| 7 |
+
# 生成 Nginx Basic Auth 文件
|
| 8 |
+
echo "Generating .htpasswd for user: $USER"
|
| 9 |
+
htpasswd -bc /etc/nginx/.htpasswd "$USER" "$PASSWORD"
|
| 10 |
+
|
| 11 |
+
# 启动 ttyd (本地监听,无 Auth,由 Nginx 接管)
|
| 12 |
+
# -i 127.0.0.1: 仅监听本地
|
| 13 |
# -W: 允许写入
|
| 14 |
echo "Starting ttyd on 127.0.0.1:7681..."
|
| 15 |
ttyd -p 7681 -i 127.0.0.1 -W bash &
|
| 16 |
|
| 17 |
+
# 启动 Nginx
|
| 18 |
+
echo "Starting Nginx on port 7860..."
|
| 19 |
+
nginx -g "daemon off;"
|
|
|
|
|
|
|
|
|
|
|
|