Bugzilla 5.2 部署实战

Ubuntu 24.04 + PostgreSQL 16 上以官方源码包部署 Bugzilla 5.2 的完整实测:checksetup.pl 三轮全流程、install-module.pl 补装 Template 3、localconfig 与 Apache 配置、testserver.pl 自检,附 4 条真实排障实录。

BugzillaBugzilla2026/10/28

Bugzilla 5.2 部署实战

目标:在一台 Ubuntu 24.04 服务器上,以官方源码包完成 Bugzilla 5.2 的完整部署:PostgreSQL 16 后端、Apache CGI 运行、checksetup.pl 全流程、管理员创建与部署后自检。本文所有命令与回显均来自真实服务器的逐条实测(查询与实测日期 2026-10-27),参数体系与 REST API 的深入使用分别见本专栏《Bugzilla 配置参数详解》《Bugzilla 常用命令与运维实战》。

一、环境信息

项目取值
操作系统Ubuntu 24.04 LTS(内核 7.0.0-38-generic,x86_64)
Bugzilla 版本5.2(官方稳定版,2026-10-27 官方下载页确认当前最新稳定线即 5.2)
安装方式官方源码 tarball 部署到 /var/www/html/bugzilla
Perlv5.38.2(系统自带)
Apache2.4.58(Ubuntu 仓库 httpd,mod_cgi 方式运行)
数据库PostgreSQL 16.15(本机同机部署,监听 localhost)
管理员账号admin@example.com(真实姓名 admin,密码 q1w2e3r4)
数据库账号数据库角色 bugs / 密码 q1w2e3r4 / 库名 bugs

二、方案总览

本文选用的部署路径为:官方 5.2 稳定版 tarball + Ubuntu 系统包提供 Perl 依赖 + 官方自带 install-module.pl 从 CPAN 补齐版本不足的模块 + PostgreSQL 16 后端 + Apache 2.4 以 mod_cgi 运行。这是官方安装文档(Installation and Maintenance Guide)推荐的标准形态,也是生产环境中最容易维护的形态。

几个关键决策点:

  1. 为什么不用发行版仓库的 bugzilla 包:Ubuntu 24.04 官方仓库没有提供 bugzilla 软件包(Debian 系的 bugzilla 打包长期停留在旧版本且依赖体系陈旧),而官方明确建议从源码分支安装以便跟随修复。源码部署也让升级(覆盖目录 + 重跑 checksetup.pl)路径最清晰。
  2. 为什么必须用 install-module.pl 补装 Template:5.2 要求 Template-Toolkit ≥ 3.008,而 Ubuntu 24.04 仓库的 libtemplate-perl 只有 2.27(实测 checksetup 明确报出版本差距),必须经 CPAN 安装 3.x。这是 5.2 部署的第一个拦路虎,实测过程见「排障实录 1」。
  3. 为什么选 PostgreSQL 而不是 MySQL/MariaDB:两者均为官方一等公民。实测环境已运行 PostgreSQL 16,故按 PostgreSQL 路径记录;如果你选择 MariaDB,差异仅在第 4.7 步的建库 SQL 与 localconfig 的 db_driver 取值(合法值见表,实测验证)。
  4. Apache 运行形态:默认按 mod_cgi(动态 CGI)部署,小团队规模足够;官方文档与 checksetup 均提示可用 mod_perl 获得数量级性能提升(实测环境已装 mod_perl 2.000013,mod_perl 化改造属于性能优化,不影响部署主流程,不在本文展开)。

💡 技术拓展:Bugzilla 是「安装器驱动」型应用——真正建库、建表、生成配置、修权限的都不是人手而是 checksetup.pl。它可重复执行(幂等):每次运行都会检测当前状态并只做缺失的部分,因此「跑三遍很正常」不是部署过程的混乱,而是官方设计的分阶段引导:第一遍查模块 → 第二遍生成 localconfig → 第三遍建库建管理员。理解这一点,部署排障思路会清晰很多。

三、前置准备

3.1 安装系统依赖

以 root 执行(生产环境可用 sudo)。以下一组命令覆盖 Apache、PostgreSQL、Perl 及编译工具链、常用 Perl 模块的系统包版本(模块版本不足的部分稍后由 install-module.pl 解决):

apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y \
  apache2 postgresql postgresql-contrib git curl wget build-essential sudo \
  libapache2-mod-perl2 libdbd-pg-perl libdbi-perl libdatetime-perl \
  libdatetime-timezone-perl libtemplate-perl libemail-mime-perl \
  libemail-sender-perl libjson-xs-perl liblist-moreutils-perl \
  libtimedate-perl liburi-perl libwww-perl libsoap-lite-perl \
  libcgi-pm-perl libjson-rpc-perl libnet-ldap-perl libxml-twig-perl \
  libfile-which-perl

同时安装可选模块对应的系统包(图表、邮件入站、字符集探测、邮件队列等增强功能,见 4.3 节功能对照):

DEBIAN_FRONTEND=noninteractive apt-get install -y \
  libgd-graph-perl libgd-text-perl libhtml-scrubber-perl \
  libencode-detect-perl libemail-reply-perl libhtml-formattext-withlinks-perl \
  libtheschwartz-perl libdaemon-generic-perl libfile-mimeinfo-perl \
  libcache-memcached-perl libfile-copy-recursive-perl libauthen-radius-perl

3.2 主机名与 FQDN(重要,务必先做)

Bugzilla 发送邮件时需要解析本机 FQDN(详见「排障实录 4」,这是一条真实踩坑:主机名不含域名点号时,发信在污点模式下直接报错)。部署前先规划一个 FQDN 主机名并配置:

hostnamectl set-hostname bz.example.org

并在 /etc/hosts 中保证「IP → FQDN 短名」解析(Ubuntu 标准 hosts 格式,FQDN 在前短名在后):

10.89.63.2	bz.example.org	bz

⚠️ 注意:很多部署指南跳过这一步,系统「看起来」一切正常,直到第一封 HTML 通知邮件触发 multipart 消息组装时才在运行时报 Insecure directory in $ENV{PATH}。把 FQDN 放在部署前置项,是为了让读者避开这条弯路。

四、部署步骤

4.1 下载官方源码包

官方下载页给出的 5.2 稳定版 tarball 直链为 https://ftp.mozilla.org/pub/webtools/bugzilla/5.2-branch/bugzilla-5.2.tar.gz。下载到 /usr/local/src:

cd /usr/local/src
curl -o bugzilla-5.2.tar.gz https://ftp.mozilla.org/pub/webtools/bugzilla/5.2-branch/bugzilla-5.2.tar.gz

实测记录:在本次部署的网络环境中,对 ftp.mozilla.org 的直连偶发超时,最终以下载重试完成;如果你的服务器同样位于受限网络,可显式走 HTTP 代理下载(curl 的 -x http://proxy:port 参数),或从官方仓库 git clone --branch release-5.2-stable https://github.com/bugzilla/bugzilla.git 换用 git 路径获取源码。

下载完成后校验完整性(实测文件 85,692,063 字节):

sha256sum bugzilla-5.2.tar.gz

实测回显:

6a2d66352456695fcdd1d0d7a9afe62fc2a94cc6217ebccc2b9b474d5c047b74  /usr/local/src/bugzilla-5.2.tar.gz

💡 说明:官方 tarball 未发布 sha256 清单,此哈希值来自本次实测下载文件,供后续读者对照参考;如哈希不一致,优先确认下载是否完整(文件大小是否为 85,692,063 字节),而非直接怀疑版本被篡改。

4.2 解压部署

cd /var/www/html
tar -xzf /usr/local/src/bugzilla-5.2.tar.gz
mv bugzilla-5.2 bugzilla
ls bugzilla | head

实测回显(目录核心内容):

Bugzilla
.htaccess
checksetup.pl
editparams.cgi
enter_bug.cgi
index.cgi
install-module.pl
localconfig
testserver.pl
template

解压后 localconfig 并不存在——它由第一轮 checksetup.pl 自动生成,这正是官方「安装器引导」设计的入口。

4.3 第一轮 checksetup.pl:模块体检

cd /var/www/html/bugzilla
./checksetup.pl

实测回显(节选,完整清单较长):

* This is Bugzilla 5.2 on perl 5.38.2
* Running on Linux 7.0.0-38-generic #38~24.04.4-Ubuntu SMP PREEMPT_DYNAMIC Mon Sep 14 16:37:11 UTC 2

Checking perl modules...
Checking for               CGI.pm (v3.51)     ok: found v4.63 
Checking for           Digest-SHA (any)       ok: found v6.04 
Checking for             TimeDate (v2.23)     ok: found v2.24 
Checking for             DateTime (v0.75)     ok: found v1.65 
Checking for    DateTime-TimeZone (v1.64)     ok: found v2.62 
Checking for                  DBI (v1.614)    ok: found v1.643 
Checking for       DBIx-Connector (v0.56)     ok: found v0.59 
Checking for                  Moo (v2.003004) ok: found v2.005005 
Checking for     Template-Toolkit (v3.008)    found v2.27 
Checking for         Email-Sender (v2.600)    ok: found v2.601 
Checking for     Email-Address-XS (v1.05)     ok: found v1.05 
Checking for           Email-MIME (v1.904)    ok: found v1.953 
Checking for                  URI (v1.55)     ok: found v5.27 
Checking for       List-MoreUtils (v0.32)     ok: found v0.430 
Checking for    Math-Random-ISAAC (v1.0.1)    ok: found v1.004 
Checking for              JSON-XS (v2.01)     ok: found v4.04 

Checking available perl DBD modules...
Checking for            DBD-mysql (v4.032)    ok: found v4.052 
Checking for           DBD-SQLite (v1.29)     not found 
Checking for               DBD-Pg (v2.7.0)    ok: found v3.18.0 
Checking for           DBD-Oracle (v1.19)     not found 
Checking for          DBD-MariaDB (any)       not found 

脚本末尾给出精确的补装命令(实测回显):

COMMANDS TO INSTALL REQUIRED MODULES (You *must* run all these commands
and then re-run checksetup.pl):

    /usr/bin/perl install-module.pl Template

To attempt an automatic install of every required and optional module
with one command, do:

  /usr/bin/perl install-module.pl --all

*** Installation aborted. Read the messages above. ***

同时实测发现 Apache 模块建议(checksetup 会扫描并提示需要启用的模块,实测回显节选):

* The modules you need to enable are:                                 *
*                                                                     *
*    mod_expires, mod_headers, mod_rewrite                            *

4.4 安装缺失的必装模块(Template 3)

按 checksetup 给出的命令执行(CPAN 安装,编译耗时视机器数分钟):

/usr/bin/perl install-module.pl Template

安装完成后验证版本:

perl -MTemplate -e 'print "Template $Template::VERSION\n"'

实测回显:

Template 3.106

可选模块方面,除 Chart / Template-GD / PatchReader 三个保持未装(分别对应图表报表与补丁查看器增强)外,其余可选模块均已由 3.1 节的系统包满足,第二轮 checksetup 中这些模块全部显示 ok(包括 GDTextUtil v0.86、GDGraph v1.56、HTML-Scrubber v0.19、TheSchwartz v1.12 等)。如需完整图表功能,可按提示执行 /usr/bin/perl install-module.pl Chart::Lines 等。

4.5 启用 Apache 模块

a2enmod expires headers rewrite cgi

实测回显:

Enabling module expires.
Enabling module headers.
Enabling module rewrite.
Enabling module cgi.

4.6 第二轮 checksetup.pl:生成 localconfig

./checksetup.pl

此轮所有必装模块通过(实测回显:Checking for Template-Toolkit (v3.008) ok: found v3.106),脚本走到参数文件生成阶段,末尾实测回显:

Reading ./localconfig...

This version of Bugzilla contains some variables that you may want to
change and adapt to your local settings. The following variables are
new to ./localconfig since you last ran checksetup.pl:

create_htaccess, webservergroup, use_suexec, db_driver, db_host,
db_name, db_user, db_pass, db_port, db_sock, db_check,
db_mysql_ssl_ca_file, db_mysql_ssl_ca_path, db_mysql_ssl_client_cert,
db_mysql_ssl_client_key, index_html, interdiffbin, diffpath,
site_wide_secret

Please edit the file ./localconfig and then re-run checksetup.pl
to complete your installation.

4.7 初始化 PostgreSQL 数据库

启动数据库服务并创建 Bugzilla 专用角色与库(本机 PostgreSQL 16.15):

service postgresql start
sudo -u postgres psql -c "CREATE USER bugs WITH PASSWORD 'q1w2e3r4';"
sudo -u postgres psql -c "CREATE DATABASE bugs OWNER bugs ENCODING 'UTF8' TEMPLATE template0;"
sudo -u postgres psql -c '\l'

实测回显(\l 节选):

                                 List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 bugs      | bugs     | UTF8     | en_US.utf8  | en_US.utf8  | 
 postgres  | postgres | UTF8     | en_US.utf8  | en_US.utf8  | 
 template0 | postgres | UTF8     | en_US.utf8  | en_US.utf8  | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8  | en_US.utf8  | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres

💡 说明:如果 PostgreSQL 与 Bugzilla 不同机,db_host 填数据库服务器地址,并记得配置 pg_hba.conf 允许 Bugzilla 主机以密码方式连接 bugs 库;同机部署(本文形态)默认 localhost 即可。

4.8 编辑 localconfig

localconfig 默认为 MySQL 形态的 apache 组配置,需要改四处。可直接编辑,也可用 sed 批量替换(实测命令):

cd /var/www/html/bugzilla
sed -i "s/^\$webservergroup = 'apache';/\$webservergroup = 'www-data';/;
        s/^\$db_driver = 'mysql';/\$db_driver = 'pg';/;
        s/^\$db_pass = '';/\$db_pass = 'q1w2e3r4';/" localconfig

修改后关键项实测值(即 4.6 节生成后仅有的手工改动):

$create_htaccess = 1;
$webservergroup = 'www-data';
$use_suexec = 0;
$db_driver = 'pg';
$db_host = 'localhost';
$db_name = 'bugs';
$db_user = 'bugs';
$db_pass = 'q1w2e3r4';
$db_port = 0;
$db_sock = '';
$db_check = 1;

⚠️ 注意:db_driver 的合法取值只有 mysql、mariadb、pg、oracle。写成直觉上的 pgsql 会直接报错(实测见「排障实录 2」),这不是笔误提示而是硬失败。Ubuntu/Debian 的 Apache 组是 www-data(默认模板写的 apache 是 RHEL 系习惯),不改会导致后续 checksetup 修权限时把目录组改成不存在的组。

4.9 第三轮 checksetup.pl:建库建管理员

./checksetup.pl

实测回显(关键段落):

Checking for               DBD-Pg (v2.7.0)    ok: found v3.18.0 
Checking for           PostgreSQL (v8.03.0000) ok: found v16.00.1500 
Checking for               DBD-Pg (v2.17.2)   ok: found v3.18.0 

Adding new table bz_schema...
Initializing bz_schema...
Creating tables...
Adding new index 'profiles_login_name_lower_idx' to the profiles table ...
Adding new index 'fielddefs_name_lower_idx' to the fielddefs table ...
Adding new index 'keyworddefs_name_lower_idx' to the keyworddefs table ...
Adding new index 'products_name_lower_idx' to the products table ...
Setting up choices for standard drop-down fields:
   bug_status op_sys priority bug_severity rep_platform resolution
Creating ./data directory...
Creating ./data/assets directory...
Creating ./data/attachments directory...
Creating ./data/db directory...
Creating ./data/extensions directory...
Creating ./data/mining directory...
Creating ./data/webdot directory...
Creating ./graphs directory...
Creating ./skins/custom directory...
Creating ./data/extensions/additional...
Creating ./data/mailer.testfile...
Creating ./Bugzilla/.htaccess...
Creating ./data/.htaccess...
Creating ./data/assets/.htaccess...
Creating ./data/attachments/.htaccess...
Creating ./data/webdot/.htaccess...
Creating ./graphs/.htaccess...
Creating ./lib/.htaccess...
Creating ./template/.htaccess...
Creating contrib/.htaccess...
Creating t/.htaccess...
Creating xt/.htaccess...
Precompiling templates...done.
Fixing file permissions...
Initializing "Product/Component Changes" email_setting ...
Initializing "Dependency Tree Changes" email_setting ...
Marking closed bug statuses as such...
Creating default classification 'Unclassified'...
Setting up foreign keys...
Setting up the default status workflow...
Creating default groups...
Setting up user preferences...

Looks like we don't have an administrator set up yet. Either this is
your first time using Bugzilla, or your administrator's privileges
might have accidentally been deleted.

Enter the e-mail address of the administrator: Enter the real name of the administrator: stty: 'standard input': Inappropriate ioctl for device
Enter a password for the administrator account: 
Please retype the password to verify: stty: 'standard input': Inappropriate ioctl for device

admin@example.com is now set up as an administrator.
Creating initial dummy product 'TestProduct'...

Now that you have installed Bugzilla, you should visit the 'Parameters'
page (linked in the footer of the Administrator account) to ensure it
is set up as you wish - this includes setting the 'urlbase' option to
the correct URL.
checksetup.pl complete.

交互环节输入内容为:管理员邮箱 admin@example.com、真实姓名 admin、密码 q1w2e3r4(两次)。回显中出现的 stty: 'standard input': Inappropriate ioctl for device 是本次实测通过管道喂入交互输入导致的 stty 提示(脚本正常关闭终端回显以隐藏密码),在真实终端交互时不会出现,可忽略。

checksetup.pl 至此完成:数据库 schema 就绪、data/ 目录与 .htaccess 体系生成、模板预编译、管理员创建、初始产品 TestProduct 建好。

4.10 配置 Apache 站点

创建 /etc/apache2/conf-available/bugzilla.conf(实测最终生效内容):

Alias /bugzilla /var/www/html/bugzilla

<Directory /var/www/html/bugzilla>
    AddHandler cgi-script .cgi
    Options +ExecCGI
    DirectoryIndex index.cgi index.html
    AllowOverride All
    Require all granted
</Directory>

启用站点并启动 Apache:

a2enconf bugzilla
service apache2 start

⚠️ 注意:AllowOverride All 不是可有可无的宽松配置——Bugzilla 自动生成的 .htaccess 在 <FilesMatch> 段中使用 Require 指令保护 localconfig 等敏感文件,Apache 默认的 AllowOverride Limit FileInfo Indexes Options 不足以放行它,实测会得到 500 错误(详见「排障实录 3」)。

五、部署验证

5.1 官方自检脚本 testserver.pl

cd /var/www/html/bugzilla
./testserver.pl http://localhost/bugzilla/

实测回显:

TEST-OK Webserver is running under group id in $webservergroup.
TEST-OK Got padlock picture.
TEST-OK Webserver is executing CGIs via mod_cgi.
403 Forbidden
TEST-OK Webserver is preventing fetch of http://localhost/bugzilla/localconfig.
TEST-WARNING Failed to run gdlib-config; can't compare GD versions.
TEST-OK GD library generated a good PNG image.
TEST-FAILED Chart::Lines is not installed.
TEST-FAILED Template::Plugin::GD is not installed.

判读:四个 TEST-OK 覆盖了 web 服务器组、静态资源、CGI 执行、敏感文件保护;403 Forbidden 后跟 TEST-OK 是预期行为(验证 localconfig 不可被 HTTP 拉取);GD 相关仅影响图形报表,一条 WARNING 两条 FAILED 均为可选功能缺失,不影响核心运行。要消除这三条,安装 Chart::Lines 与 Template::Plugin::GD 模块即可。

5.2 HTTP 访问验证

curl -sI http://localhost/bugzilla/ | head -1
curl -s http://localhost/bugzilla/index.cgi | grep -oE '<title>[^<]*</title>'

实测回显:

HTTP/1.1 200 OK
<title>Bugzilla Main Page</title>

浏览器访问 http://<服务器IP或域名>/bugzilla/,右上角 Log In 使用 admin@example.com / q1w2e3r4 登录即可进入管理界面。首次登录后建议立即做的两件事:在 Parameters 页设置 urlbase(否则邮件里的链接不完整)、把 mail_delivery_method 改为你的真实邮件投递方式(部署环境未配置 MTA 时可先用 Test 落盘验证)——参数体系详见《Bugzilla 配置参数详解》。

六、排障实录

以下四条均为本次部署实测真实发生的问题,按遇到顺序记录。

排障实录 1:Template-Toolkit 版本不满足,checksetup 拒绝继续

现象:第一轮 checksetup.pl 在模块清单中报 Checking for Template-Toolkit (v3.008) found v2.27,并在 REQUIRED MODULES 区块中止安装。

原因:5.2 稳定线把模板引擎最低版本提升到 3.008,而 Ubuntu 24.04 仓库的 libtemplate-perl 停在 2.27。这是 5.2 相对 5.0 系列最典型的版本约束。

解决:按 checksetup 给出的命令 /usr/bin/perl install-module.pl Template 从 CPAN 安装(实测装得 3.106),重新 checksetup 即过。不建议手工升级系统包,install-module.pl 会把模块装到 Bugzilla 目录的 lib/ 下,与系统包隔离、升级安全。

排障实录 2:db_driver 写成 pgsql 直接报错

现象:编辑 localconfig 时按直觉把数据库驱动写成 $db_driver = 'pgsql';,第三轮 checksetup 立即中止,实测报错原文:

pgsql is not a valid choice for $db_driver in./localconfig at Bugzilla/DB.pm line 193, <DATA> line 960.

原因:Bugzilla/Constants.pm 中 DB_MODULE 定义的合法驱动键名为 mysql、mariadb、pg、oracle,pgsql 不是合法枚举值(尽管 DBD 驱动名恰好叫 DBD::Pg)。

解决:改为 $db_driver = 'pg'; 后重跑即通过。

排障实录 3:首页 500,日志报 Require not allowed in <FilesMatch> context

现象:Apache 启动后访问 /bugzilla/ 返回 500,/var/log/apache2/error.log 实测报错:

[core:alert] /var/www/html/bugzilla/.htaccess: Require not allowed in <FilesMatch> context

原因:Bugzilla 自动生成的 .htaccess 在 <FilesMatch> 段用 Require 指令封锁敏感文件;Apache 对 .htaccess 中指令的放行由 AllowOverride 控制,初始配置写了 AllowOverride Limit FileInfo Indexes Options,不含 AuthConfig(Require 属于授权类指令),导致 .htaccess 解析失败、整个目录 500。

解决:AllowOverride All(本地配置文件已由 root 完全掌控时无额外风险;更保守的替代是加入 AuthConfig),重启 Apache 后恢复 200。

排障实录 4:发信 500,报 Insecure $ENV{PATH}(Sys/Hostname/Long.pm line 82)

现象:部署完成后通过 REST/API 或界面触发 bug 变更(操作会发送通知邮件),请求报 500,错误消息实测为:

Insecure directory in $ENV{PATH} while running with -T switch at /usr/share/perl5/Sys/Hostname/Long.pm line 82.

原因链(逐层实测定位):

  1. Bugzilla 以污点模式(perl -T)运行,Bugzilla.pm 在初始化时删除 %ENV 中的 PATH(源码注释明确「Some environment variables are not taint safe」);
  2. 构建 HTML 格式通知邮件时产生 multipart 消息,Email::MIME 需要生成 MIME boundary,其实现调用 Email::MessageID,后者调用 Sys::Hostname::Long::hostname_long() 解析本机 FQDN;
  3. Sys::Hostname::Long 的解析方法链中,当 POSIX uname 返回的主机名不含点号(如 bzserver)时,会退化为反引号执行 hostname --fqdn,而反引号在污点模式下要求可用的 PATH——已被 Bugzilla 删除,于是抛出 Insecure 错误。

解决:给主机配置含点号的 FQDN,让 uname 直接返回完整域名,方法链在第一步就命中,完全绕开反引号。实测修复动作(对应 3.2 节前置项):

hostnamectl set-hostname bz.example.org
# /etc/hosts 增加:10.89.63.2 bz.example.org bz

修复后验证(实测):

su www-data -s /bin/sh -c 'perl -T -MSys::Hostname::Long -e "print hostname_long(), qq{\n}"'
bz.example.org

随后重新触发 bug 变更,通知邮件正常生成(mail_delivery_method=Test 模式下可在 data/mailer.testfile 看到带 multipart 边界与 Message-ID 的完整信件)。

经验总结:这类「装完一切正常、一封邮件打回原形」的问题根源在部署时序——FQDN 属于邮件功能的前置依赖。另外,若你的环境因故无法配置 FQDN,临时规避可把用户通知格式设为纯文本(settings 中 email_format=text_only,单部件消息不触发 boundary 生成)或保持 mail_delivery_method=None,但都不是长期解。

七、参考链接