海外云服务器搭建 Umami 自建网站统计系统完整教程(2026最新版)

📅 · ChengziCloud - 一站式云端服务

Meta Description: 从零开始用海外云服务器搭建 Umami 自建网站统计分析系统,涵盖 Docker Compose 部署、PostgreSQL 数据库、Nginx 反向代理、Let's Encrypt SSL、广告拦截绕过与数据备份全流程,附服务器配置推荐与价格对比。

> 关键词:海外云服务器搭建 Umami、自建网站统计、Google Analytics 替代、Umami Docker 部署、隐私优先分析、Nginx 反向代理

前言:自建网站统计到底解决什么问题

如果你想让自己的博客或独立站知道"每天有多少人来看、从哪里来、用什么设备、看了哪几篇文章",同时又不愿意把这些访问数据交给第三方平台,那么用一台海外云服务器自建 Umami 是目前性价比最高的一条路。Umami 是一个隐私优先(privacy-first)的开源网站分析平台,用 Node.js 编写、数据完整落在你自己的 PostgreSQL 数据库里,页面里不写 Cookie、不做跨站追踪,因此也不需要弹 Cookie 同意横幅。

一句话回答:一台 1 核 1G 的海外云服务器 + Docker Compose,半小时内就能跑起一套属于你自己的网站统计系统,月成本不到 5 美元,却可以替代 Google Analytics 的核心功能。

> 🚀 还没有海外云服务器?通过 5.chengzicloud.cloud 选购阿里云/AWS/腾讯云国际版,享专属折扣和中文技术支持。

一、为什么要自建网站统计:四个不是"省钱"的理由

很多人第一反应是"Google Analytics 不是免费的吗,为什么要折腾"。免费是真的,但免费的东西往往在别的地方计价。下面四个理由,才是自建统计真正的价值所在。

1. 数据主权:原始访问日志留在你自己的硬盘上

第三方统计平台给你看到的永远是它愿意给你看的聚合报表。你拿不到原始事件,也就无法做二次分析、无法在平台改口径后回溯历史数据。自建 Umami 之后,每一条 pageview、每一个自定义事件都写进你自己服务器上的一个 PostgreSQL 表里,想导出 CSV、想接 BI、想写 SQL 做漏斗,随时都可以,而且导出按钮就在后台。

2. "免费"的代价:配额、政策与账号风险

商业分析平台的免费档都有事件量或数据保留期的天花板。一旦超过,要么升级付费、要么数据被截断。更麻烦的是政策型风险——平台调整免费额度、变更数据处理条款、甚至在你所在地区无法访问,这些都发生过。自建之后,这些变量跟你无关,你的历史数据不会因为某个平台改了策略就消失。

值得注意的是 Umami 官方自身也提供托管版 Umami Cloud,免费档是每月 10 万事件、1 个网站、6 个月数据保留;付费的 Pro 档为每月 20 美元、含 100 万事件、最多 20 个网站、2 年保留。用 20 美元/月的托管费对比一台 5 美元/月的 VPS,就是自建的经济账(下面第二节有完整对比表)。

3. 无 Cookie、无同意横幅,合规负担更轻

Umami 的设计前提就是"不采集可识别个人的数据":不设持久 Cookie、不生成跨站指纹、默认把 IP 匿名化处理。这意味着在多数以 GDPR 为参照的合规框架下,它通常不需要像 Google Analytics 那样在站点上强制弹 Cookie 同意横幅,也不用担心数据跨境传输的申报问题。对于做跨境独立站的用户,这一点省下的不只是开发时间,还有法务沟通成本。

4. 数据归集:多站点、多域名统一看板

Umami 可以在同一个后台里管理多个网站,每个网站分配到独立的 website-id。对同时运营博客、独立站、落地页的用户来说,好几种流量来源可以放在一套看板里横向比较,而不是在多个平台之间来回切账号。

需要诚实说明的边界

自建统计不是银弹,有两点必须提前说清楚:

- 它替代不了广告投放归因。Umami 不做跨站追踪,所以它无法像 Google Analytics 那样和 Google Ads、Facebook 广告后台做归因打通。如果你重度依赖付费投放的转化归因,自建统计只能作为补充,而不是唯一来源。 - 你要自己负责运维。数据库备份、镜像升级、磁盘告警,这些原本由托管平台承担的活,自建之后都在你自己肩上。本文第七节和安全加固一节会给出完整的自动化方案,但前提是你愿意维护一台服务器。

想清楚这两点之后,如果你要的是"我的流量数据我自己说了算",那 Umami 就是对的工具。

二、服务器配置推荐与价格对比

Umami 本身非常轻量,真正吃资源的是它背后的 PostgreSQL。选配置时的核心原则是:内存优先满足数据库,而不是 CPU 核数。统计类应用几乎没有并发峰值,2 核 1G 这种"CPU 够、内存不够"的配置反而最容易在 Postgres 内存不足时被杀进程,宁可牺牲一个核数也要把内存顶到 2G。

配置档位表

| 场景 | 推荐配置 | 月流量参考 | 说明 | |------|---------|-----------|------| | 个人博客/尝鲜 | 1 核 1G + 20G SSD | 每月 5 万 pageview 以内 | 必须加 2G swap,否则 Postgres 容易 OOM | | 单站正式使用(推荐) | 1 核 2G + 40G SSD | 每月 30 万 pageview 以内 | 内存够用,跑得稳,性价比最高 | | 多站/小团队 | 2 核 4G + 60G SSD | 每月 100 万 pageview 以内 | 可加 Redis 缓存,多站共用一套 | | 高流量/实时看板 | 4 核 8G + 100G SSD | 每月 500 万 pageview 以上 | 建议单独部署数据库,应用与 DB 分离 |

> 💡 结论就一句:预算有限时选 1 核 2G,不要选 2 核 1G。统计应用的瓶颈在数据库内存,不在 CPU。

服务商价格表

| 服务商 | 月付 | 年付(折扣后) | 数据中心 | 优点 | |--------|------|--------------|---------|------| | 阿里云国际版 ECS | $4.2 | $3.2/月 | 新加坡/香港/硅谷 | 中文面板、支持支付宝 | | AWS Lightsail | $3.5 | $3.5/月 | 全球 20+ 区域 | 新用户免费套餐、生态完善 | | 腾讯云国际版 CVM | $4.5 | $3.5/月 | 香港/新加坡/东京 | 低延迟到国内、微信支付 | | Vultr | $6.0 | $6.0/月 | 全球 32 个 | 按小时计费、随时销毁 | | DigitalOcean | $6.0 | $6.0/月 | 全球 14 个 | 文档最完善、社区教程多 |

> 🚀 通过 5.chengzicloud.cloud 购买以上平台均有额外折扣,点击首页查看最新优惠。

自建 vs 托管 vs 商业平台:四方案对比

| 维度 | 自建 Umami | Umami Cloud | Google Analytics | 自建 Plausible | |------|-----------|-------------|------------------|----------------| | 起步成本 | VPS 约 $3.5~6/月 | 免费档 | 免费 | VPS 约 $3.5~6/月 | | 超过免费额度的成本 | 加配置即可 | Pro $20/月含 100 万事件 | 免费但功能阉割 | 同自建 Umami | | 数据归属 | 自己的数据库 | 平台 | 平台 | 自己的数据库 | | 需要 Cookie 横幅 | 不需要 | 不需要 | 通常需要 | 不需要 | | 事件量天花板 | 取决于服务器 | 10 万/月(免费档) | 有采样上限 | 取决于服务器 | | 是否可二手迁移 | 数据库可整体导出 | 支持导出 | 导出受限 | 数据库可导出 | | 运维负担 | 自己维护 | 无 | 无 | 自己维护 |

一句话结论:长期跑、多站点、看重数据所有权选自建 Umami;只想临时看个大概选 Umami Cloud 免费档;重度投放归因还是得配一套 Google Analytics 做补充。

> 声明:本文价格数据采集于 2026 年 9 月,仅为公开官网参考区间。云厂商不定期调整刊例价与活动折扣,下单前请以各厂商控制台结算页的实时价格为准。除特别标注外,金额单位均为美元(USD)。

三、八步部署完整教程

下面用 Ubuntu 22.04CentOS 7 双系统给出全部命令。凡是两套系统有差异的地方都会分别标注,直接复制对应系统的命令执行即可。整套流程基于官方发布的 Docker 镜像,不写死任何版本号,长期有效。

第一步:系统初始化

先用 root 登录服务器,做基础加固与内存补充。1 核 1G 的机器务必要加 swap,否则 Postgres 在导入数据或重建索引时很容易被系统 OOM Killer 杀掉。

创建 2G 的 swap 文件(两套系统通用):

`bash fallocate -l 2G /swapfile || dd if=/dev/zero of=/swapfile bs=1M count=2048 chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo '/swapfile none swap sw 0 0' >> /etc/fstab free -h `

Ubuntu 22.04 更新系统并配置防火墙,只放行 SSH 与 Web 端口,Umami 的 3000 端口绝不对外开放:

`bash apt update && apt upgrade -y apt install -y curl ca-certificates ufw ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp ufw --force enable `

CentOS 7 对应命令(注意 CentOS 7 已 EOL,仓库需要指向 vault 才能正常安装):

`bash yum install -y epel-release sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/CentOS-*.repo sed -i 's|^#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*.repo yum install -y curl firewalld systemctl enable --now firewalld firewall-cmd --permanent --add-service=ssh firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload `

两条提醒:一是云厂商的安全组也要同步放开 22/80/443,只在服务器内配置防火墙是不够的;二是 3000 端口不要在任何地方放行,Umami 只允许通过 Nginx 反代访问。

第二步:安装 Docker 与 Compose v2

Ubuntu 22.04 用官方脚本一次装好:

`bash curl -fsSL https://get.docker.com | sh systemctl enable --now docker docker compose version `

CentOS 7 同样可以用官方脚本装 Docker,但Compose v2 插件不会一起装上,需要手动补一个二进制到插件目录(这也是 CentOS 上装 Docker 最常见的坑):

`bash curl -fsSL https://get.docker.com | sh systemctl enable --now docker mkdir -p /usr/local/lib/docker/cli-plugins curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 \ -o /usr/local/lib/docker/cli-plugins/docker-compose chmod +x /usr/local/lib/docker/cli-plugins/docker-compose docker compose version `

如果你用的是甲骨文永久免费 ARM 实例或树莓派,把上面下载链接里的 linux-x86_64 换成 linux-aarch64 即可。装完后确认 docker compose version(不是老的 docker-compose)能输出 v2.x 版本号——Umami 官方 compose 文件使用 docker compose 子命令写法,v1 的旧命令不兼容。

> 🚀 部署过程中卡在环境问题?通过 5.chengzicloud.cloud 可申请中文技术支持协助初始化服务器。

第三步:编写 docker-compose.yml

为 Umami 建立独立目录,并生成两个密钥。APP_SECRET 用于签名登录令牌,TWO_FACTOR_ENCRYPTION_KEY 用于加密两步验证密钥(想启用 2FA 就必须先设置它,否则后台无法开启):

`bash mkdir -p /opt/umami && cd /opt/umami openssl rand -base64 32 openssl rand -hex 32 `

把上面两条命令的输出分别记下来,稍后填入 compose 文件。然后在 /opt/umami/docker-compose.yml 写入以下内容(YAML 文件中 # 是注释符号,而本站渲染器会把行首 # 当成标题,所以下面的配置文件里不含任何注释,每一项的含义都在文件之后的表格里说明):

`yaml services: umami: image: ghcr.io/umami-software/umami:latest container_name: umami ports: - "127.0.0.1:3000:3000" environment: DATABASE_URL: postgresql://umami:换成你的强密码@db:5432/umami APP_SECRET: 填入你生成的随机字符串 TWO_FACTOR_ENCRYPTION_KEY: 填入你生成的64位十六进制字符串 TZ: Asia/Shanghai depends_on: db: condition: service_healthy init: true restart: always healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:3000/api/heartbeat || exit 1"] interval: 30s timeout: 5s retries: 5 db: image: postgres:15-alpine container_name: umami-db environment: POSTGRES_DB: umami POSTGRES_USER: umami POSTGRES_PASSWORD: 换成你的强密码 TZ: UTC volumes: - umami-db-data:/var/lib/postgresql/data restart: always healthcheck: test: ["CMD-SHELL", "pg_isready -U umami -d umami"] interval: 10s timeout: 5s retries: 5 volumes: umami-db-data: `

关于这份配置,有六点必须理解到位,否则很容易踩坑:

| 配置项 | 作用 | 踩坑后果 | |--------|------|---------| | DATABASE_URLPOSTGRES_PASSWORD | 应用连接数据库的凭据 | 两处密码必须完全一致,且密码中不要含 @:/ 等 URL 保留字符 | | APP_SECRET | 签名认证令牌 | 不设置或每个实例都一样,会导致 token 可被伪造,是官方明确要求每套实例唯一的值 | | TWO_FACTOR_ENCRYPTION_KEY | 加密 2FA 密钥 | 不设置则后台无法启用两步验证 | | 127.0.0.1:3000:3000 | 只把端口绑到回环地址 | 写成 3000:3000 会把后台直接暴露到公网,这是自建统计最常见的安全事故 | | TZ: Asia/Shanghai(应用) | 应用侧时区 | 官方建议数据库用 UTC,应用侧可设本地时区,避免报表时间偏移 | | TZ: UTC(数据库) | 数据库时区 | 官方原文建议 Postgres 使用 UTC,否则跨时区部署会出现时间戳不一致 | | postgres:15-alpine | 数据库镜像 | v3 版 Umami 只支持 PostgreSQL(最低 v12.14),网上旧教程里的 MySQL 方案在 v3 上已经不可用 |

需要特别提醒的是:Umami v3 已不再支持 MySQL,官方文档明确写的是"supports PostgreSQL (minimum v12.14)"。如果你照抄两三年前的教程用 MySQL 起库,应用会在建表阶段直接失败。

第四步:启动并验证

`bash cd /opt/umami docker compose up -d docker compose ps curl -I http://127.0.0.1:3000/api/heartbeat `

首次启动时容器会自动执行数据库迁移建表,稍等十几秒。看到 docker compose ps 里两个容器都是 healthy、并且心跳接口返回 200 就说明后端已经就绪。如果 umami 容器反复重启,用下面的命令看日志,九成是数据库密码写错或 Postgres 还没起来:

`bash docker compose logs --tail=50 umami `

第五步:Nginx 反向代理

安装 Nginx 并新建站点配置。注意下面配置里同样不含 # 注释,相关说明在配置之后。

Ubuntu 22.04:

`bash apt install -y nginx `

CentOS 7:

`bash yum install -y nginx systemctl enable --now nginx `

写入 /etc/nginx/conf.d/umami.conf

`nginx server { listen 80; server_name analytics.example.com;

location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 300; client_max_body_size 20m; } } `

把这处配置里的四个关键点解释清楚:

- proxy_set_header Host $host:不传 Host 头,Umami 生成的重定向链接会指向 127.0.0.1:3000,登录后跳回错误地址。 - X-Forwarded-ForX-Real-IP:让 Umami 拿到访客真实 IP。若不传,所有访问都会被认为来自 127.0.0.1,地理位置统计直接失效。Umami 也支持用 CLIENT_IP_HEADER 环境变量指定自定义的取 IP 头。 - UpgradeConnection "upgrade":透传 WebSocket,实时在线人数看板依赖它,不写会出现"实时数据一直转圈"。 - client_max_body_size 20mproxy_read_timeout 300:给导入导出和历史数据查询留出余量,避免偶发 413 或 504。

改完配置后先测试再重载:

`bash nginx -t && systemctl reload nginx `

第六步:配置 Let's Encrypt 免费 SSL 证书

Umami 的后台登录、脚本上报都应走 HTTPS,否则浏览器会对混合内容报警告。用 certbot 一条命令搞定:

Ubuntu 22.04:

`bash apt install -y certbot python3-certbot-nginx `

CentOS 7:

`bash yum install -y certbot python2-certbot-nginx `

两个系统都用同一条签发命令(把域名换成你自己的):

`bash certbot --nginx -d analytics.example.com --redirect --agree-tos -m [email protected] --no-eff-email `

--redirect 会自动把 80 端口的请求 301 跳转到 443,并接管前面的 Nginx 配置。certbot 会顺带装好 systemd 定时任务自动续期,可以用下面的命令确认续期逻辑正常:

`bash certbot renew --dry-run `

第七步:初始化账号并创建网站

浏览器打开 https://analytics.example.com,使用默认账号登录:

- 用户名:admin - 密码:umami

第一件事就是改密码(右上角头像 → Settings → Profile),官方文档也专门加了提醒。Umami 默认密码是全局的 admin/umami,如果不改,等于任何知道你域名的人都能登录看你的流量数据。

改完密码后,进入 Settings → Websites → Add website,填写:

- Name:网站名称(显示在看板上) - Domain:你的站点域名,例如 blog.example.com - 保存后系统会生成一个 website-id(一串 UUID),第八步要用到。这一个 ID 就代表一个被统计的站点,多站点就多建几条。

第八步:在网站里嵌入统计脚本

打开你的网站模板(WordPress 可以放到主题的 header.php,静态站放到公共头文件,Shopify 放到 theme.liquid</head> 前),加入下面这一行:

`html <script defer src="https://analytics.example.com/script.js" data-website-id="你的website-id"></script> `

其中 data-website-id 就是第七步生成的那串 UUID。src 指向你自己的统计域名,script.js 是 Umami 默认的追踪脚本名。加完之后刷新你的网站页面,回到 Umami 后台的 Realtime 面板,通常几秒内就能看到自己的访问记录进来。

常用的脚本属性还有几个,按需添加:

| 属性 | 用途 | |------|------| | data-domains="blog.example.com" | 只在指定域名上报,避免统计到本地开发环境或测试站 | | data-auto-track="false" | 关闭自动上报,完全由你手动调用 umami.track() | | data-performance | 自动采集 Core Web Vitals(LCP/CLS/INP)等性能指标 | | data-exclude-search="true" | 不上报 URL 里的查询参数(避免敏感参数进统计) | | data-do-not-track="true" | 尊重访客浏览器的 Do Not Track 设置 |

用 JS 手动上报自定义事件(例如"点击购买按钮"):

`javascript window.umami.track('购买按钮点击', { plan: 'pro', price: 20 }); `

注意事件名最长 50 个字符,且事件数据不能脱离事件名单独发送;用 data-umami-event 属性上报的话,所有附加数据都会被存成字符串,需要保留数字/布尔类型就必须用上面的 JS 方式。

四、进阶配置:让统计更稳、更准、更省

1. 绕过广告拦截器

不少广告拦截插件(uBlock、AdGuard 等)会按名单拦截 /script.js/api/send 这两个特征路径,导致你的统计量莫名偏低。Umami 官方给了两条规避方案:

- 自定义脚本名:设置环境变量 TRACKER_SCRIPT_NAME,把脚本名从默认的 script.js 改成别的名字(比如 metricslib/a1b2),前台脚本地址同步改成新名字即可。扩展名 .js 可以省略。 - 自定义上报端点:设置 COLLECT_API_ENDPOINT,把默认的 /api/send 换成别的路径,让拦截名单匹配不到。

这两个变量都在 compose 文件的 environment 里追加即可,改完 docker compose up -d 重建容器生效。

2. 加一个 Redis 缓存(多站点、高流量才需要)

Umami v3.0.1 起支持可选的 Redis 连接:设置 REDIS_URL 环境变量即可启用缓存与协调能力(不设则相关功能保持关闭)。对个人博客来说不需要,只有在网站数量多、实时看板频繁查询时才有明显收益。自建 Redis 可参考本站《Redis 缓存服务器搭建》一文。

3. 数据备份:pg_dump 是唯一正确的姿势

统计数据的价值在于累积,一旦数据库卷损坏又没有备份,几个月的流量记录就全没了。用 pg_dump 从容器里导出,配合 crontab 定时执行,是最省事的方案。下面脚本存成 /opt/umami/backup.sh

`bash #!/bin/bash D=$(date +%F) docker exec umami-db pg_dump -U umami umami | gzip > /opt/umami/backup/umami-$D.sql.gz find /opt/umami/backup -name 'umami-*.sql.gz' -mtime +7 -delete `

`bash chmod +x /opt/umami/backup.sh mkdir -p /opt/umami/backup crontab -e `

在 crontab 里加一行,每天凌晨 3 点执行(crontab 文件里的 # 是注释语法,但为避免行首符号被渲染器误判,这里不写注释,就加这一行):

`text 0 3 * /opt/umami/backup.sh `

更进一步,用 rclone 把备份文件同步到对象存储(阿里云 OSS / AWS S3 / 腾讯云 COS 均可),实现异地容灾,具体做法见本站《服务器备份容灾实战》一文。

4. 升级到新版本

Umami 更新很频繁,升级只需要两条命令:先拉取新镜像,再强制重建容器(数据库卷会被保留,不会丢数据):

`bash cd /opt/umami docker compose pull docker compose up --force-recreate -d `

升级前务必先跑一次上一节的备份脚本。虽然没有重大版本变更时数据库迁移通常是安全的,但手里有一份 dump 意味着任何问题都能回滚。另外强烈建议不要把 compose 里的镜像写成 :latest,生产环境固定一个大版本 tag(如 :v3.4.0)更稳妥,官方当前最新版本为 v3.4.0,可用 GitHub API 动态查询:

`bash curl -s https://api.github.com/repos/umami-software/umami/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' `

> 🚀 需要按流量规模选一台合适的机器?通过 5.chengzicloud.cloud 可按配置档位挑选海外云服务器,享专属折扣。

五、安全加固清单(部署后逐条检查)

自建统计系统持有一份完整的访客行为日志,安全等级应当按"数据库"而不是"小工具"来对待。下面八条建议逐条落实,成本很低但能挡掉绝大多数常见事故:

1. 应用端口必须绑回环127.0.0.1:3000:3000,绝不写成 3000:3000。这是本节最重要的一条。 2. 防火墙 + 云安全组双重收敛:只放行 22/80/443,3000 与 5432 都不对外暴露。安全组和系统防火墙要同时检查,只改一处等于没改。 3. 数据库不映射端口:compose 里 db 服务不写 ports,只靠 Docker 内部网络通信,Postgres 天然不对公网开放。 4. 首次登录立即改密码:默认 admin/umami 是公开信息,不改等于后台裸奔。有条件的再启用两步验证(需先设置 TWO_FACTOR_ENCRYPTION_KEY)。 5. 启用强制 HTTPSFORCE_SSL 环境变量会让 Umami 对所有响应带上 HSTS 头,避免降级攻击。 6. 数据库备份加密并异地存放:dump 文件里含全部访问记录,本地备份目录权限设 700,异地同步建议加 rclone 的加密层。 7. 加 fail2ban 防爆破:后台登录页暴露在公网,给 Nginx 加一个针对登录路径的 jail,能有效挡住暴力破解。做法同本站《网站安全加固》一文。 8. 不用的上报数据及时清理:设置里可以按站点清空历史数据;如果对数据保留期有合规要求,配合备份轮转策略一起做。

六、常见问题 FAQ

Q:Umami 一定要用 PostgreSQL 吗?能不能用 MySQL? A:v3 版起只支持 PostgreSQL,最低版本 v12.14,官方文档的措辞是 "Umami supports PostgreSQL (minimum v12.14) databases",没有列出 MySQL。网上大量旧教程给出的 MySQL 方案适用于 v2 及更早版本,在 v3 上建表阶段就会失败。如果你想沿用已有的 MySQL 环境,只能选 v2 的旧镜像,但那意味着放弃后续安全更新,不推荐。

Q:CentOS 7 上会不会遇到 glibc 版本不兼容的问题? A:不会。Umami 走的是完整的容器化部署路线,Node.js 运行时和依赖都打包在官方镜像内部,宿主机的 glibc 版本根本不参与应用运行。这和本站《code-server 云端开发环境》《Ollama 私有 AI 助手》《Meilisearch 自建搜索》三篇里遇到的 GLIBC_2.xx not found 形成鲜明对照——凡是官方提供镜像的项目,CentOS 7 的 glibc 2.17 就不再是障碍。CentOS 7 上真正需要额外处理的只有一件事:手动补装 Docker Compose v2 插件(见第二步)。

Q:Umami 的统计数字和 Google Analytics 对不上,正常吗? A:正常,两者口径不同。常见差异来源有三个:一是广告拦截插件拦掉了 Umami 的 script.js,导致自建统计偏低(用 TRACKER_SCRIPT_NAME 改脚本名可缓解);二是 Umami 默认把机器人流量排除,而 GA 的口径未必一致;三是在单页应用(SPA)里如果只加载一次脚本,路由切换不会自动上报,需要调用 umami.track() 手动上报。判断依据应以你自己的服务器访问日志为参考基准。

Q:后台实时数据一直转圈、页面卡住怎么办? A:先检查 Nginx 配置里有没有透传 WebSocket——proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade"; 这两行必须存在。Umami 的实时看板通过 WebSocket 推送数据,缺少这两行就会出现"连接建立但数据不来"的现象。改完记得 nginx -t && systemctl reload nginx

Q:我该不该把 3000 端口直接开放出来省掉 Nginx? A:不该。直接暴露 3000 意味着 Umami 以明文 HTTP 服务在公网,登录凭据和上报数据都可能被中间人截获,而且失去了统一的反代入口和后续加 WAF 的可能。多配一层 Nginx 只多花十分钟,换来的是 HTTPS、证书自动续期和端口收敛。

Q:忘记后台密码了怎么恢复? A:如果只是忘了自己改过的密码,最直接的办法是重置数据库里的用户表(docker exec -it umami-db psql -U umami umami 后更新 user 表密码字段),或者从最近的备份恢复。若连数据库都登录不了,可以删掉用户表让 Umami 重新走初始化流程,但那会丢失该账号的配置。这也是为什么第七步强调"先备份再折腾"。

Q:换服务器时怎么把数据搬过去? A:三步走。第一,在旧机上执行 pg_dump 导出(见进阶第 3 节);第二,在新机上按本文部署到"容器起来但还没登录"的状态;第三,用 docker exec -i umami-db psql -U umami umami < backup.sql 把 dump 导入新库,然后重建容器。注意新机的 APP_SECRET 若与旧机不同,已有的登录会话会全部失效,需要重新登录,但历史统计数据不受影响。

Q:为什么访客的地理位置信息显示不准或全是"未知"? A:两个原因。一是 Nginx 没有转发 X-Forwarded-For / X-Real-IP,Umami 拿不到真实 IP 就只能按 127.0.0.1 处理;二是 Umami 需要一份 MaxMind 兼容格式的 GeoIP 库来做 IP 定位,可通过 GEO_DATABASE_URL 环境变量指定下载地址。如果站点前面还挂了 Cloudflare,注意配合 SKIP_LOCATION_HEADERSCF-IPCountry 的使用方式,否则国家级定位可能只精确到国家。

七、总结

用海外云服务器自建 Umami,本质上是把"网站访问数据"这件资产从第三方平台手里拿回到自己账号下。整套流程的复杂度其实低于大多数人的预期——装 Docker、写一份 compose、配一层 Nginx 反代、签一张 Let's Encrypt 证书,四件事做完系统就能跑。真正决定成败的不是技术难度的,而是几个容易被忽略的细节:

- 选配置时内存优先,1 核 2G 优于 2 核 1G; - 端口必须绑 127.0.0.1,绝不直接暴露 3000; - 默认密码立刻改APP_SECRET 每套实例唯一; - v3 只支持 PostgreSQL,别再照抄 MySQL 老教程; - 备份要自动化,统计数据丢了不可逆。

把上面五条守好,一套自建统计系统可以稳定跑很多年,成本却始终维持在每月几美元的水平。对于正在做跨境独立站、技术博客或内容站的用户来说,这几乎是性价比最高的一项基础设施投入。

延伸阅读: - 海外云服务器 Docker + Portainer 容器管理平台搭建教程 - Nginx 反向代理 + Let's Encrypt 免费 SSL 证书配置完整教程 - 海外云服务器备份与容灾实战(快照 + rclone 异地 + 数据库定时备份) - MySQL / PostgreSQL 数据库服务器搭建与调优完整教程 - 海外云服务器监控运维:Prometheus + Grafana + Telegram 告警

> 本文由 5.chengzicloud.cloud 提供,点击访问首页了解更多海外云服务器部署方案和专属优惠。