早在半年前,我就动了本地部署 Sentry 的念头,但每次都被它那套庞大的服务编排吓得退回去。后来项目里线上报错越来越多,团队天天在群里发截图,终于让我下定决心把 Sentry 完整跑起来。这篇踩坑实录,就是记录我从零到能正常上报错误的全过程。如果你正准备本地部署 Sentry,或者已经被各种奇奇怪怪的错误折腾得想掀桌子,这篇文章应该能帮你省下不少周末。
先说结论:Sentry 的本地部署没有想象中那么难,但坑很多,尤其是对资源规划不熟、不读官方文档默认配置的人,基本都要交一遍学费。文章里我会把每一步的背景和原因讲清楚,包括为什么选 Docker Compose、内存到底要多少、邮件服务怎么接、升级时为什么老失败,这些都有实际经历支撑,不是纸上谈兵。
1. 部署前必须想明白的几件事
1.1 本地部署 Sentry 到底是要解决什么问题
很多团队接触 Sentry,第一反应是“这不就是个错误监控平台吗,直接用官方 SaaS 版不就行了”,但实际上自托管 Sentry 的价值远不止省钱。就拿我们项目来说,服务器环境偏内网,业务数据的敏感级别较高,用户上报的某些日志信息又不适合放到第三方平台,这时候本地部署就成了几乎唯一的选择。另一个场景是研发团队有定制需求,比如想把异常数据和企业内部工单系统打通,或者要对接私有化权限体系,这些在 SaaS 版里做起来限制非常多,而自托管版本能直接改代码、改配置。
所以你在动手之前必须想清楚:你是为了数据私密性、合规要求、定制能力,还是单纯为了省钱?这个决定会影响你后续所有配置。如果是图省钱,我劝你先算一笔账:自托管 Sentry 需要的服务器、维护时间、升级成本,加上偶尔出问题抢救的一次性人力成本,未必比官方免费额度或低档套餐划算。但如果是为了数据主权和定制空间,那自托管就是正路,值得投入。
我个人建议,如果只是个人学习、小项目试用,不要急着上完整集群,先跑单机 Docker Compose 模式就好。Sentry 的完整部署会拉起十几个服务,包括 ClickHouse、Kafka、PostgreSQL、Redis、Zookeeper、Snuba 等等,第一次看到docker compose ps刷出满满一屏时,确实有点吓人。但别慌,底层逻辑并不复杂:它就是用这些组件来支撑事件存储、搜索分析、队列处理和缓存,理解了大方向,后面的排障就不会迷路。
1.2 硬件要求与操作系统的选择
官方文档其实写得比较保守,告诉你推荐配置是 4 核 8G 起步,但我的实际体验是,8G 内存只够勉强跑起来,一旦开始有流量、有查询,就会频繁触发 OOM,尤其是 Kafka 和 Snuba 这两个家伙,吃内存毫不客气。我自己第一次部署在一台 4 核 16G 的 Linux 服务器上,跑了两周还算稳定,之后有一次升级时 ClickHouse 和 Kafka 同时重启,内存直接被打满,整个 Docker 都卡死在那了。你要是条件允许,直接上 16G 内存,硬盘建议 SSD,至少留出 100G 空间。
磁盘空间这个事很容易被忽略。Sentry 的日志、事件原始数据、ClickHouse 的数据都占用空间,尤其 ClickHouse 的存储路径默认会不断膨胀。我见过有人硬盘被写满后整个 Sentry 处于半死不活状态,登录页面能打开,但新事件根本不进来。所以部署前就要规划好数据目录,最好用独立数据盘,顺便把日志轮转和保留策略配好。
操作系统我偏向 Ubuntu 22.04 LTS 或 Debian 12,原因是 Docker 支持最稳,遇到问题搜索时能找到大量现成解决方案。不建议用带桌面版的系统跑生产环境,如果你是个人学习就无所谓,但团队的服务器还是越干净越好。另外,如果是 CentOS 7 这种老系统,会遇到内核版本和 Docker 版本兼容性问题,Sentry 容器启动时也是一堆诡异报错,我劝你趁早放弃。内核版本建议 5.10 以上,能避免很多 cgroup 和网络问题。
1.3 域名、HTTPS 与访问方式的提前规划
本地部署完成后总要访问 Web 界面。在真正动手前,你还要想清楚通过什么地址访问。如果只是内网自己用,可以直接用http://IP:9000这种方式,但现代浏览器的安全策略会越来越严格,而且很多特性,比如 clipboard 写入、摄像头权限、Service Worker 这些在非 HTTPS 环境下会有莫名其妙的问题。个人学习阶段无所谓,但要让团队正式用起来,我强烈建议配一个域名并启用 HTTPS。
我当时就是图省事,先用 IP 地址跑了两周,结果同事反馈说某些浏览器里登录状态总失效,上传 Source Map 也会失败,查了半天发现都是因为页面不是安全上下文导致的。后来加了 Nginx 反代和 Let‘s Encrypt 证书,整个世界清净了。如果你们公司有内部 CA,也可以用内部证书,但记得在每台客户端安装信任链,不然浏览器拦截也很麻烦。
反向代理这块,最常用的方案就是 Nginx。Sentry 默认监听 9000 端口,你只需要在 Nginx 里做一个location /的转发,把 WebSocket 也代理过去就行。注意 WebSocket 支持,Sentry 的 Web 界面有实时推送功能,不配置 WebSocket 的话,页面能开但某些操作会感觉很迟钝或者报错。Nginx 配置里添加Upgrade和Connection头即可,我后面会给出具体示例。
2. 安装前的准备工作:镜像、配置与网络
2.1 用官方 install.sh 还是手动 Docker Compose
这是新手最容易纠结的问题。Sentry 官方仓库getsentry/self-hosted提供了一键安装脚本./install.sh,实际上它做的工作也不复杂:检查环境、生成默认配置、创建 docker volume、构建镜像、初始化数据库。你会发现,如果用脚本安装,整条链路走下来会顺滑很多,因为它的默认版本组合是经过验证的,不太会出现镜像间版本不匹配的问题。
我的建议是:第一次部署,就用官方 install.sh,不要自己手工去改镜像 tag。Sentry 的组件之间版本耦合度很高,比如 Snuba 和 Sentry 前端版本不一致,会出现界面能打开,但事件详情页 API 报 500 的情况。你可能会觉得手工指定每个镜像的最新版更酷,实际上这只是给自己挖坑。install.sh 用到的docker-compose.yml里已经固定了镜像版本组合,你最多就是改环境变量,不要动镜像 tag。
同时,install.sh 还会生成.env文件,里面包含了大量配置项,例如SENTRY_SECRET_KEY、POSTGRES_PASSWORD、SENTRY_EVENT_RETENTION_DAYS等。它要求你必须设置一个复杂的SENTRY_SECRET_KEY,这是用来给 Django 做签名和加密的,不能丢失,否则数据库里的部分数据将无法读取。生成后记得保存好,别随手删了。
2.2 Docker 环境检查与 Compose 插件
在运行 install.sh 之前,先把 Docker 环境整利索。你需要安装 Docker Engine 和 Docker Compose 插件。注意,如果你用的是docker-compose这个旧版命令,和插件版的docker compose在某些解析行为上有差异。Sentry 官方脚本会检测 compose 是否可用,建议直接装官方插件。
另外,一个容易踩坑的点是 Docker 的存储驱动。如果你之前配置过 devicemapper 或别的存储驱动,可能会导致容器层构建异常。现在主流环境都建议使用 overlay2,可通过docker info查看 Storage Driver 字段。如果发现不是 overlay2,我建议你重新安装 Docker,别在这个上面将就。
Docker 版本也不能太老。Sentry 的编排文件用到了不少较新的语法,老版本可能直接报解析错误。官方要求 Docker 20.10 以上,最好是 24 及以上。在准备阶段执行docker version检查一下 Client 和 Server 版本,顺便看看权限问题,确保当前用户能直接操作 Docker。我在第一次部署时就是忘了加用户组,结果./install.sh里所有 docker 命令都被权限拒绝,浪费了不少时间。
2.3 反向代理与 WebSocket 配置
前面说到要提前规划域名和 HTTPS,这里直接给出一份 Nginx 示例配置,方便你对照修改。注意,我这个配置只负责转发,不包含证书申请逻辑。
server { listen 80; server_name sentry.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name sentry.example.com; ssl_certificate /etc/nginx/ssl/sentry.example.com.crt; ssl_certificate_key /etc/nginx/ssl/sentry.example.com.key; client_max_body_size 50m; location / { proxy_pass http://127.0.0.1:9000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; } location /ws/ { proxy_pass http://127.0.0.1:9000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 86400; } }这里最关键的是client_max_body_size,如果项目里要上传不少 Source Map 文件,默认 1m 肯定不够。我在实际使用中碰到过上传 sourcemap 时 413 Request Entity Too Large,调大这个值就解决了。WebSocket 的/ws/路径是 Sentry 内部功能用的,包括实时事件流和看板刷新,漏掉这一段会导致页面一直转圈。
另外,如果你之前只用过 Caddy,那更简单,Caddy 会自动申请证书并支持 WebSocket 代理,配置量比 Nginx 小很多。我这里贴 Nginx 是因为团队服务器上普遍都装了 Nginx,你按自己的实际情况选就好。
3. 完整安装过程实录
3.1 拉取仓库与执行安装脚本
我以 Ubuntu 22.04 为例,完整安装命令如下:
sudo apt update && sudo apt install -y git vim curl git clone https://github.com/getsentry/self-hosted.git cd self-hosted注意,默认分支通常是最新的稳定发布版。既然要做本地部署,最好固定版本,不要一更新就跟着最新走,否则哪天官方改了编排格式,你可能连升级路径都没有。可以用git tag查看当前发布版本,比如24.4.1这种格式,然后git checkout 24.4.1。我这次踩坑就是没固定版本,中途官方调整了镜像名称,我拉下来一堆新旧混合,最后只能重来。
接着运行:
sudo ./install.sh安装脚本会做几件事,首先检查环境依赖,然后交互式询问是否要创建初始用户。它会让你输入邮箱和密码,这步别跳过,因为 Sentry 初始化页面虽然也可以注册,但因为默认开启了注册限制,很多情况下会因配置问题无法成功注册,直接创建管理员账户最省事。
整个过程耗时取决于网络和机器性能,一般在 10 到 30 分钟之间。因为脚本要编译部分前端资源,等待时压力很大。不要频繁中断,如果中途断了,理论上可以重新运行,但部分步骤可能不幂等,我建议断了几次后干脆把~/.sentry缓存清掉再来,不要硬着头皮续跑。
3.2 环境变量与关键参数解读
安装完以后,仓库目录下会生成一个.env文件。这个文件是自托管 Sentry 的核心配置,你需要重点理解以下几个参数。
SENTRY_SECRET_KEY是 Django 密钥,必须保持稳定,一改掉所有 session 失效,严重时数据都解不开。SENTRY_EVENT_RETENTION_DAYS控制事件数据保留天数,我这里设置成 30 天,因为磁盘空间不是无限大,默认 90 天对于个人或者中小团队来说太长,还会拖慢查询性能。
邮件相关配置在后续会单独讲,这里更需要注意的是SENTRY_SINGLE_ORGANIZATION。如果设置为true,Sentry 会强制你不能创建多个组织,适合小团队的单实例使用;如果希望以后有多业务线接入,就保留默认或设为 false。我一开始没仔细看,默认是 true,后来想加一个新组织一直找不到入口,查了一圈才明白是这个开关的问题。
还有一个参数是SKIP_USER_CREATION,如果设成1,新用户注册功能会被禁用,只能由管理员邀请。内网环境建议开启,避免任何人都能注册。
3.3 启动服务与健康检查
安装完成后,用以下命令启动所有服务:
docker compose up -d docker compose ps第一次启动时,上面这一串服务会按照依赖顺序启动。如果安装脚本执行顺利,启动一般问题不大,但你还是得学会怎么判断服务是否健康。使用docker compose ps查看状态,Sentry 的状态字段会显示running或者healthy。Sentry 正常工作时,sentry-web、sentry-worker、sentry-cron这几个核心容器必须长期运行。
因为容器数量多,日志排查时要学会只盯着出问题的容器看,不要用docker logs -f一把梭地看全部,信息量太大会淹没真正的报错。常用的排障命令是:
docker compose logs sentry-web -f docker compose logs sentry-worker -f docker compose logs snuba -f如果sentry-web的日志里持续出现数据库连接失败,那就说明 PostgreSQL 容器还没正常起来,先docker compose ps看数据库状态,再去查对应日志。内存不足时,很多容器会反复重启,状态里出现Restarting,这时候最有效的办法是增加内存或减少同时运行的组件,而不是在报错里找答案。
4. 我在实际操作中踩到的那些坑
4.1 内存不足导致的构建失败
我最初部署时用的是 8G 内存的机器,前 20 分钟还很顺利,结果到编译前端静态资源时直接 OOM。症状表现是 install.sh 卡在某个地方不动,终端没有任何动静,过一会儿容器自动退出,日志里能看到Killed或者We did not find any downloads。
这个阶段最吃内存的是sentry-web的前端构建任务,用到了 webpack,本身就是一个内存大户。我的建议是,内存不足的机器不要硬扛,升级到 16G 最省事。如果实在不方便升级,可以临时增加 swap,比如:
sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile但 swap 只能缓解,生产环境别指望靠 swap 长期顶着。
4.2 升级时常见错误及恢复方法
自托管 Sentry 每过一阵子官方就会发布新版本,升级本来是一次git pull && ./install.sh就能搞定的操作,但是我在升级过程中遇到的最经典问题,是升级脚本因为数据库迁移失败而中断。 第一次升级时我从非常老的版本跳到比较新的版本,结果 ClickHouse 的 schema 迁移跑挂,报错信息大段大段地输出,根本无从看起。
后来我学会了备份先行:在升级前先备份 PostgreSQL 和 ClickHouse 的数据目录,或者直接打 Docker volume 的 tar 包。备份命令也许是这样:
docker run --rm -v sentry_postgres:/data -v $(pwd):/backup alpine tar czf /backup/postgres.tar.gz -C /data .ClickHouse 的数据量通常更大,备份起来更久,但也必须做。升级失败的时候,第一件事不是去查报错,而是先确认网络和磁盘空间,然后看是否有未完成的迁移锁。部分迁移锁可以通过重启对应容器解除,但有些需要手动连接数据库去清理表,这对新手来说难度陡增。
我这边的经验是:小版本升级不用太怕,大版本升迁前一定要先跑一个docker compose down,然后用完整备份留出回滚路径,再执行git pull。另外,不要跨太多版本跳跃升级,官方有时只保证相邻版本可升级,跨了太多版本中间缺了迁移步骤,谁都救不了你。
4.3 邮件服务不生效的排查
自托管 Sentry 的邮件服务是我折腾最久的一个功能。本地部署后,如果不对 SMTP 做配置,你会发现用户无法收到注册确认邮件、密码重置邮件,问题反馈也无法转到邮箱。即使你填对了 SMTP 参数,发送也可能失败,因为 Sentry 对邮件发送的配置层级比较绕人。
最关键的配置项在.env里:
SENTRY_MAIL_HOST=smtp.example.com SENTRY_MAIL_PORT=465 SENTRY_MAIL_USERNAME=yourname@example.com SENTRY_MAIL_PASSWORD=yourpassword SENTRY_MAIL_USE_TLS=true SENTRY_MAIL_FROM=no-reply@example.com要注意的是,如果端口是 465,则使用 SSL,对应的变量名可能是SENTRY_MAIL_USE_SSL而不是 TLS;如果是 587 端口,则用 STARTTLS。我一开始填反了,页面提示发送成功,实际邮箱里什么都没有,查 worker 日志才发现握手失败。
如果使用了阿里云、腾讯云这类厂商的邮件推送服务,一般会要求验证发件域名,还要配置 SPF/DKIM 记录。这些在本地部署时同样生效,别以为在配置里填了账号密码就万事大吉。排查邮件问题时,一条最快的命令是:
docker compose exec sentry-web python manage.py shell -c " from django.core.mail import send_mail; send_mail('test subject', 'message', 'no-reply@example.com', ['target@example.com'], fail_silently=False) "通过这条命令可以直接测试 Sentry 进程能不能发信,排除不少转发层和配置层的干扰因素。
4.4 构建失败与镜像拉取超时
国内网络环境下拉取 Docker Hub 镜像时还会经常出现超时、连接重置的情况。我第一次部署就卡在了拉取ghcr.io和docker.io镜像的环节,install.sh 反复提示某个镜像 pull 失败。
最有效的解决方案是配置你的 Docker daemon 使用可用的镜像加速器,这个需要在/etc/docker/daemon.json里写入 registry-mirrors。但因为镜像源属于外部环境问题,不同地区和不同网络情况效果差异很大,如果你的部署环境比较特殊,要么耐心多拉几次,要么提前把需要的镜像手动 pull 下来导出成 tar,再在离线环境导入。
这个步骤容易被忽略,所以建议你在规划部署时就把网络因素考虑进去。如果你所在团队有内网镜像仓库,建议把所有需要的镜像 tag 推送到内网仓库,然后把.env里的镜像地址替换成内网地址,这样后续升级也稳定很多,不会再因为外网波动中断安装。
5. 部署完成后的关键配置与日常维护建议
5.1 创建项目、获取 DSN 并与后端集成
Sentry 部署完成后,第一步是登录管理员账号,创建一个项目。项目类型可以选择你实际使用的技术栈,比如 Django、Flask、Node.js 或前端 JavaScript。Sentry 会根据项目类型展示对应的接入代码。其实它真正需要的东西只有一个:DSN 字符串。
DSN 的格式一般是这样的:
http://<public_key>:<secret_key>@sentry.example.com/<project_id>在新版本中,secret_key 这个字段已经不太用了,但在 SDK 中它仍然出现在 DSN 里。你在后端代码里初始化 Sentry 时,只需要填这一个 DSN 即可。
以 Python 项目为例,安装sentry-sdk后,在初始化代码中写入:
import sentry_sdk sentry_sdk.init( dsn="http://public_key@localhost:9000/2", traces_sample_rate=1.0, )然后故意制造一个异常,Sentry 就能收到并展示错误详情、堆栈、上下文信息。要注意的是,上报的请求是会走 Web 服务所在的 9000 端口,如果项目代码和 Sentry 不在同一台机器,DSN 里的主机名要写成能访问到的服务器地址,不能写localhost,否则线上环境会全部上报失败。
5.2 SDK 配置中容易忽略的细节
很多人在本地部署 Sentry 后,接入 SDK 时想当然地用默认配置,结果上报的数据量忽大忽小,或者性能监控完全没数据。实际上有几个参数非常关键。
traces_sample_rate是性能监控的采样率,我建议不要直接设成 1.0。高流量场景下设成 1.0 会让事件量和性能数据暴涨,存储和查询压力马上就上来了。更合理的方式是动态采样,比如根据 用户是否登录决定采样率。同样,send_default_pii这个开关要谨慎开启,它会在事件中附带用户 IP、Cookies 等个人信息,本地部署虽然数据不出网,但也要考虑合规和隐私问题。
如果把 SDK 集成到大型项目里,建议给 SDK 增加环境标签,方便区分开发、测试和生产环境。Sentry 内部的看板支持按环境筛选,这是做故障分级很重要的能力。不然开发环境报的错误和生产环境混在一起,排查效率非常低。
5.3 日常维护:备份、清理与安全检查
自托管 Sentry 一旦稳定跑起来,日常维护其实没有想象中复杂,但有几件事必须养成习惯。第一是定期备份数据库和配置文件。Sentry 的业务配置、用户账号、项目设置都存在 PostgreSQL 里,事件数据则在 ClickHouse 里。如果你关心的是配置和用户数据,PostgreSQL 备份优先级最高;如果担心丢失大量历史事件,ClickHouse 也要纳入备份策略。
第二是磁盘空间和容器日志体积的管理。长期运行的 Docker 容器会产生大量日志文件,尤其是sentry-worker和snuba,它们的日志轮转如果不配置,很容易克隆到几十 GB。可以在/etc/docker/daemon.json里设置 log rotation:
{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }重启 Docker 后,新容器才生效。旧容器日志的那个体积问题只能手动清或者等你下一次重新部署时再解决。
第三是安全更新。Sentry 的很多组件是用 Docker 镜像方式发布的,镜像本身的漏洞需要官方发布新版本才会修复,所以定期关注 GitHub Releases 很重要。对于生产环境,我建议至少每季度检查一次是否需要升级。当然,升级前别忘了我前面说的备份和固定版本那条铁律。
最后再说一个小技巧:如果你发现某天 Sentry 异常变慢,不要急着重启所有容器。先看docker stats分析哪个容器内存和 CPU 占用异常,多数情况下是 ClickHouse 在做合并或者 Kafka 堆积了大量消息。用docker compose logs定位,针对性处理,比无脑重启靠谱得多。
自托管 Sentry 这条路,走通之后你会获得一个完全受自己控制的错误监控系统,也理解了事件处理链路里的那些组件分工。虽然第一次部署花了我几乎两个完整周末,但把所有坑记录下来之后,后续升级和迁移都变得非常顺。如果你正准备部署,按照前面的步骤一步一步来,遇到问题不要焦虑,大部分故障都能通过在docker compose ps、docker compose logs和.env文件里找到线索。希望这篇实录能帮你少走几段弯路。