乐于分享
好东西不私藏

Sentry安装与运维文档

Sentry安装与运维文档
适用范围:基于 getsentry/onpremise 的 Sentry nightly(功能完整版) 自托管部署。 文档所有 IP、密码、授权码、具体邮箱域名等涉密信息均已脱敏,以 <...> 占位,实际部署请替换为真实值。 说明:本文配置片段来自 2026-08-04 现场核实记录;本次撰写时因服务器 root 口令已变更,未做实时二次拉取。

目录

  • 第一部分:安装部署(细节 + 完整步骤)
  • 第二部分:扩展支持 OpenLDAP
  • 第三部分:邮件功能调试
  • 第四部分:问题与解决方案

第一部分:安装部署(细节 + 完整步骤)

1.1 环境要求

项目
建议值
说明
服务器
云主机(如华为云 ECS)
需有公网 IP 与安全组放行
操作系统
Ubuntu 22.04 LTS
本文基于此验证
配置
≥ 8 核 / 16G(实测 8 核 30G 可用)
Sentry 较吃内存,建议 16G 起步,不足时开 swap
磁盘
≥ 40G
镜像 + 数据库 + 附件
网络
可访问公网
需拉取镜像、发邮件
端口
Web 9000(容器内);对外经反代暴露 443
安全组放行 9000 入方向(或仅反代机访问)
前置依赖
Docker ≥ 24、Docker Compose v2、Git
见 1.3
内存不足兜底:如物理内存 < 16G,务必配置 swap(本文 1.5 节写入 8G swap 到 /etc/fstab),否则 worker 易被 OOM 杀掉。

1.2 获取源码

git clone https://github.com/getsentry/onpremise.git /opt/onpremisecd /opt/onpremise# nightly 为功能完整版;如需稳定版可切换 taggit checkout nightly

容器镜像标签统一为 sentry-self-hosted-local(由本地 docker compose build 生成)。

1.3 安装 Docker 与 Compose(Ubuntu)

apt-get updateapt-get install -y docker.io docker-compose-pluginsystemctl enable --now dockerdocker version

1.4 ⚠️ 国内网络(GFW)必做:源加速

这是最容易卡死的一步。 不加速:镜像拉不下来、构建阶段 apt/pip/apk 超时、alpine 源只返回 IPv6 地址导致解析失败。以下 5 项均已实测落地并持久化,重装/升级前不要删除

  1. Docker Hub 镜像加速 —— /etc/docker/daemon.json

    {  "registry-mirrors": [    "https://<1panel镜像>.com",    "https://<1ms镜像>",    "https://<轩辕镜像>",    "https://<daocloud镜像>"  ]}

    改完 systemctl restart docker

  2. ghcr.io 镜像站 —— /opt/onpremise/.env.custom

    SENTRY_IMAGE=ghcr.nju.edu.cn/getsentry/sentry:nightly
    注意:.env.custom仅被 install.sh 读取。裸 docker compose 仍用 ghcr.io 原名,需先从加速站 pull 再 docker tag 回原名,否则仍走官方源。
  3. 构建镜像内部源 —— 改 Dockerfile(jq / cron / sentry 三个)让:

    • Debian apt 走华为云/阿里云源
    • pip
       走国内源(如清华/阿里)
    • 原文件保留 .orig 备份,便于升级回滚。
  4. alpine apk 源 —— install/bootstrap-s3-*.sh 将 dl-cdn.alpinelinux.org 改为阿里云 apk 源,解决"仅返回 IPv6 地址、容器内无法解析"的问题。

  5. swap —— /etc/fstab 追加 8G swap 自动挂载(详见 1.5)。

1.5 基础系统配置

# 8G swap(内存不足时必需)fallocate -l 8G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfileecho '/swapfile none swap sw 0 0' >> /etc/fstab

1.6 关键环境变量与调优(.env

# 邮件域名(发件人后缀、链接域名基础)SENTRY_MAIL_HOST=<企业邮箱域名># 并发(按 CPU 核数设,本文 8 核)SENTRY_TASKWORKER_CONCURRENCY=8LAUNCHPAD_TASKWORKER_CONCURRENCY=8
内存/核数变化后相应调整并发,避免 worker 打满或空转。

1.7 构建与启动

cd /opt/onpremise# 方式一:官方安装脚本(会读取 .env.custom 镜像 + 引导)./install.sh# 方式二:手动构建并启动docker compose builddocker compose up -d
易踩坑docker compose up 被中断时,部分容器会停在 Created 未 start 状态 → 重连后需手动 docker compose up -d <服务名> 逐个补起(如 webtaskworkerworkerpostgresrediskafkaclickhouse 等)。

1.8 反向代理(对外暴露 HTTPS)

前端经 Tengine / Nginx 反代到容器 9000:

https://<Sentry域名>  →  <Sentry服务器内网IP>:9000

config.yml / sentry.conf.py 需配置 CSRF 信任与 HTTPS 信任(SECURE_PROXY_SSL_HEADERCSRF_TRUSTED_ORIGINS 等),否则登录/提交会被 CSRF 拦截。

重启后网络提示:服务器重启后 iptables 临时规则(如旧 DNAT)会丢失;外部访问现依赖 docker-proxy 发布的 0.0.0.0:9000,无需 DNAT。公网不通先查云安全组是否放行 9000 入方向

1.9 验证安装

docker compose ps                 # 所有容器 State=running/healthydocker compose logs --tail 50 web # 无启动报错、能进入就绪curl -I http://localhost:9000     # 返回 200/302

访问 https://<Sentry域名> 应能看到登录页。


第二部分:扩展支持 OpenLDAP

2.1 兼容性现状(重要)

官方 sentry-ldap-auth 2.9(2021 年)与 Sentry nightly(Django 4+,模型改名)根本不兼容。直接装 2.9 会在登录时 500:

  • 旧版 backend 引用的模型路径在新版已改名;
  • 配置垫片(shim)救不了,会触发 AUTH_LDAP_SENTRY_GROUP_ROLE_MAPPING 相关报错。

结论:必须改写其 backend.py 并打进 web 镜像

2.2 改写 backend 并打包进镜像

  1. 兼容版 backend 源码放在宿主机 /opt/onpremise/sentry/sentry_ldap_auth_backend.py
  2. 在 sentry/Dockerfile 末尾加一行,把兼容 backend 覆盖安装到站点包:
    COPY sentry_ldap_auth_backend.py /.venv/lib/python3.13/site-packages/sentry_ldap_auth/backend.py
  3. 重新构建并滚动更新 web:
    docker compose build webdocker compose up -d --no-deps web

兼容版 backend 关键注意点

  • import 必须走新路径:sentry.models.organizationsentry.models.organizationmembersentry.users.models.user_optionsentry.users.models.useremail
  • 创建 OrganizationMember 时用 user_id=(新版字段名);
  • _get_effective_sentry_role()
     在没有配置AUTH_LDAP_SENTRY_GROUP_ROLE_MAPPING 时,不能读取 ldap_user.group_names(否则会要求 AUTH_LDAP_GROUP_TYPE)。

2.3 sentry.conf.py 的 LDAP 段

需含 Django4 垫片(否则启动时挂):

# Django4 兼容垫片from django.utils.encoding import force_str  # 替代旧 force_unicode# Signal.__init__ 需丢弃 providing_args 参数

LDAP 连接与映射配置(占位示例):

import ldapfrom django_auth_ldap.config import LDAPSearch, GroupOfUniqueNamesTypeAUTH_LDAP_SERVER_URI = "ldap://<LDAP服务器IP>:389"AUTH_LDAP_BIND_DN = "cn=<bind用户>,dc=<公司域名>,dc=com"AUTH_LDAP_BIND_PASSWORD = "<LDAP绑定密码>"AUTH_LDAP_USER_SEARCH = LDAPSearch(    "ou=People,dc=<公司域名>,dc=com",    ldap.SCOPE_SUBTREE,    "(uid=%(user)s)",          # 登录名 = uid)AUTH_LDAP_USER_ATTR_MAP = {    "name""cn",    "email""mail",}# 新用户加入组织时的默认角色:member(普通成员),不要默认 adminAUTH_LDAP_SENTRY_ORGANIZATION_ROLE_TYPE = "member"AUTH_LDAP_SENTRY_ALLOW_LOGIN_WITHOUT_LINK = True# 允许自动加入/离开组织(员工首次 LDAP 登录即自动入组织,无需邀请)SENTRY_FEATURES["auth:ldap"] = True
角色从 admin 改为 member 后,已存在的 LDAP 用户需同步降级(用 sentry shell 把 OrganizationMember.role 由 admin 改为 member)。

2.4 用户入驻方式(onboarding)

  • LDAP 用户(员工,uid 如 bc-xxx
    不要发邮件邀请。直接让他们访问 https://<Sentry域名>/auth/login/sentry/,用 LDAP uid + 密码登录,allow_joinleave=True 会自动加入组织。
  • 非 LDAP / 外部人员
    :用组织内"邀请成员"发邮件邀请(走 email + password 注册)。

2.5 LDAP 账号改密码说明

LDAP 账号密码在 LDAP 服务器上,Sentry 侧改不了。改密码要去 LDAP(<LDAP服务器IP>:389)侧操作。Sentry 本地账号改密见第四部分 / 配套帮助文档。


第三部分:邮件功能调试

3.1 邮件配置放哪里

两层:

  1. /opt/onpremise/sentry/config.yml
     —— 邮件传输(SMTP)参数:
    mail.backend: 'smtp'mail.host: '<企业邮箱SMTP地址>'      # 如 smtphz.qiye.163.commail.port: 465mail.use-ssl: truemail.use-tls: false                 # 与 use-ssl 互斥!见 3.4mail.username: 'admin@<企业邮箱域名>'mail.password: '<客户端授权码>'       # 注意:是授权码,不是网页登录密码mail.from'admin@<企业邮箱域名>'
  2. /opt/onpremise/sentry/sentry.conf.py
     —— 发件人固定覆盖(约第 348 行):
    SENTRY_OPTIONS["mail.from"] = "admin@<企业邮箱域名>"
直连企业邮箱(推荐,方案 A):不依赖内置 smtp 中继容器(该容器为 Exim 设计转发 AWS SES,无凭证,默认用不了)。直接把 config.yml 指向真实企业 SMTP。

3.2 验证邮件走 taskworker 异步(最容易踩的坑)

网页"重发验证邮件"按钮链路:

网页按钮 → 后端 204 → send_confirm_email_singular → send_async        → 异步任务 sentry.tasks.email.send_email(跑在 taskworker 容器,不是 web)

程序里直连 smtp 能收到 ≠ 网页按钮能收到。 网页按钮走的是 taskworker 异步投递。

3.3 改完邮件配置必须重启两个服务

docker compose restart web taskworker
为什么:taskworker 会把 mail.* 选项缓存进进程内存。只改 config.yml 不重启 taskworker → 它继续用旧 host → 表现为 ConnectionRefusedError(连旧地址)或邮件石沉大海。收不到验证邮件时,先看 docker compose logs taskworker 的 send_email / ConnectionRefused / ValueError 报错,不要只看 web 日志。

3.4 use-tls 与 use-ssl 必须互斥

mail.use-ssl: truemail.use-tls: false   # 必须显式关掉,不能留注释!
坑:config.yml 里被注释掉的 mail.use-tls: false 会沿用默认值 True,与 mail.use-ssl: true 同时为真 → ValueError: EMAIL_USE_TLS/EMAIL_USE_SSL are mutually exclusive465 端口应设 use-ssl: true + use-tls: false

3.5 公共邮箱域名被拦截(qq.com 报 “Invalid email”)

Sentry 源码 server.py 默认值:

INVALID_EMAIL_ADDRESS_PATTERN = re.compile(r"\@qq\.com$", re.I)

会把所有 @qq.com 邮箱判为非法,添加/验证时直接 400 "Invalid email"

修复(不动源码,升级不丢):在 /opt/onpremise/sentry/sentry.conf.py 末尾覆盖:

import re# 放行公共邮箱域名:只拒"连续两个点"的畸形邮箱INVALID_EMAIL_ADDRESS_PATTERN = re.compile(r"\.{2,}")

改后 docker compose restart web,即可正常添加/验证 qq.com。

3.6 邮件连通性自检

# 容器内直连发信测试(同步,绕过 taskworker,验证 SMTP 本身)docker compose run --rm web sentry shell>>> from sentry.utils.email import send_mail>>> send_mail('测试''正文''admin@<企业邮箱域名>', ['你的邮箱@xx.com'])# 期望输出 SENT OK, message count = 1# 验证 taskworker 异步链路docker compose logs --since 2m taskworker | grep -iE 'mail.sent|ConnectionRefused|ValueError'# 期望看到 sentry.mail: mail.sent (message_id=...)

3.7 企业邮箱侧注意

  • 客户端授权码(非网页密码);授权码归属哪个账号,发件人 mail.from / mail.username 就必须用同一账号(否则 535 LOGIN.PERMDENY)。
  • 若邮件服务商按登录 IP 限制,需把服务器公网出口 IP 加入白名单。

第四部分:问题与解决方案

#
现象
根因
解决方案
1
登录后页面卡在 “Parallelizing webpack builders…”,设置页报"插件有问题"
多次 docker compose build web 导致 chunk hash 变更;入口 app.js 被 Service Worker 长期缓存,请求已不存在的旧 hash chunk → 404。服务器本身自洽(新 hash 返回 200)
浏览器清站点数据(DevTools → Application → Clear site data,或 chrome://settings/siteData 删 <Sentry域名>),再 Ctrl+Shift+R 硬刷
2
LDAP 用户登录默认是 admin 权限
AUTH_LDAP_SENTRY_ORGANIZATION_ROLE_TYPE
 设成了 admin
改为 "member",并把已存在的 LDAP 用户(如 bc-xxxOrganizationMember.role 同步降级
3
邮件报 535 5.7.0 LOGIN.PERMDENY
用了网页登录密码、或授权码归属账号与发件人账号不一致
改用同域客户端授权码mail.username 与 mail.from 必须和授权码所属账号一致
4
添加 qq.com 邮箱报 Invalid email
Sentry 默认 INVALID_EMAIL_ADDRESS_PATTERN 拦截 @qq.com
在 sentry.conf.py 末尾覆盖为 re.compile(r"\.{2,}")docker compose restart web
5
网页"重发验证邮件"点没反应、收不到信(但程序发信能收到)
验证邮件走 taskworker 异步;taskworker 缓存旧 host → ConnectionRefused,或 use-tls/use-ssl 互斥报错 ValueError
① config.yml 设 mail.use-ssl:true + mail.use-tls:false;② 改完 docker compose restart web taskworker;③ 看 docker compose logs taskworker 确认 mail.sent
6
邀请链接打开报"此组织邀请链接无效 / 可能已过期 / 需用其他账户登录"
点链接的浏览器已登录别的账号(邮箱 ≠ 被邀请邮箱);或多次重发导致旧邮件链接 member id 已失效
受邀人用无痕窗口或先登出再点;链接单用且绑定该邮箱,不能转发/复用;误删重建后发新链接即可
7
createuser --password
 设置的管理员密码不生效(nightly 新版)
新版不采用该方式生成的密码
用 sentry shell:from sentry.users.models import Useru,_=User.objects.get_or_create(email='admin@sentry.local', defaults={'username':'admin'})u.set_password('<新密码>'); u.is_superuser=u.is_staff=u.is_active=True; u.save()。注意 import 路径是 sentry.users.models(不是旧 sentry.models
8
改 mail.* 或账号密码后不生效
配置未重新加载
docker compose up -d --force-recreate web
(web);邮件相关还要重启 taskworker
9
docker compose up
 中断后部分服务起不来
容器停在 Created 未 start
docker compose up -d <服务名>
 逐个补起
10
服务器重启后外部访问不通
iptables
 临时规则丢失
现依赖 docker-proxy 的 0.0.0.0:9000;先查云安全组 9000 入方向是否放行

附:本地用户改密码(非 LDAP)

  • 自助
    :登录 → 头像 → Settings → Account → Security → Change password(需当前密码)。
  • 管理员代改
    :用配套的 change_sentry_password.py(SFTP 上传密码、规避特殊字符转义、含 --dry-run 只读校验),或 sentry shell 调 set_password(),改完立即生效、无需重启。
  • 详见配套《Sentry本地用户改密帮助文档》(HTML)。

附:常用运维命令速查

cd /opt/onpremisedocker compose ps                                   # 服务状态docker compose restart web taskworker               # 邮件/配置改动后重载docker compose logs --since 5m taskworker | grep -i mail   # 查邮件异步投递docker compose run --rm web sentry shell            # 进 Django shell 改数据/发信docker compose build web && docker compose up -d --no-deps web  # 改了 LDAP backend 后重建

文档状态:配置片段基于 2026-08-04 现场核实;本次(撰写时)因服务器 root 口令已变更,未做实时二次拉取,如有出入以服务器实际文件为准。涉及 LDAP 绑定密码、邮件授权码、root 口令等均应以最新凭据替换文中占位符。