适用范围:基于getsentry/onpremise的 Sentry nightly(功能完整版) 自托管部署。 文档所有 IP、密码、授权码、具体邮箱域名等涉密信息均已脱敏,以<...>占位,实际部署请替换为真实值。 说明:本文配置片段来自 2026-08-04 现场核实记录;本次撰写时因服务器 root 口令已变更,未做实时二次拉取。
目录
第一部分:安装部署(细节 + 完整步骤) 第二部分:扩展支持 OpenLDAP 第三部分:邮件功能调试 第四部分:问题与解决方案
第一部分:安装部署(细节 + 完整步骤)
1.1 环境要求
内存不足兜底:如物理内存 < 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 项均已实测落地并持久化,重装/升级前不要删除:
Docker Hub 镜像加速 ——
/etc/docker/daemon.json{"registry-mirrors": ["https://<1panel镜像>.com","https://<1ms镜像>","https://<轩辕镜像>","https://<daocloud镜像>"]}改完
systemctl restart docker。ghcr.io 镜像站 ——
/opt/onpremise/.env.customSENTRY_IMAGE=ghcr.nju.edu.cn/getsentry/sentry:nightly注意:
.env.custom仅被install.sh读取。裸docker compose仍用ghcr.io原名,需先从加速站 pull 再docker tag回原名,否则仍走官方源。构建镜像内部源 —— 改
Dockerfile(jq / cron / sentry 三个)让:Debian apt走华为云/阿里云源pip走国内源(如清华/阿里) 原文件保留 .orig备份,便于升级回滚。alpine apk 源 ——
install/bootstrap-s3-*.sh将dl-cdn.alpinelinux.org改为阿里云 apk 源,解决"仅返回 IPv6 地址、容器内无法解析"的问题。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 <服务名>逐个补起(如web、taskworker、worker、postgres、redis、kafka、clickhouse等)。
1.8 反向代理(对外暴露 HTTPS)
前端经 Tengine / Nginx 反代到容器 9000:
https://<Sentry域名> → <Sentry服务器内网IP>:9000config.yml / sentry.conf.py 需配置 CSRF 信任与 HTTPS 信任(SECURE_PROXY_SSL_HEADER、CSRF_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 并打包进镜像
兼容版 backend 源码放在宿主机 /opt/onpremise/sentry/sentry_ldap_auth_backend.py。在 sentry/Dockerfile末尾加一行,把兼容 backend 覆盖安装到站点包:COPY sentry_ldap_auth_backend.py /.venv/lib/python3.13/site-packages/sentry_ldap_auth/backend.py重新构建并滚动更新 web: docker compose build webdocker compose up -d --no-deps web
兼容版 backend 关键注意点:
import 必须走新路径: sentry.models.organization、sentry.models.organizationmember、sentry.users.models.user_option、sentry.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/,用 LDAPuid+ 密码登录,allow_joinleave=True会自动加入组织。 - 非 LDAP / 外部人员
:用组织内"邀请成员"发邮件邀请(走 email + password 注册)。
2.5 LDAP 账号改密码说明
LDAP 账号密码在 LDAP 服务器上,Sentry 侧改不了。改密码要去 LDAP(<LDAP服务器IP>:389)侧操作。Sentry 本地账号改密见第四部分 / 配套帮助文档。
第三部分:邮件功能调试
3.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@<企业邮箱域名>'/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 exclusive。465 端口应设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 加入白名单。
第四部分:问题与解决方案
docker compose build web 导致 chunk hash 变更;入口 app.js 被 Service Worker 长期缓存,请求已不存在的旧 hash chunk → 404。服务器本身自洽(新 hash 返回 200) | chrome://settings/siteData 删 <Sentry域名>),再 Ctrl+Shift+R 硬刷 | ||
AUTH_LDAP_SENTRY_ORGANIZATION_ROLE_TYPEadmin | "member",并把已存在的 LDAP 用户(如 bc-xxx)OrganizationMember.role 同步降级 | ||
535 5.7.0 LOGIN.PERMDENY | mail.username 与 mail.from 必须和授权码所属账号一致 | ||
Invalid email | INVALID_EMAIL_ADDRESS_PATTERN 拦截 @qq.com | sentry.conf.py 末尾覆盖为 re.compile(r"\.{2,}"),docker compose restart web | |
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 | ||
createuser --password | from sentry.users.models import User;u,_=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) | ||
mail.* 或账号密码后不生效 | docker compose up -d --force-recreate webtaskworker | ||
docker compose up | Created 未 start | docker compose up -d <服务名> | |
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 口令等均应以最新凭据替换文中占位符。
夜雨聆风