开源互联网操作系统 Puter:本地开发、Docker 与 Docker Compose 自托管部署指南
本文基于 Puter 仓库的官方说明文档与配套源码,完整讲解如何把 Puter 跑起来:从克隆仓库后的本地开发启动,到 Docker 单容器部署,再到 Docker Compose 全栈自托管。读完本文,你将掌握 Puter 的三种运行方式、各方式下的目录结构与端口约定,以及首次启动后需要关注的配置项与登录验证方法。
一、Puter 是什么:可自托管的"互联网电脑"
Puter 被定位为一个功能丰富、速度快、高度可扩展的开源互联网操作系统(Internet OS)。根据其 丹麦语 README(与 英文主 README 内容对应)的描述,Puter 的典型用途包括:
- 一个注重隐私的个人云空间,把文件、应用和游戏集中存放在一个安全的地方,随时随地访问;
- 一个构建并发布网站、Web 应用与游戏的平台;
- 具备清爽界面与强大功能、可替代 Dropbox / Google Drive / OneDrive 的方案;
- 面向服务器与工作站(workstation)的远程桌面环境;
- 一个帮助学习者理解 Web 开发、云计算与分布式系统的友好开源项目。
从仓库结构看,这一"全功能"定位是实至名归的:根目录下的 workspaces 覆盖 src/backend(Node.js 后端,含控制器、服务、存储层与数据库迁移)、src/gui(浏览器内桌面环境)、src/puter-js(开放给开发者应用的 SDK 运行时)、src/worker(Serverless Worker 沙箱)等,配套 docker-compose.yml、caddy/Caddyfile 与 config.template.jsonc 则构成了完整的自托管部署面。
二、本地开发快速上手
最轻量的体验方式是直接在源码树中运行。官方给出的步骤是:
git clone https://gitcode.com/GitHub_Trending/pu/puter
cd puter
npm install
npm start
启动成功后,Puter 会运行在 http://puter.localhost:4100(若端口被占用则顺延到下一个可用端口)。
npm start 背后并不是简单地 node server.js,而是由 tools/start.mjs 编排的一条构建-启动链,从源码结构看其流程为:
- 若未指定远程后端,先执行
npm run setupExtensions(运行 tools/extensionSetup.mjs,准备扩展模块); - 接着
npm run build:ts,即tsc -p tsconfig.build.json加 tools/write-dist-package-json.mjs 写出 dist 的 package.json; - 最后以
--enable-source-maps启动编译产物dist/src/backend/index.js,并通过-r dist/src/backend/telemetry.js预加载遥测模块。
也就是说,本地开发模式是"先全量编译 TypeScript,再运行自托管后端"的完整链路,这也是为什么系统要求中 Node.js 版本不能太低——它要承担整个后端的类型编译。
此外,start.mjs 还支持一个面向开发者的进阶用法:通过 --server=<域名或 origin> 参数跳过本地后端,只把 GUI 指向远程 Puter 后端,例如:
npm start --server=puter.com
此时实际调用的是 src/gui/dev-server.js 中的 GUI-only 模式。该文件里的注释说明了几个值得注意的细节:裸域名会自动按生产约定解析为 https://api.<域名>;dev-server 默认从 4000 端口开始尝试,最多尝试 10 个端口后改用任意空闲端口;登录时会跳转到远端 GUI 的 ?action=authme 授权流程,而非在本地页面直接提交密码(因为远端的 /login 只接受自己的源,防止任意页面用密码换会话令牌)。
三、Docker 单容器部署
如果只想快速跑一个 Puter 实例,官方 README 提供了一条 docker run 命令:
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v $(pwd)/puter/config:/etc/puter -v $(pwd)/puter/data:/var/puter ghcr.io/heyputer/puter
拆解这条命令,有三处与镜像内部约定直接相关:
- 两个挂载点:
./puter/config挂到容器内/etc/puter(配置文件目录),./puter/data挂到/var/puter(运行时持久数据)。这与 docker-compose.yml 中 puter 服务的卷映射(./puter/config:/etc/puter、./puter/data/puter:/var/puter)完全一致。 chown -R 1000:1000:不是可省略的仪式。Compose 文件中 puter 服务显式设置了PUID: 1000/PGID: 1000,容器内进程以 UID/GID 1000 运行;宿主机目录属主不匹配时,容器内无法写入挂载卷。- 端口
4100:这是 Puter 的默认内部监听端口。config.template.jsonc 中"port": 4100的注释即为"Port Puter listens on internally",Compose 健康检查也是探测容器内的http://localhost:4100/。
四、Docker Compose 全栈自托管
README 中的 Compose 流程假设你已拿到仓库里的 docker-compose.yml(Linux/macOS 用 wget 下载、Windows 用 PowerShell Invoke-WebRequest 下载,本仓库根目录已直接包含该文件,克隆后可直接使用):
Linux / macOS:
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
# 将仓库根目录的 docker-compose.yml 放到当前目录
docker compose up
Windows(PowerShell):
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
# 将仓库根目录的 docker-compose.yml 复制到当前目录
docker compose up
全栈架构:一个 Compose 文件拉起 7 个服务
当前仓库中的 docker-compose.yml 是一个完整生产形态的全栈编排,文件头注释明确写道它"拉起 Puter 及其所需的每一个外部服务":
| 容器 | 镜像 | 角色 |
|---|---|---|
puter-caddy |
caddy:2.11-alpine |
反向代理,监听 80(启用 TLS 后还有 443),把各 Host 转发给 Puter |
puter |
ghcr.io/heyputer/puter |
应用本体 |
puter-mariadb |
mariadb:11 |
SQL 数据库,首次启动时由 Puter 自动应用 schema |
puter-valkey |
valkey/valkey:8-alpine |
Redis 兼容缓存 / 限流后端 |
puter-dynamo |
amazon/dynamodb-local |
KV 存储,表在首次启动时自动创建 |
puter-s3 |
rustfs/rustfs |
S3 兼容对象存储(可替换为 MinIO) |
puter-s3-init |
amazon/aws-cli |
一次性容器,首次启动创建 bucket 后退出 |
几个从文件注释中可以确认的部署细节:
- Valkey 以单节点集群模式运行:Puter 的 ioredis 客户端只支持 Cluster 模式,因此 Compose 在首次启动时把全部 16384 个槽位分配给该节点(
CLUSTER ADDSLOTSRANGE 0 16383),后续启动检测到槽位已分配即跳过。 - 依赖顺序由 healthcheck 保证:puter 服务等待
valkey、mariadb健康、dynamo启动、s3-init成功完成后才启动,这正是docker compose up可能长时间停在 "waiting for service to be healthy" 的原因。 - S3 仅走内部网络:RustFS 不直接发布 9000 端口,浏览器侧的 S3 流量由 Caddy 通过
s3.<domain>子域路由进来,以保留 Host 头供 S3 签名校验。 - 可选的本地 LLM:
ollama/ollama-init两个服务藏在aiprofile 后面,需要docker compose --profile ai up -d显式启用,默认模型为tinyllama。
所有状态都落在 ./puter/data/<服务名>/ 下,备份这一个目录即可覆盖全部数据。更细的分步部署(.env 生成、config.json 完整示例、DNS 通配符、Let's Encrypt 通配证书、自定义反代规则、PostgreSQL/SMTP/OIDC 等扩展配置)参见仓库内的 doc/self-hosting.md。
首次启动与管理员登录
Compose 首次启动约需 30 秒(MariaDB 初始化 + 应用 schema + 默认应用)。观察日志:
docker compose logs -f puter
正常的启动日志应包含 [config] override from /etc/puter/config.json 以及 [mysql] running migrations ... 等行。管理员账号为 admin,临时密码只在首次启动时打印一次:
docker compose logs puter | grep tmp_password
登录后请在设置中修改该密码。
五、系统要求与运行环境
README 给出的系统要求如下:
| 项目 | 要求 |
|---|---|
| 操作系统 | Linux、macOS、Windows |
| 内存 | 2GB 最低(推荐 4GB) |
| 磁盘空间 | 1GB 可用空间 |
| Node.js | 16+(推荐 22+) |
| npm | 最新稳定版 |
需要注意一个适用前提:以上 Node 版本建议来自 README 的通用表述,而当前仓库根目录 package.json 的 engines 字段已声明 "node": ">=24.0.0"——即对本地开发与构建而言,以当前仓库实际要求为准,建议直接使用较新的 Node 版本(24+),Docker 方式则不受影响(镜像内置运行时)。
六、关键配置项速览
把 config.json 放入 ./puter/config/ 后,Puter 会覆盖默认配置(日志中的 [config] override from ... 即此行为)。完整键位清单见 config.template.jsonc,每个字段的源码级说明在 src/backend/types.ts。与自托管关系最密切的几个参数:
domain/static_hosting_domain/private_app_hosting_domain:Puter 完全基于 Host 头做子域路由——api.<domain>是 API,site.<domain>承载静态托管,app.<domain>承载私有应用。因此公网部署必须配置通配符 DNS(*.<domain>指向服务器),否则托管与 S3 子域无法解析。env:dev会打开浏览器、跳过受限邮箱检查并运行开发用 webpack watcher;prod直接服务预构建的静态包。自托管应使用prod(bundled 的config.default.json默认是dev,匹配源码树开发流程)。jwt_secret_v2/url_signature_secret:分别是签发校验 JWT(kid: v2)的 HMAC 密钥与 URL 签名密钥,任何公网部署都应替换为openssl rand -hex 64的随机值;旧版jwt_secret格式已退役。trust_proxy:反代跳数计数。Caddy 直连 Puter 时设为1;前面再加一层(如 Cloudflare)则为2;绝不能设为true(信任所有跳会导致X-Forwarded-For可伪造)。meteringEnforcement.subscriptions:自托管没有付费订阅体系,该开关默认场景下应关闭订阅校验,否则声明为付费计划专属的端点(如 OpenAI/Anthropic 兼容的 AI 接口)会对所有账号返回402 subscription_required。providers.ollama.enabled:Puter 默认会探测127.0.0.1:11434的本地 Ollama;未部署时应显式置false,否则每次启动都会刷ECONNREFUSED。
七、许可协议与社区支持
整个仓库(包括全部子项目、模块与组件)在未被显式另行声明的情况下均遵循 AGPL-3.0 许可(见 LICENSE.txt),第三方库可能各自受其许可证约束。
社区支持渠道(与丹麦语 README 一致):Bug 报告与功能建议请在仓库 Issue 区提交;社区讨论可通过 Discord、Reddit(r/puter)、X(@HeyPuter)、Mastodon 进行;安全相关问题请联系 security@puter.com,普通维护者邮件为 hi@puter.com。仓库还维护了 doc/i18n 下的 30+ 语言版 README,本文所依据的 README.da.md 即其中之一。
最后提示:本文所有命令均可在当前仓库只读状态下直接复现——npm install && npm start、docker run 单容器、docker compose up 全栈三条路径相互独立,可按环境任选其一;生产部署时请务必替换默认密码与密钥,并将 ./puter/data 纳入备份策略。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00