使用 Docker Compose 在 VPS 上自托管 Plausible Analytics
使用 Docker Compose 在 VPS 上部署 Plausible 社区版。完整指南涵盖安装、跟踪脚本集成、自定义事件、备份和更新。
Plausible Analytics 提供无 cookie、不收集个人数据、无需同意横幅的网站分析。自托管社区版意味着访客数据永远不会离开你的服务器。本指南涵盖完整生命周期:使用 Docker Compose 部署 Plausible CE v3.2.0、集成跟踪脚本、设置自定义事件、备份和更新。
前提条件: 一台至少 4 GB 内存的 VPS,运行 Docker 和 Docker Compose VPS上的Docker生产环境:会出什么问题以及如何解决,一个指向服务器的域名,以及一个处理 TLS 的反向代理 Traefik vs Caddy vs Nginx:Docker反向代理对比。
Plausible 社区版是什么?与云版本有何不同?
Plausible CE 是 Plausible Analytics 的免费、AGPL 许可、自托管版本。它以三个 Docker 容器运行:Plausible Web 应用(Elixir)、PostgreSQL(用户账户)和 ClickHouse(分析事件存储)。你可以获得与付费云版本相同的隐私优先仪表板。数据保留在你的服务器上。CE 每年发布两次长期支持版本。
两者的区别:
| 功能 | 云版本 | 社区版 |
|---|---|---|
| 核心分析仪表板 | 是 | 是 |
| 隐私优先(无 cookie) | 是 | 是 |
| 自定义事件和目标 | 是 | 是 |
| Stats API (v2) | 是 | 是 |
| 邮件报告 | 是 | 是(需要 SMTP) |
| 漏斗和收入目标 | 是 | 否 |
| Sites API | 是 | 否 |
| Looker Studio 连接器 | 是 | 否 |
| Google Search Console 集成 | 是 | 是(需要配置) |
| SSO / 团队管理 | 是 | 否 |
| 高级支持 | 是 | 仅社区 |
| 更新频率 | 每周 | 每年两次 |
| 基础设施管理 | 托管 | 自行管理 |
云版本采用订阅模式。访问 Plausible 定价页面查看当前费率。自托管只需支付 VPS 资源费用。
自托管 Plausible 的系统要求是什么?
ClickHouse 是最消耗资源的组件。空闲时至少需要 2 GB 内存,在对大数据集执行复杂查询时消耗更多。CPU 必须支持 SSE 4.2 指令(所有现代 x86_64 处理器都支持;ARM64 的 NEON 也可以)。请据此规划你的 VPS。
| 资源 | 最低要求 | 推荐 |
|---|---|---|
| 内存 | 2 GB | 4 GB |
| CPU | 1 vCPU (SSE 4.2) | 2 vCPU |
| 磁盘 | 10 GB | 20 GB+ |
| Docker | 20.10+ | 最新稳定版 |
| Docker Compose | v2.x | 最新稳定版 |
磁盘增长取决于流量。ClickHouse 中每 100-200 万页面浏览量大约占用 1 GB。低流量情况下(每月不到 10 万页面浏览量),磁盘使用可以忽略不计。
如何使用 Docker Compose 安装 Plausible Analytics?
克隆官方社区版仓库的 v3.2.0 标签,配置环境变量,启动容器。整个过程大约五分钟。
克隆仓库:
git clone -b v3.2.0 --single-branch https://github.com/plausible/community-edition plausible-ce
cd plausible-ce
这会给你 compose.yml、ClickHouse 配置文件和一个 README。
如何配置环境变量?
在 plausible-ce 目录中创建 .env 文件。两个变量是必需的。其余是可选的,但有些强烈建议配置。
首先生成密钥:
openssl rand -base64 48
输出一个 64 字符的字符串。复制它用于 SECRET_KEY_BASE。
为 TOTP 加密生成一个单独的密钥:
openssl rand -base64 32
现在创建 .env 文件:
cat > .env << 'EOF'
BASE_URL=https://plausible.example.com
SECRET_KEY_BASE=<your-64-char-secret>
TOTP_VAULT_KEY=<your-32-char-key>
DISABLE_REGISTRATION=invite_only
# SMTP for email reports and password resets
MAILER_EMAIL=plausible@example.com
SMTP_HOST_ADDR=mail.example.com
SMTP_HOST_PORT=587
SMTP_USER_NAME=plausible@example.com
SMTP_USER_PWD=<your-smtp-password>
SMTP_HOST_SSL_ENABLED=false
EOF
锁定文件权限,因为其中包含密钥:
chmod 600 .env
ls -la .env
-rw------- 1 root root 412 Mar 20 10:00 .env
各变量的作用:
- BASE_URL:Plausible 可访问的公共 URL。必须与反向代理配置匹配。
- SECRET_KEY_BASE:加密会话并生成派生密钥。最少 64 字节。绝不要分享。
- TOTP_VAULT_KEY:使用 AES256-GCM 加密双因素认证密钥。如果省略,将通过 PBKDF2 从
SECRET_KEY_BASE派生,但显式设置更有利于密钥轮换。 - DISABLE_REGISTRATION:设为
invite_only(默认)或在创建账户后设为true。防止陌生人在你的实例上注册。 - SMTP 变量:邮件报告、密码重置和邀请邮件所需。没有 SMTP,Plausible 仍可工作,但邮件功能将被禁用。
如何为 Plausible 配置带 TLS 的反向代理?
Plausible 默认监听 8000 端口。反向代理将 HTTPS 流量转发到该端口。如果你已经运行了 Caddy 或 Traefik Traefik vs Caddy vs Nginx:Docker反向代理对比,将 Plausible 添加为新的上游。
创建 compose.override.yml 将 Plausible 连接到反向代理网络:
services:
plausible:
networks:
- proxy
- default
networks:
proxy:
external: true
如果使用 Caddy,在 Caddyfile 中添加:
plausible.example.com {
reverse_proxy plausible:8000
}
如果使用 Traefik,在 override 中添加标签:
services:
plausible:
labels:
- "traefik.enable=true"
- "traefik.http.routers.plausible.rule=Host(`plausible.example.com`)"
- "traefik.http.routers.plausible.tls.certresolver=letsencrypt"
- "traefik.http.services.plausible.loadbalancer.server.port=8000"
networks:
- proxy
- default
networks:
proxy:
external: true
另外,Plausible 内置了 Let's Encrypt 支持。在 .env 文件中设置 HTTP_PORT=80 和 HTTPS_PORT=443,然后在 override 中暴露这些端口:
services:
plausible:
ports:
- 80:80
- 443:443
这种方式更简单,但意味着 Plausible 自行管理 TLS,如果其他服务共享同一服务器可能会产生冲突。
启动容器
docker compose up -d
三个容器启动:plausible_db(PostgreSQL 16)、plausible_events_db(ClickHouse 24.12)和 plausible(Web 应用)。Plausible 容器在启动时自动运行数据库迁移。
检查三个容器是否健康:
docker compose ps
NAME IMAGE STATUS
plausible ghcr.io/plausible/community-edition:v3.2.0 Up 30s (healthy)
plausible_db postgres:16-alpine Up 35s (healthy)
plausible_events_db clickhouse/clickhouse-server:24.12-alpine Up 35s (healthy)
三个都应显示 (healthy)。如果 ClickHouse 显示 (health: starting),再等一分钟。它通过 wget 对 HTTP 接口执行健康检查。
创建管理员账户
在浏览器中打开 https://plausible.example.com。你会看到注册表单。创建你的账户。设置 DISABLE_REGISTRATION=invite_only 后,新用户只能在你从仪表板明确邀请后才能注册。
注册后,如果你是唯一用户,可以完全锁定注册:
编辑 .env 并更改:
DISABLE_REGISTRATION=true
然后重启:
docker compose up -d
如何将 Plausible 跟踪脚本添加到你的网站?
登录后,点击"Add a website"并输入你的域名。Plausible 会生成一个跟踪代码片段。默认的 script 标签如下:
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.js"></script>
将 plausible.example.com 替换为你的 Plausible 实例的实际 URL。将此标签添加到每个需要跟踪的页面的 <head> 中。
如何将 Plausible 添加到静态 HTML 网站?
将 script 标签直接粘贴到 HTML 的 <head> 中:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Site</title>
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.js"></script>
</head>
<body>
<!-- content -->
</body>
</html>
对于静态网站生成器(Hugo、Jekyll、11ty),将 script 标签添加到基础模板或 head partial 中。
如何将 Plausible 添加到 WordPress 网站?
官方 Plausible Analytics WordPress 插件(v2.5.4,10,000+ 活跃安装)通过 WordPress 后台处理所有配置。
- 安装插件:插件 > 安装新插件 > 搜索"Plausible Analytics"
- 进入 设置 > Plausible Analytics
- 输入自托管实例的域名 URL(例如
https://plausible.example.com) - 输入要跟踪的域名
- 保存
插件自动注入跟踪脚本。它还支持 WooCommerce 转化跟踪和 Contact Form 7、WPForms、Ninja Forms 的自动表单提交跟踪。
如何将 Plausible 添加到 Next.js 应用?
使用 next-plausible 包(v3.12.5,每周 36,000 次下载)。
npm i next-plausible
对于 App Router(Next.js 13+),在根 layout 中添加 provider:
import PlausibleProvider from "next-plausible";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<head>
<PlausibleProvider
domain="yoursite.com"
customDomain="https://plausible.example.com"
selfHosted
/>
</head>
<body>{children}</body>
</html>
);
}
要在组件中跟踪自定义事件,使用 usePlausible hook:
"use client";
import { usePlausible } from "next-plausible";
export default function SignupButton() {
const plausible = usePlausible();
return (
<button onClick={() => plausible("Signup")}>
Sign up
</button>
);
}
如何将 Plausible 添加到单页应用?
对于 React、Vue、Svelte 或任何 SPA,将 script 标签添加到 index.html。Plausible 通过 History API 自动跟踪路由变化。无需额外配置。
如果你的 SPA 使用基于 hash 的路由(/#/path),使用 hash 扩展:
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.hash.js"></script>
如何在 Plausible 中跟踪自定义事件和目标?
自定义事件可以跟踪页面浏览之外的操作:按钮点击、表单提交、文件下载、注册。Plausible 提供两种方法:无代码的 CSS 类方法和用于动态跟踪的 JavaScript API。
首先,启用支持自定义事件的增强脚本。替换默认脚本源:
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.tagged-events.js"></script>
CSS 类方法(无需 JavaScript)
以 plausible-event-name=EventName 格式向任何 HTML 元素添加 CSS 类:
<a href="/signup" class="plausible-event-name=Signup">Create Account</a>
<button class="plausible-event-name=Download+PDF">Download Report</button>
<form class="plausible-event-name=Contact+Form+Submit">
<!-- form fields -->
</form>
事件名中的空格用 + 表示。某些 CMS(Webflow)会将 = 替换为 -。这种情况下使用双连字符 --:plausible-event-name--Signup。
JavaScript API 用于动态事件
对于需要条件逻辑或动态属性的事件,直接调用 plausible() 函数:
// Simple event
plausible("Signup");
// Event with custom properties
plausible("Download", {
props: { format: "PDF", document: "annual-report" }
});
// Event with a callback (useful for redirects)
plausible("Outbound Link", {
props: { url: "https://example.com" },
callback: () => { window.location = "https://example.com"; }
});
在仪表板中创建目标
事件在创建匹配目标之前不会出现在仪表板中。进入 Site Settings > Goals > Add Goal。选择"Custom event"并输入准确的事件名称(例如 Signup)。名称区分大小写,必须与代码匹配。
如何使用 Plausible Stats API?
Plausible 包含 Stats API (v2),用于以编程方式访问分析数据。在自托管实例上,API 基础 URL 为 https://plausible.example.com/api/v2/query。
创建 API 密钥:进入 Account Settings > API Keys > New API Key > Stats API。
查询过去 7 天的访客数量:
curl --request POST \
--header 'Authorization: Bearer YOUR-API-KEY' \
--header 'Content-Type: application/json' \
--url 'https://plausible.example.com/api/v2/query' \
--data '{
"site_id": "yoursite.com",
"metrics": ["visitors", "pageviews", "bounce_rate"],
"date_range": "7d"
}'
{
"results": [
{
"metrics": [1423, 3847, 42],
"dimensions": []
}
],
"query": {
"site_id": "yoursite.com",
"metrics": ["visitors", "pageviews", "bounce_rate"],
"date_range": ["2026-03-13", "2026-03-20"]
}
}
按页面细分访客:
curl --request POST \
--header 'Authorization: Bearer YOUR-API-KEY' \
--header 'Content-Type: application/json' \
--url 'https://www.example.com/api/v2/query' \
--data '{
"site_id": "yoursite.com",
"metrics": ["visitors", "pageviews"],
"date_range": "30d",
"dimensions": ["event:page"],
"pagination": {"limit": 5}
}'
API 支持过滤、时间维度(time:day、time:month)和排序。速率限制为每小时 600 次请求。完整的 Stats API 参考文档包含所有可用指标和维度。
如何设置邮件报告?
邮件报告需要在 .env 文件中配置可用的 SMTP(上面的环境设置部分已介绍)。SMTP 配置完成后,任何用户都可以从 Plausible 仪表板启用每周或每月邮件报告。
进入 Site Settings > Email Reports。添加收件人地址。Plausible 按你选择的频率发送访客、热门页面和流量来源的摘要。
如果邮件未送达,检查 Plausible 容器日志:
docker compose logs plausible | grep -i mail
常见问题:SMTP 端口错误(STARTTLS 使用 587,隐式 TLS 使用 465 并设置 SMTP_HOST_SSL_ENABLED=true),或认证失败。
如何备份自托管的 Plausible 实例?
Plausible 将数据存储在两个数据库和一个卷中。丢失其中任何一个都意味着数据丢失。三个都要备份。
| 数据 | 存储 | 备份方法 |
|---|---|---|
| 用户账户、站点配置 | PostgreSQL | pg_dump |
| 分析事件 | ClickHouse | 卷备份或 BACKUP 命令 |
| 证书、上传文件 | plausible-data 卷 |
卷复制 |
备份 PostgreSQL
docker compose exec plausible_db pg_dump -U postgres plausible_db | gzip > backup-postgres-$(date +%F).sql.gz
备份 ClickHouse
ClickHouse 24.12 原生支持 BACKUP 命令。在容器内执行:
docker compose exec plausible_events_db clickhouse-client \
--query "BACKUP DATABASE plausible_events_db TO Disk('backups', 'plausible-$(date +%F).zip')"
如果 backups 磁盘未配置,使用卷级别备份:
docker compose stop plausible_events_db
docker run --rm \
-v plausible-ce_event-data:/source:ro \
-v $(pwd)/backups:/backup \
alpine tar czf /backup/clickhouse-$(date +%F).tar.gz -C /source .
docker compose start plausible_events_db
这会短暂停止 ClickHouse。如需零停机备份,在 ClickHouse 中配置 backups 磁盘或使用 clickhouse-backup。
自动化备份
创建脚本 /opt/plausible-backup.sh:
#!/bin/bash
set -euo pipefail
BACKUP_DIR=/opt/backups/plausible
mkdir -p "$BACKUP_DIR"
cd /opt/plausible-ce
# PostgreSQL
docker compose exec -T plausible_db pg_dump -U postgres plausible_db \
| gzip > "$BACKUP_DIR/postgres-$(date +%F).sql.gz"
# ClickHouse volume
docker run --rm \
-v plausible-ce_event-data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/clickhouse-$(date +%F).tar.gz" -C /source .
# Plausible data volume
docker run --rm \
-v plausible-ce_plausible-data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/plausible-data-$(date +%F).tar.gz" -C /source .
# Rotate: keep 14 days
find "$BACKUP_DIR" -name "*.gz" -mtime +14 -delete
echo "Backup complete: $(ls -lh $BACKUP_DIR/*$(date +%F)*)"
chmod 700 /opt/plausible-backup.sh
使用 cron 安排每日执行:
crontab -e
添加:
0 3 * * * /opt/plausible-backup.sh >> /var/log/plausible-backup.log 2>&1
了解更多 Docker 卷备份策略,请参阅 在VPS上备份和恢复Docker卷。
如何安全更新 Plausible 社区版?
Plausible CE 每年发布两次。在 compose.yml 中将版本固定到特定标签以获得可预测的升级。默认配置已固定到 v3.2.0。
版本固定策略:
| 级别 | 标签示例 | 自动更新内容 |
|---|---|---|
| 补丁(最安全) | v3.2.0 |
无。仅手动升级。 |
| 次要版本 | v3.2 |
补丁版本(错误修复) |
| 主要版本 | v3 |
次要和补丁版本 |
建议:固定到补丁级别,阅读发布说明后手动更新。
升级步骤
-
阅读发布说明了解破坏性变更
-
备份数据库(运行上面的备份脚本)
-
拉取新版本:
cd /opt/plausible-ce
git fetch --tags
git checkout v3.3.0 # replace with the target version
- 启动更新后的容器:
docker compose up -d
Plausible 在启动时自动运行数据库迁移。首次启动时关注日志:
docker compose logs -f plausible
在输出中寻找 [info] Migrations up to XXXXXXXX applied successfully。如果看到迁移错误,不要丢弃旧数据。查看升级 wiki 页面获取版本特定说明。
- 清理旧镜像:
docker image prune -f
安全补丁不会回移植到旧版本。在 GitHub 上订阅发布通知:进入仓库,点击 Watch > Custom > Releases。
自托管 Plausible 不使用 cookie 是否符合 GDPR?
是的。Plausible 不设置 cookie。不收集或存储个人数据。唯一访客通过访客 IP 地址与 User-Agent 字符串的哈希值计数。该哈希每 24 小时轮换一次,且从不以原始形式存储。原始 IP 地址在哈希后即被丢弃。
这意味着:
- 无需 GDPR、CCPA 或 PECR 下的 cookie 同意横幅
- 无个人数据处理,因此 GDPR 第六条的合法性基础要求不适用
- 自托管意味着数据永远不会离开你的服务器,也不会传输给第三方处理者
- 你是唯一的数据控制者,无需为分析签订数据处理协议
如果你的 VPS 托管在欧盟(Virtua Cloud 服务器位于欧洲数据中心),你的分析数据留在欧盟境内。无 Schrems II 传输问题。
这就是许多独立开发者和注重隐私的开发者放弃 Google Analytics 的原因。没有同意横幅,没有访客摩擦,没有数据处理协议需要管理。
监控 ClickHouse 资源使用
ClickHouse 是最消耗资源的组件。低流量空闲时使用约 500 MB 内存。查询大数据集时可能飙升到 2-3 GB。如果你的 VPS 总共只有 2 GB 内存,繁忙时可能出现 OOM kill。
监控内存使用:
docker stats plausible_events_db --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM %
a1b2c3d4e5f6 plausible_events_db 0.50% 487MiB / 3.84GiB 12.38%
Plausible CE 附带的 ClickHouse 配置已包含低资源覆盖(通过 low-resources.xml 和 default-profile-low-resources-overrides.xml)。这些限制了合并和查询的内存使用。
如果需要进一步调优,创建 clickhouse/custom.xml 覆盖文件并在 compose.override.yml 中挂载。关于 Docker Compose 中的资源限制,请参阅 Docker Compose资源限制、健康检查与重启策略。
检查 ClickHouse 日志中的警告:
docker compose logs plausible_events_db | grep -i "memory\|oom"
出了问题?
容器无法启动: 检查 docker compose logs <service>。常见原因:端口冲突、缺少 .env 变量、ClickHouse 在旧 CPU 上未通过 SSE 4.2 检查。
登录页面出现"Bad Request": 你的 BASE_URL 与访问的 URL 不匹配。Plausible 检查 origin 头与 BASE_URL 是否一致以防止跨站请求伪造。
跟踪脚本未记录访问: 打开浏览器开发者工具,在网络标签中检查发往 /api/event 的请求。202 响应表示事件已被接受。如果看到 CORS 错误,说明反向代理剥离了请求头。确保代理传递 Host 头。
邮件报告未发送: 验证 SMTP 凭据。用 docker compose logs plausible | grep -i smtp 检查日志。用 swaks 或 openssl s_client 独立测试 SMTP 服务器。
ClickHouse 被 OOM killer 终止: VPS 内存不足。升级到至少 4 GB,或在 ClickHouse 配置覆盖中降低 max_memory_usage。
安装后仪表板显示零访客: 跟踪脚本可能被广告拦截器阻止。考虑通过主域名代理脚本。Plausible 文档将此称为 proxy setup。
要监控 Plausible 实例的可用性,请参阅 使用Docker Compose在VPS上自建Uptime Kuma和Beszel。