字节笔记本
2026年6月21日
Single Server:一台 Linux 服务器运行所有应用,5 秒内完成部署
本文介绍 Single Server,一个开源的单服务器部署方案。它把 Cloudflare、Tailscale、Docker、Kamal 和 GitHub 串联起来,让个人开发者或小型团队能在一台 Linux 机器上托管所有应用,并把每次 git push 的上线时间压缩到 5 秒以内。
项目简介
Single Server 是由 Daniel Vassallo 等人开源的项目,仓库地址为 dvassallo/singleserver。项目的核心理念是"一台 Linux 服务器可以运行你所有曾经发布过的应用",通过统一的 CLI 和部署守护进程管理所有服务,不再需要为每个应用单独配置构建队列、账单或一堆 YAML 文件。
截至目前,该项目在 GitHub 上已获得 163 stars,主要使用 Go(约 70.5%)编写,辅助以 Shell 和 HTML/CSS。
核心特性
- 单服务器托管所有应用:一台 Linux 机器即可承载多个项目,减少基础设施碎片化。
- Git push 即部署:配置完成后,推送到指定分支即可在数秒内自动上线。
- 无构建队列、无按应用计费:不依赖复杂的 CI/CD 平台或按项目付费的 PaaS。
- 集成 Cloudflare + Tailscale:自动处理公网入口和私有网络连接。
- 基于 Docker 和 Kamal:复用成熟的容器化部署工具,降低学习成本。
- 稳定与 edge 双通道:支持 SemVer 稳定版和最新 main 构建的 edge 通道。
工作原理
Single Server 并不是重新发明一套部署系统,而是把几个已有的成熟工具按特定方式粘合在一起,让"单服务器跑所有应用"这件事变得自动化。
单服务器架构
传统 PaaS 或 Kubernetes 的思路是把应用分散到多台机器上,由调度器决定每个容器跑在哪里。Single Server 反其道而行:所有应用都跑在同一台 Linux 服务器的 Docker 容器里,由 singleserverd 这个守护进程统一协调。
这样做的好处是架构简单、成本低。对于个人项目或小型团队来说,一台 4C8G 的云服务器往往足够承载多个低流量应用,没必要为了"可扩展性"提前引入复杂调度。
各组件角色
- GitHub:作为源码仓库和触发源。当你 push 到指定分支时,GitHub 通过 webhook 通知 Single Server。
- singleserverd:一个 Go 二进制文件,既是长期运行的部署守护进程,也是交互式 CLI。它监听 webhook、管理配置、执行部署。
- Docker:所有应用以容器形式运行,互相隔离,共享同一台宿主机的内核。
- Kamal:Basecamp 开源的容器部署工具,负责拉取镜像、启动容器、健康检查、零停机切换。Single Server 用 Kamal 处理实际的容器生命周期。
- Cloudflare:处理公网流量入口,包括 DNS、CDN、TLS 终止和 DDoS 防护。你的域名解析到这台服务器,Cloudflare 把请求转发过来。
- Tailscale:提供私有网络连接,让你可以通过安全的内网地址访问服务,而不必把所有端口都暴露到公网。
一次 git push 后发生了什么
- Webhook 触发:你执行
git push后,GitHub 向 singleserverd 发送 webhook 请求,通知仓库有更新。 - 拉取最新代码:singleserverd 收到通知后,在服务器上拉取仓库的最新提交。
- 构建 Docker 镜像:根据仓库里的
Dockerfile构建应用镜像。如果镜像已存在且层没有变化,Docker 会复用缓存。 - 运行测试:构建过程中会执行单元测试(Single Server 把
go test ./...或项目里的测试嵌入到构建流程)。 - 启动新容器:Kamal 基于新镜像启动一个容器,并检查健康状态。
- 零停机切换:新容器健康后,Kamal 把流量从旧容器切到新容器,然后停止旧容器。
- 清理旧镜像:保留最近的镜像版本,清理过期的中间层,释放磁盘空间。
整个过程在本地服务器上完成,不需要等待外部 CI 队列,因此能把部署时间控制在 5 秒以内。
零停机切换是怎么做到的
Kamal 使用一种"蓝绿部署"的简化版本:同一时间段内,旧版本容器和新版本容器同时存在。只有当新容器通过健康检查后,反向代理(通常是 Kamal 内置的 Traefik 或类似组件)才会把请求路由到新容器。旧容器在短暂保留后被停止,从而实现用户无感知的更新。
网络流量路径
对于公网访问:
用户请求 → Cloudflare(DNS + TLS)→ 服务器公网 IP → Traefik/Kamal 反向代理 → 目标应用容器
对于内部访问或管理:
你的设备 → Tailscale 内网 → 服务器 Tailscale IP → 目标应用容器
Tailscale 的作用是让开发者和一些不需要公网暴露的服务(如数据库、监控)通过私有网络通信,减少公网攻击面。
配置管理
Single Server 通过 config/apps.example.yml 类似的配置文件管理每个应用的参数,包括仓库地址、分支、环境变量、端口映射、域名等。singleserver add 命令本质上是把仓库注册到这个配置中,并生成对应的 Kamal 部署配置。
技术栈
- Go — CLI 与部署守护进程核心
- Docker — 应用容器化运行
- Kamal — 容器部署编排与零停机切换
- Cloudflare — 域名、TLS、CDN 与公网入口
- Tailscale — 私有网络连接
- GitHub — 源码仓库与 webhook 触发源
- Traefik(Kamal 默认)— 反向代理与流量路由
安装指南
前置要求
- 一台全新的 Linux 服务器
- 服务器的 root 访问权限
- 一个 GitHub 仓库
- 一个 Cloudflare 托管的域名(用于公网访问)
- 可选:Tailscale 账号(用于私有网络访问)
安装步骤
# SSH 登录服务器
ssh root@<server_ip>
# 运行交互式安装脚本
curl -fsSL https://singleserver.com/install.sh | sh安装脚本会自动配置 Docker、Tailscale 客户端、下载 singleserverd 二进制文件,并注册 systemd 服务。
安装完成后,singleserver 命令即可使用。
快速开始
# 添加一个 GitHub 仓库,后续该仓库指定分支的每次 push 都会自动部署
singleserver add https://github.com/you/your-app配置完成后,向该仓库推送代码,Single Server 会在 5 秒内完成部署。
使用示例
部署一个应用
# 添加应用
singleserver add https://github.com/you/your-app
# 手动触发部署
singleserver deploy your-app设置环境变量
singleserver add https://github.com/you/your-app --env DATABASE_URL=postgres://...切换到 edge 通道
# 全新安装时使用 edge
SINGLESERVER_CHANNEL=edge curl -fsSL https://singleserver.com/install.sh | sh
# 现有安装切换到 edge
singleserver upgrade --edge查看帮助
singleserver help构建与测试
项目本身使用 Go 1.26,开发时无需额外服务依赖:
# 构建
go build ./...
# 运行单元测试
go test ./...单元测试是纯 go test,不需要网络或构建标签,并且会在站点 Docker 构建中运行,确保有测试失败时不会把问题带到线上。
发布新版本
Single Server 使用 Git tag 触发发布流程:
git tag -a v0.2.0 -m "…"
git push origin v0.2.0.github/workflows/release.yml 会自动构建二进制文件,并发布带有校验和与说明的 GitHub Release。
注意事项
- Single Server 更适合个人项目或小型团队,重度的多租户、弹性伸缩场景可能不是它的目标。
- 安装脚本需要 root 权限,因为会配置 Docker、网络和其他系统级服务。
- 首次使用建议先在一台可丢弃的 VPS 上验证,熟悉流程后再用于生产环境。
- Cloudflare 和 Tailscale 的配置需要在安装前或安装过程中完成授权。
- End-to-end 测试需要 Docker Desktop 和 Tailscale、Cloudflare、GitHub 的测试凭证,详细配置见
test/e2e/README.md。