跳到内容
MagicFrog
目录

自部署

运行 MagicFrog 控制面——单文件服务端,或 Docker Compose。

自部署(self-hosted)是 MagicFrog 控制面的部署模型。支持两种形态,共享同一条规则:没有托管服务,也没有其他部署拓扑。单文件服务端是主路径——一个下载的二进制、一个 SQLite 文件,不需要容器 runtime。Docker Compose 仍可作为可选替代。


快速开始——单文件服务端

三条命令即可拉起一个可用的控制面:

curl -fsSL https://www.magicfrog.ai/install-server | bash
chmod +x ~/.magicfrog/bin/magicfrog-server
MAGICFROG_PASSWORD='<server-api-password>' \
MAGICFROG_ADMIN_IDENTIFIER='admin@example.com' \
MAGICFROG_ADMIN_PASSWORD='<initial-admin-password>' \
MAGICFROG_FIELD_KEY='<64-hex-chars>' \
./magicfrog-server serve --hostname 0.0.0.0 --port 4096

安装器把二进制放进 ~/.magicfrog/bin——与 magicfrog 客户端 CLI 相同的位置。在该目录中运行,或把它加进你的 PATH;可用 --data <dir> 或 MAGICFROG_DATA_DIR 设置别的数据目录。

必需环境变量

四个变量全部必填——缺任何一个,服务端都会显式启动失败,而不是带着空凭据启动:

变量 含义
MAGICFROG_PASSWORD 客户端 --server 连接密码
MAGICFROG_ADMIN_IDENTIFIER 初始管理员(邮箱或用户名)
MAGICFROG_ADMIN_PASSWORD 初始管理员密码
MAGICFROG_FIELD_KEY 字段加密密钥,64 个十六进制字符(openssl rand -hex 32)

MAGICFROG_ADMIN_IDENTIFIER 与 MAGICFROG_ADMIN_PASSWORD 必须成对注入——只给其一会让服务端在启动时显式失败。MAGICFROG_FIELD_KEY 也可以改用 MAGICFROG_FIELD_KEY_FILE(卷/secret 挂载)提供;两者都设置时以直接值为准。

首次启动与初始管理员

首次启动时,服务端把一个以给定标识与初始密码的账号写入 SQLite,标记它 role=owner 并置上 must_change_password;账号已存在时跳过写入(重启不会覆盖它)。初始密码只属于部署状态,且一次性。

强制改密

用初始密码经 POST /v1/account/login 登录(/admin 的管理控制台登录是同一道门)。响应携带 mustChangePassword=true。

该标志置位期间,除登录与改密之外的每个业务端点都以 403 password_change_required 拒绝请求。客户端呈现改密界面而不是工作台。经 POST /v1/account/change-password 提交旧密码与新密码:服务端校验旧密码,把新密码以单向哈希存储(明文绝不落盘),并清除标志。初始密码就此作废。

范围:一台服务器

控制面刻意做成单服务器:它只在自己所在的主机上、经该主机的容器 runtime 托管创建并管理云电脑。没有远程 Docker daemon 设置(DOCKER_HOST 一类)、没有多主机节点资源池、没有跨机器调度或集群模式。持久化遵循同一条规则——一个 SQLite 文件,没有外部或共享数据库选项。完整边界见云电脑。

你用 CLI 自行登记的机器在这个范围之外:控制面通过它们主动外连的 daemon 连接向它们发送工具调用,但从不托管创建、启动、停止或销毁它们。

单文件服务端的可变状态存放在数据目录(MAGICFROG_DATA_DIR 或 --data;SQLite 数据库为 MAGICFROG_DB):

内容 位置
SQLite 数据库 <data>/magicfrog.db(MAGICFROG_DB)
数据 / 状态 / 缓存 / 配置 <data>/xdg/{data,state,cache,config}
CLI 凭据 <data>/.magicfrog/credentials

字段加密密钥

MAGICFROG_FIELD_KEY 加密服务端仍需按精确值检索的个人数据:账号标识(邮箱或用户名)、登记设备名与计算机名。加密后登录与查找照常工作,而明文永不落库。

  • 每个部署单独生成一个:openssl rand -hex 32(64 个十六进制字符,32 字节)。
  • 与数据目录一起存放,不放进镜像:和其他 secret 在同一处 export,或经 MAGICFROG_FIELD_KEY_FILE 从你的 secret 存储挂载进来(两者都设置时直接值优先)。
  • **密钥缺失、为空、不是 32 字节或文件不可读时,启动失败。**服务端绝不回落成明文存储这些列。这个失败即关闭(fail-closed)的行为是刻意的。
  • **密钥丢失,被加密的列无法恢复。**请随数据目录一起备份。
  • **轮换密钥需要对存量数据重新加密。**迁移完成之前保留旧密钥可用;用错误的密钥启动会直接失败,不会给出误导性结果。

数据如何加密存储

没有任何一类敏感值以明文落库:

  • 账号密码、会话 token、设备 token 与配对码:只存单向哈希,无法还原原文。
  • 账号标识、登记设备名与计算机名:用 MAGICFROG_FIELD_KEY 加密存储(登录与查找照常工作)。

客户端本地的设备凭据文件(~/.magicfrog/credentials/device.json)受 0600 文件权限保护。审计记录与日志永不携带明文凭据或密钥。


Docker Compose(可选路径)

Compose 把同一个服务端跑成容器:单个 magicfrog 服务,背后是 Docker 命名卷上的 SQLite 数据库。镜像来自 GHCR 发布面 ghcr.io/gsc-org/magicfrog:<version>——GHCR 上的镜像发布目前不在现行发布面内,将另行公告;在此之前请使用单文件服务端。持久化与备份是卷操作:用 docker volume inspect magicfrog_magicfrog-data 找到数据在服务器上的位置。docker compose down 保留卷;down -v 删除卷。

Compose 首启导出与单文件相同的变量外加一个版本标签,然后启动栈:

export MAGICFROG_VERSION=<published-version>            # a real GHCR release tag
export MAGICFROG_PASSWORD='<server-api-password>'
export MAGICFROG_ADMIN_IDENTIFIER='admin@example.com'
export MAGICFROG_ADMIN_PASSWORD='<initial-admin-password>'
export MAGICFROG_FIELD_KEY='<64-hex-chars>'
docker compose up -d
docker compose logs -f magicfrog

五个变量全部必填:Compose 对它们做严格插值,缺任何一个就报错退出,所以这个栈绝不会带着空凭据启动。端口默认 4096;用 MAGICFROG_PORT 覆盖主机端口映射。容器内部,所有可变状态都位于 /data 之下(映射到命名卷)。


下载与校验

已发布产物(magicfrog 客户端与单文件 magicfrog-server)从官方下载源分发。每个产物都附带 sha256 与 size 元数据;任何不一致都会拒绝安装,没有「照样安装但警告」的降级路径。


未签名产物

Windows 与 macOS 产物当前不做代码签名。SmartScreen 与 Gatekeeper 的「未知开发者」提示是操作系统行为,不是产品故障;选择「仍要运行」即可。


客户端发现

桌面或 web 客户端面对自部署启动时,显式解析服务端。未配置服务端时,它呈现未配置状态并提供服务端地址输入框,而不是静默继续。显式输入的服务端地址恒胜过自动发现。

管理控制台(/admin 管理面)需要在 console 构建时把 VITE_ADMIN_CONTROL_PLANE_URL 设为控制面源。变量未设置时,admin 登录门报告缺失配置,而不是把请求瞄准猜出来的源。console 与控制面不同源时,在服务端用 magicfrog serve --cors <origin> 放行 console 的源。


故障排查

症状 原因 / 处置
服务端启动失败,报告缺少必需变量 MAGICFROG_PASSWORD / MAGICFROG_ADMIN_IDENTIFIER / MAGICFROG_ADMIN_PASSWORD / MAGICFROG_FIELD_KEY 之一未设置;见「必需环境变量」
首启日志报告 MAGICFROG_ADMIN_IDENTIFIER 与 MAGICFROG_ADMIN_PASSWORD 必须一起注入 两个 admin 变量只给了一个;成对注入
启动在字段加密密钥上失败 MAGICFROG_FIELD_KEY 缺失、为空或非法——用 openssl rand -hex 32 生成一个;见「字段加密密钥」
业务端点返回 403 password_change_required 强制改密尚未完成;见「强制改密」
docker compose up 报 set MAGICFROG_VERSION … 某个必需变量未导出;见「Docker Compose」

| 创建云电脑返回 503,日志涉及 iptables 与 Permission denied | 服务器以非 root 用户运行,网络隔离规则装不上。要么以 root 运行,要么为 iptables 配置免密 sudo 并设置 MAGICFROG_POOL_HOST_COMMAND_PREFIX="sudo -n"。请求失败即关闭——修复后重试是安全的 |