小型 VPS 自托管栈:2 GB 和 4 GB 内存能跑什么
在小型 VPS 上搭建一套务实的自托管入门栈:Docker Compose、Caddy、Vaultwarden、Uptime Kuma 和 Forgejo,附每项服务的内存预算、备份与安全基础。
简答:一台 2 GB 内存的 VPS 可以在 Docker Compose 下轻松运行由 Caddy(HTTPS 反向代理)、Vaultwarden(密码管理)、Uptime Kuma(监控)和 Forgejo(git)组成的自托管核心栈,内存占用约 0.6 到 1 GB。加上 Nextcloud 就需要 4 GB;如果改用 Syncthing 或 File Browser 等更轻量的工具,2 GB 仍然够用。
本指南提供一份可用的 Compose 文件、每项服务的内存预算,以及大多数自托管部署直到为时已晚才会想起的两件事:异地备份和收紧的网络暴露面。命令假定使用 Debian 12/13 或 Ubuntu 24.04,并已从 Docker 官方仓库安装 Docker Engine 和 Compose 插件。
每项服务的内存预算
表中数据为 1 到 5 名用户、在支持的情况下使用 SQLite 时,从空闲到轻度使用的典型常驻内存。升级、克隆大型 git 仓库或 Nextcloud 生成预览时峰值可能更高,因此请至少预留 20% 的余量,并添加 1 到 2 GB 的 swap 文件。
| 服务 | 作用 | 典型内存 | 说明 |
|---|---|---|---|
| 操作系统 + sshd + journald | 基础系统 | 150–250 MB | Debian 或 Ubuntu 最小安装 |
| Docker Engine + containerd | 容器运行时 | 80–120 MB | 使用容器的固定开销 |
| Caddy | 反向代理,自动 HTTPS | 20–50 MB | 单一二进制文件,无数据库 |
| Vaultwarden | 兼容 Bitwarden 的密码服务器 | 20–60 MB | Rust 编写,SQLite |
| Uptime Kuma | 可用性与证书监控 | 100–200 MB | Node.js;随监控项数量增长 |
| Forgejo | Git 托管、议题、CI 钩子 | 150–300 MB | Go 编写,小团队用 SQLite 即可 |
| Nextcloud + MariaDB + Redis | 文件、日历、通讯录 | 600 MB–1.2 GB | PHP-FPM 工作进程占大头 |
| Syncthing | 文件同步,无 Web 套件 | 50–150 MB | 更轻量的 Nextcloud 替代品 |
| File Browser | Web 文件管理器 | 20–40 MB | 通过 HTTPS 上传和分享文件 |
| Radicale | CalDAV 和 CardDAV | 30–50 MB | 无需 Nextcloud 的日历与通讯录 |
选择 VPS 规格
核心栈(Caddy、Vaultwarden、Uptime Kuma、Forgejo)加上基础系统约为 0.6 到 1 GB,2 vCPU / 2 GB 的服务器即可容纳,还有余量运行 Syncthing 和 Radicale。Nextcloud 加 MariaDB 和 Redis 会把总量推到约 1.5 到 2.2 GB,所以如果你想要完整套件外加其他所有服务,4 GB 才是现实的下限。磁盘同样重要:Forgejo 仓库和同步的文件会不断增长,而服务本身只需几 GB。
在 NoctisNode,Pulse 套餐(2 vCPU、2 GB 内存、40 GB NVMe,$10 / 28 天)可容纳核心栈,Umbra(4 vCPU、4 GB、60 GB NVMe,$15 / 28 天)可容纳核心栈加 Nextcloud。两者均为 KVM,提供完整 root 权限和独立 IPv4,可用门罗币或其他加密货币付款。本指南的内容不依赖于任何特定服务商。
Docker Compose 文件
只有 Caddy 发布 Web 端口;各应用只能通过 Compose 内部网络访问。Forgejo 还发布了 2222 端口用于 git over SSH,这样宿主机的 OpenSSH 可以保留在自己的端口上。在 `.env` 文件中把 `FORGEJO_TAG` 设为当前 Forgejo 主版本号,并将示例域名替换为你自己的 DNS 记录。
# /srv/stack/compose.yaml
services:
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy/data:/data
- ./caddy/config:/config
vaultwarden:
image: vaultwarden/server:latest
restart: unless-stopped
environment:
DOMAIN: "https://vault.example.com"
SIGNUPS_ALLOWED: "true" # set to "false" after creating your account
volumes:
- ./vaultwarden:/data
uptime-kuma:
image: louislam/uptime-kuma:2
restart: unless-stopped
volumes:
- ./uptime-kuma:/app/data
forgejo:
image: codeberg.org/forgejo/forgejo:${FORGEJO_TAG}
restart: unless-stopped
environment:
USER_UID: "1000"
USER_GID: "1000"
FORGEJO__service__DISABLE_REGISTRATION: "true"
volumes:
- ./forgejo:/data
ports:
- "2222:22"
# /srv/stack/Caddyfile
# vault.example.com {
# reverse_proxy vaultwarden:80
# }
# status.example.com {
# reverse_proxy uptime-kuma:3001
# }
# git.example.com {
# reverse_proxy forgejo:3000
# }启动服务
- 01.将 `vault`、`status` 和 `git` 的 A(及 AAAA)记录指向服务器 IP,以便 Caddy 首次启动时获取证书。
- 02.创建 `/srv/stack`,把 `compose.yaml`、`Caddyfile` 和 `.env` 放进去,然后运行 `docker compose up -d`。
- 03.打开 Forgejo 网址并完成安装向导;由于公开注册已关闭,你通过向导创建的第一个账户将成为管理员。
- 04.创建你的 Vaultwarden 账户,然后把 `SIGNUPS_ALLOWED` 设为 `"false"` 并再次运行 `docker compose up -d`。除非设置了经 Argon2 哈希的 `ADMIN_TOKEN`,否则保持管理面板禁用。
- 05.启动后立即创建 Uptime Kuma 管理员用户,因为在此之前任何人都能访问设置页面。
- 06.为每项服务和证书到期添加监控,最好从第二个位置监控,因为同一台服务器上的监控无法报告自身的故障。
Note · Caddy 会自动处理 HTTPS。关于请求头、速率限制和更复杂的路由,请参阅 Caddy 反向代理指南。
真正能恢复的备份
所有值得保留的数据都在 `/srv/stack` 下:SQLite 数据库、Forgejo 仓库、Caddy 证书和你的配置。不要指望服务商的快照;按照 restic 备份指南用 restic 保留一份你自己的加密异地副本。
在服务写入时复制的 SQLite 文件可能不一致。在小型服务器上最简单的安全做法,是在备份所需的一分钟内停止整个栈。如果你加了带 MariaDB 的 Nextcloud,请在运行 restic 之前用 `mariadb-dump` 导出数据库。至少测试一次恢复到临时目录;从未恢复过的备份只是一种猜测。
#!/bin/sh
# /usr/local/sbin/stack-backup (run nightly from cron or a systemd timer)
# needs RESTIC_REPOSITORY and RESTIC_PASSWORD_FILE in the environment
cd /srv/stack || exit 1
docker compose stop
rc=0
restic backup /srv/stack --tag stack || rc=$?
docker compose start
[ "$rc" -eq 0 ] || exit "$rc"
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune安全基础
- ▹SSH:仅限密钥登录,禁止 root 密码登录,可选使用非标准端口;参见 [SSH 加固指南](/guides/ssh-hardening)。
- ▹防火墙注意事项:Docker 发布的端口会绕过 `ufw` 规则,因为 Docker 会写入自己的 iptables/nftables 链。只发布必须公开的端口(80、443、2222),绝不发布数据库或管理端口。
- ▹更新:为宿主机启用 `unattended-upgrades`,并按你真正能坚持的计划运行 `docker compose pull && docker compose up -d`。
- ▹注册:在 Vaultwarden 和 Forgejo 中保持公开注册关闭;改为邀请用户。
- ▹磁盘加密:把 `/srv` 放在[加密根分区](/guides/luks-encrypted-root)上,这样被复制的磁盘镜像什么也不会泄露;在远程服务器上使用[通过 SSH 远程解锁 LUKS](/guides/luks-remote-unlock-ssh),并优先选择 [LUKS2 与 LUKS1 对比](/guides/luks2-vs-luks1)中介绍的 LUKS2 格式。
- ▹机密信息:`.env` 和 Vaultwarden 数据目录应仅限 root 读取(`chmod 600`/`700`)。
常见问题
Q自托管需要多少内存?
A由 Caddy、Vaultwarden、Uptime Kuma 和 Forgejo 组成的自托管核心栈,包括操作系统和 Docker 在内约占 0.6 到 1 GB,所以 2 GB 的 VPS 就够了。加上带 MariaDB 和 Redis 的 Nextcloud 后,4 GB 是实际的下限。
Q能在 2 GB VPS 上运行 Nextcloud 吗?
A能运行,但与其他服务并存时余量很少,在生成预览或同步高峰时会变慢。在 2 GB 上,Syncthing 加 File Browser 和 Radicale 只需一小部分内存就能覆盖文件、日历和通讯录。
Q自托管 Vaultwarden 安全吗?
AVaultwarden 只存储端到端加密的密码库数据,因此服务器被入侵并不会直接暴露明文密码。保持注册关闭,禁用管理面板或用哈希令牌保护,定期更新,并备份其数据目录。
Q自托管 Docker 栈用哪个反向代理最好?
A对于小型部署,Caddy 最省事,因为它只需几行配置就能自动获取并续期 HTTPS 证书。Nginx 和 Traefik 也可以,但需要更多配置。
Qufw 能保护 Docker 容器吗?
A默认不能。用 Docker 的 `ports:` 选项发布的端口会绕过 ufw,因为 Docker 会插入自己的防火墙规则,所以只发布应当公开的端口。