news 2026/9/25 4:55:19

Mailcow邮件服务器部署实战:用Docker Compose打造自建邮箱系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Mailcow邮件服务器部署实战:用Docker Compose打造自建邮箱系统

简介:Mailcow是基于Docker容器化技术构建的开源邮件服务器整合方案,将SMTP/IMAP/POP3/Webmail、反垃圾、反病毒以及DKIM/DMARC/SPF安全认证统一封装,适用于需要自主掌控邮件数据的运维工程师、中小型企业IT部门及邮件系统二次开发者。资源共2000个文件,核心为1515个PHP源码文件,支撑Webmail界面与API逻辑;另有Shell/Python脚本、Dockerfile与YAML编排文件,便于完成容器部署、定时任务与自动化维护;JSON/XML/conf类文件则承载服务配置和日志收集规则,Markdown文档提供使用说明。压缩包仅10.98MB,整体精简,目录清晰。已有200人学习下载,适合快速搭建邮件环境或研读容器化部署细节。通过源码和配置可了解邮件收发链路、密钥管理及SPF/DKIM/DMARC校验的实际落地,为自建邮件系统的运维排错提供直接参考。

1. Mailcow不是又一个邮件系统:它把半个邮件机房塞进了 Docker Compose

如果你只是想给一个小团队配上可用、可控的自建邮件服务,可以先看一眼传统路径:Postfix负责收发投递,Dovecot管IMAP/POP3,Rspamd拦垃圾信,ClamAV扫毒,SOGo或LDAP提供通讯录和账号,再写一堆脚本让它们互相认识。等你把这一套手工拼完,往往发现最大的成本不是安装本身,而是日后的维护。Mailcow是一个功能丰富的开源邮件服务器解决方案,把这些组件固化进一套Docker编排,用几条命令就能把整套邮箱系统拉起来。它适合不想为邮件搭建和维护细节耗时间,又希望邮箱真正掌握在自己手里的团队和个人。

我在还只会手工搭Postfix的年代,光是把SPF、DKIM、DMARC三条记录调到让Rspamd不打负分就花了一个周末。换到Mailcow之后,这套组合默认就带着反垃圾、杀毒、Web邮箱和管理后台,部署节奏完全变了。下面这些内容,按我从零上手到接手生产的顺序来写,新手能照着跑通,熟手可以直接看参数和坑。

2. 动手前先看懂这套架构:容器清单、端口占用与资源预算

Mailcow看起来是一条命令启动,但它内部不是一个单体,而是一组协作的容器。如果你不明白每个容器负责什么,排障时会很被动:Dovecot报错你会去看Postfix日志,Rspamd拒绝收信你又去找ClamAV,来回浪费好几个小时。所以我建议先花十分钟把架构立住,再动手安装。

2.1 容器全家桶:Postfix、Dovecot、Rspamd 在 Mailcow 里分别是干哪一块的

默认情况下,Mailcow 管理着下面这些容器,各自的角色基本稳定:

容器职责我一般什么时候会用到它
nginx提供 Web 入口和 TLS 终结,管理界面、SOGo、API 都从它进来打不开控制台、证书异常时
postfixSMTP 收发投递,是邮件进出的大门查队列、看退信、排查收不到信
dovecotIMAP/POP3 服务,以及邮件存储和检索客户端连不上、迁移邮箱时
rspamd垃圾邮件评分,承担 DKIM/ARC 签名看为什么进垃圾箱、调整过滤
clamd病毒扫描发现带毒附件时
sogoWeb 邮箱、日历、通讯录用户说网页邮箱打不开
phpfpm运行 Mailcow 管理后台的 PHP 逻辑后台报 502 时查它
mysql域名、邮箱账号、别名、配置等元数据备份、恢复、批量建账号
redis缓存,给 Rspamd 和 UI 做辅助内存不足时先考虑它
unbound本地 DNS 解析缓存系统 DNS 慢导致投递延迟时
acme申请和续签 Let's Encrypt 证书证书明明存在却过期了
watchdog检查容器健康状态,异常时自动拉起容器反复重启时看它的判定

这套分工不是随意的:Postfix 负责对外说“我能收信”,Dovecot 负责“收进来的信现在能取走”,中间无数封被判定为垃圾或带毒的信件,由 Rspamd 和 ClamAV 在 Postfix 一侧拦截。Mailcow 把这条链路写死在 Compose 编排里,让它从一堆服务变成了一个可复制、可恢复的整体。

这对运维的好处很明显:单容器崩溃可以被 watchdog 拉起来;日志通过 docker compose logs 统一查看;改动参数不需要逐个改配置文件,多数入口都收敛到了后台和 mailcow.conf。坏处是你要接受它的整体性,不能随便替换某个组件版本,所以后面会反复提到“固定镜像 tag”。

2.2 内存磁盘与 25 号端口的账:部署前先算清三笔账

第一笔账是内存。官方最低要求 4GB,但真实跑起来我建议至少 6GB。我见过一台 4GB 云主机装完 Mailcow,MySQL、Redis、Rspamd、ClamAV 一起预热,内存曲线直接顶到 3.8GB,再来一次全量杀毒就触发 swap。如果还要跑 SOGo 并让几十人同时用网页邮箱,8GB 会更稳。

第二笔账是磁盘。下载镜像并完成首次启动后,系统盘占用大约在 1GB 到 2GB 之间,具体看你拉的是完整版本还是精简版。这还只是开始:邮件正文和附件会持续增长,MySQL 里保存账号和域名配置,日志会写满 /var/lib/docker 目录。我习惯把容器数据目录放在独立分区或 LVM 上,这样磁盘增长时可以扩容,不会因为一个分区满了带着整个系统动不了。

第三笔账是端口。Mailcow 默认要绑定以下端口:

端口用途
25SMTP 收信,出站投递也用它
80HTTP 跳转和 ACME 验证
443HTTPS 管理界面和 SOGo
587邮件客户端提交发信
143 / 993IMAP / IMAPS
110 / 995POP3 / POP3S

最容易被忽视的是 25 端口。很多云厂商默认不开放入站 SMTP,你在服务器上telnet mail.example.com 25是通的,但外域投递进来直接 Connection refused。遇到这种情况先找服务商开放 25 端口,同时把服务器 IP 的反向 PTR 记录做好,否则即使开了端口,对方也可能因为 PTR 缺失而降分拒收。

另外,如果这台机器上已经跑了 Nginx 或其他 Web 服务,80 和 443 会被占用。启动前先用ss -lntp | grep -E ':(80|443)'检查一下,避免起容器时端口冲突。当时我在一台跑着监控面板的机器上装 Mailcow,就是因为 443 被占,折腾了二十分钟才找到原因。

3. 用 Compose 把 Mailcow 跑起来:最小部署与四个必调参数

这一章的目标是让你在一台干净的系统上,把 Mailcow 拉到能创建邮箱、能正常收发。中间我会把每一步背后的逻辑讲清楚,而不是给你一串黑匣子命令。

3.1 拿到源码包之后:生成配置、改 hostname 和时区

最常见的做法是把 Mailcow 的官方仓库 clone 到 /opt 下。仓库名是 mailcow-dockerized,clone 完进入目录后,先执行它的配置生成脚本:

cd /opt git clone https://github.com/mailcow/mailcow-dockerized.git cd mailcow-dockerized ./generate_config.sh

这个脚本会交互式问几个问题,最重要的是邮件服务器的主机名,它决定了你对外的 SMTP 欢迎头和 Web 地址。注意这里填的不是域名裸域,而是一个子域,比如 mail.example.com。填错了后面很多配置都要连带改,所以宁可在这一步想清楚。

脚本跑完会生成 mailcow.conf。我一般会立刻检查几个参数:

nano mailcow.conf

关键参数有三个。MAILCOW_HOSTNAME是刚才填的邮件服务器主机名,必须是一个能解析到公网 IP 的 A 记录地址。TZ是时区,国内服务器建议改成 Asia/Shanghai,否则日志和后台时间会差八个小时。还有一个是HTTP_PORT和HTTPS_PORT,如果你没有让出 80 和 443,可以在这里改到高位端口,但我建议最好还是把原来的服务挪走,否则后面证书申请和邮件接收都会遇到额外麻烦。

3.2 三行命令启动:看懂 compose up 背后的初始化流程

配置生成后,启动只需要三条命令:

docker compose pull docker compose up -d docker compose ps

docker compose pull会把所有容器镜像拉全。Mailcow 使用的镜像比较多,这一步在部分网络环境下可能很慢,建议先保证 Docker Hub 可以正常访问,再开始部署。docker compose up -d是正式创建并启动容器组,第一次启动时 MySQL 会在 /mailcow-dockerized 数据目录里初始化库,watchdog 会检查其他容器是否健康。最后docker compose ps用来确认所有容器处于 Up 状态。

如果启动过程中某容器反复重启,看日志是第一步:

docker compose logs -f mysql docker compose logs -f watchdog

比如我遇到过 MySQL 起不来,原因是数据目录权限在之前的手动启动中被打乱,日志里直接显示权限错误。这时用chown -R root:root或调整目录属主后重启即可。不要急着把所有容器删掉,先定位哪个容器不健康。

首次启动完成后,浏览器打开 https://mail.example.com。默认管理员账号是 admin,初始密码是 moohoo,第一次登录会强制你改成自己的强密码。这个默认密码是公开知识,所以最好在部署完成后立即修改,不要留到第二天。

3.3 DNS 接管与首次登录:MX、SPF、DKIM、DMARC 的落地样板

后台登录后,在“配置”里添加上你的域名,例如 example.com。Mailcow 会为该域名自动生成 DKIM 密钥,并在域名管理页面列出它要求的 DNS 记录。你不需要凭记忆手写,直接把页面里的记录抄到 DNS 服务商即可。

以 example.com 为例,完整记录至少包含:

类型主机/名称值作用
Amail你的服务器公网 IP让 mail.example.com 可解析
MXexample.commail.example.com(优先级 10)别人知道该往哪里投递
TXTexample.comv=spf1 a mx ip4:服务器IP -all授权合法发信 IP
TXTdefault._domainkey.example.comv=DKIM1; k=rsa; p=...给收件方验签
TXT_dmarc.example.comv=DMARC1; p=quarantine; rua=mailto:postmaster@example.com接收方按 DMARC 策略处理

注意 SPF 里的ip4:一定要写这台服务器实际发信的出口 IP。如果邮件用 Mailcow 直发,不要使用某些云厂商的默认 SPF,否则会把自己排除在合法发信源之外。

配置完成后,我一般用几条命令确认:

dig MX example.com dig TXT default._domainkey.example.com dig TXT example.com

如果这些记录都返回了对应值,再用一个外部邮箱给这台邮件服务器发信测试。此刻不要急着通知团队切 MX,先把收发链路验证完,尤其是外域来信能不能进收件箱、发出去的邮件会不会进垃圾箱。

4. 邮件服务器避坑:部署 48 小时内最容易翻车的五个地方

邮件服务器不像普通 Web 服务,不是监听了端口就算成功。它需要接受来自全世界的投递和检测,而每个环节都可能因为一个小配置而失败。以下五个坑是我在 Mailcow 和手工邮件系统里都踩过的,每一条都按现象、原因、解决来写。

4.1 收不到外域邮件:先查 PTR、25 端口与发件 IP 信誉

现象:内部互相发信正常,但 Gmail、163 等外部邮箱给你发信时收到退信,退信内容常见 “Connection refused” 或 “host does not accept email”。

原因有两个。第一是服务器所在机房的 25 端口入站没有放行;第二是 IP 反向解析缺失,对方在连接前查 PTR 发现 mail.example.com 和你的 IP 对不上,直接拒绝连接。

解决:先到服务器上看 25 端口在不在监听:

ss -lntp | grep :25

如果监听正常,再用本机测试:

telnet mail.example.com 25

连接成功后会返回带主机名的 SMTP 欢迎语。如果连接超时,去机房控制台或找服务商放行 25 端口。接着做反解:到服务商后台为这个 IP 配置 PTR,值为 mail.example.com。PTR 解析生效需要一段时间,通常几小时到一天,配置完可以用dig -x 你的服务器IP验证。

4.2 发信进垃圾箱:SPF 没生效与 Rspamd 评分被抬高的连锁反应

现象:你用 Mailcow 发出去的邮件能送达,但收件人那边直接进了垃圾箱。尤其发往 Gmail 或腾讯企业邮箱时,概率很高。

原因:SPF 记录配置错误或未生效,使得你的发件 IP 被判定为未授权;另一个隐性原因是服务器公网 IP 此前被用于群发,段位信誉已经不好。Mailcow 里 Rspamd 会在投递前对邮件做 DKIM 签名,但如果 SPF 检查不过,DMARC 对齐也会失败,整体分数被打得很高。

解决:在 DNS 服务商确保 SPF 记录包含该服务器的 A 记录和 IP。我见过最坑的写法是v=spf1 -all,这等于宣布自己从来不发信,Mailcow 投出的信自然被外部拒绝。修正为下面的常见写法:

v=spf1 a mx ip4:你的服务器IP -all

改完等 DNS 生效后,在 Rspamd 后台的 History 里看正在发出的邮件,确认 SPF 和 DKIM 两项显示 pass。如果 IP 信誉确实差,短期内只能更换发信 IP,或者先把 DMARC 从 p=quarantine 提到更加严格的策略,等信誉恢复。

4.3 Web 管理界面打不开:443 被占用和证书没签出来的区别

现象:启动后 docker compose ps 全部正常,但浏览器访问 https://mail.example.com 提示安全连接失败,或者干脆一直转圈。

原因:一是服务器上已有 Nginx 或其他服务占用了 443,Mailcow 的 nginx 容器无法绑定,只能在内部进入,外部访问撞到旧服务;二是 acme 容器在首次申请证书时失败,导致 Nginx 没有拿到 ssl_certificate。

解决:先看 nginx 容器日志:

docker compose logs -f nginx

如果看到 bind: address already in use,说明 443 被占。最简单的做法是把占用 443 的服务停掉,或把 Mailcow 的 HTTPS_PORT 改到 8443,但 8443 会给后续收信和客户端配置增添变数,最佳方案还是把端口让出来。

如果是证书申请失败,日志里会显示 acme_challenge 失败,比如 HTTP-01 验证无法完成。原因通常是域名的 A 记录还没指向这台服务器,或 80 端口没有映射。检查 DNS 记录确实指向本机后,重启 acme 容器重新签发:

docker compose restart acme

证书申请是异步的,重启后等几分钟再刷新页面。

4.4 日志和临时文件把磁盘写满:Docker 日志轮转总要自己动手

现象:运行一两个月后,系统突然提示磁盘满,docker 目录占用巨大,邮箱收信开始失败。

原因:Docker 默认不限制单个容器日志文件大小。Nginx、Postfix、Rspamd 每天都会产生大量标准输出日志,/var/lib/docker/containers/ 下的 json.log 能长到几 GB。加上 ClamAV 的病毒库和临时文件,磁盘很快被吃光。

解决:在不重启所有容器的前提下,可以先把当前日志置空:

truncate -s 0 /var/lib/docker/containers/*/*-json.log

但这是临时止血。持久做法是修改 Docker daemon 配置,在 /etc/docker/daemon.json 里加入:

{ "log-driver": "json-file", "log-opts": { "max-size": "50m", "max-file": "3" } }

然后重启 Docker 服务让配置生效。已经存在的容器不会自动读取新配置,下次重建容器时才会应用。同时建议对 /var/lib/docker 做一次周期性监控,或者直接在服务器上写一个 cron 每天 truncate 一次各容器日志。

4.5 升级大版本爆红:备份 MySQL 与固定镜像 tag

现象:看到 Mailcow 有新版,直接docker compose pull后重启,界面开始报 502,或 MySQL 连接失败。

原因:全量与中间版本之间可能有数据库结构变更,你跳过了中间版本,且运行中的 MySQL 数据与新版镜像不兼容。另一个常见原因是有人把 mailcow.conf 里的镜像版本改成了 latest,一拉就拉到未来版本。

解决:升级前先备份。常见做法是使用 Mailcow 自带的 helper 脚本生成完整备份包,具体命令下一章会讲。升级时不要直接 pull 所有镜像,而是看官方更新说明,按当前大版本逐步升。固定镜像 tag 的做法是查看 docker-compose.yml 中每个镜像的具体版本标签,不要手动改成 latest。

如果已经升级失败,最快的后悔药是从刚才的备份恢复 MySQL 数据容器,再回到原 tag 启动。备份文件要同时回滚,否则邮件数据新、数据库旧,Dovecot 和 Postfix 之间也会对不上账号结构。

5. 让 Mailcow 变成生产力:API 批量建号、备份恢复与性能线

到这一步,邮件服务器已经能正常收发。接下来要做的是把它从“能用的玩具”变成“能托付业务的工具”。对于管理员来说,最花时间的不是装系统,而是反复建账号、备份、调性能。

5.1 用 Mailcow API 批量建邮箱:给 300 个新同事发账号的脚本

Mailcow 自带了 API,后台在“系统”菜单里可以创建 API Key。常见用法是给一个只读或可写 Key,然后通过 HTTP 请求管理域名和账号。

我一般用 curl 验证单个账号是否能创建成功:

curl -sS -X POST "https://mail.example.com/api/v1/add/mailbox" \ -H "X-API-Key: 你的API_KEY" \ -H "Content-Type: application/json" \ -d '{ "domain": "example.com", "local_part": "zhangsan", "password": "Init@2025", "password2": "Init@2025", "active": "1", "quota": "10" }'

这里的local_part是 @ 前面的部分,quota单位是 GB,active为 1 表示启用。注意不同版本对参数名可能略有调整,我建议先用后台手工建一个账号,再对比 API 返回的 JSON 结构,确认字段没问题后再批量跑。

批量创建时,我习惯先准备一个 CSV 或读取一个名字列表:

import requests url = "https://mail.example.com/api/v1/add/mailbox" headers = {"X-API-Key": "你的API_KEY", "Content-Type": "application/json"} users = [ {"local_part": "user01", "password": "Init@2025"}, {"local_part": "user02", "password": "Init@2025"}, ] for user in users: payload = { "domain": "example.com", "local_part": user["local_part"], "password": user["password"], "password2": user["password"], "quota": "10", "active": "1", } r = requests.post(url, json=payload, headers=headers, verify=False) print(user["local_part"], r.status_code, r.text)

verify=False是因为在某些环境中 API Key 对应的证书链不完整,生产环境建议去掉它并把证书配好。批量建号最大的坑是密码策略,Mailcow 默认对密码长度有要求,脚本里如果生成太短的密码,API 会返回校验失败,最好在脚本里统一按 8 位以上混合密码生成。

5.2 备份不是 tar 一个目录:helper.sh 的真正用法与恢复演练

很多管理员第一次备份 Mailcow,就是把/opt/mailcow-dockerized整个目录 tar 一下。这样备份不是完全没用,但恢复时很可能发现账号和域名对不上,因为 MySQL 数据目录和邮件附件并不在同一层,只 tar 当前目录容易漏掉 Docker volume 里的实际数据。

官方 helper 脚本是更省心的备份方式:

cd /opt/mailcow-dockerized ./helper.sh backup

执行完成后,脚本会在 backup 目录下生成一个带日期时间戳的 tar 包,里面包含了 MySQL 逻辑备份、密钥配置、账号列表和附件数据。由于内容较多,第一次备份时磁盘 IO 会明显升高,建议放在业务低峰期跑。

恢复同样走 helper:

./helper.sh restore /opt/mailcow-dockerized/backup/mailcow-2025-06-01-XXXX.tar.gz

恢复过程会先停止关键容器,把备份包里的数据目录和数据库释放回当前位置,再重新启动。执行前先把当前目录另存一份,避免恢复出错后连回到原状态的机会都没有。

我个人的习惯是每周全量备份一次,每天用 cron 把 helper 生成的备份包同步到另一台服务器或对象存储。邮件服务器最先丢的不是机器,而是数据。恢复包如果只存在同一块磁盘上,磁盘损坏时根本来不及后悔。每月至少做一次恢复演练,恢复到一台临时虚拟机,打开管理界面看账号数量和最后一封邮件是否完整。

5.3 性能调优的三个调节阀:邮件大小、Rspamd 内存与连接数

邮件服务器很少需要极限调优,但三个参数值得先看一眼。

第一个是邮件大小上限。Postfix 默认限制单封邮件大小,如果团队经常发大附件,会发现投递频繁被退。Mailcow 把这个参数收敛到了 mailcow.conf 里,常见做法是设为 25M:

POSTFIX_MESSAGE_SIZE_LIMIT=25

改完运行docker compose up -d让 postfix 容器重新读取。注意邮件大小限制不止出现在发送端,客户端也要认这个上限,别把 Mailcow 当网盘。

第二个是 Rspamd。Rspamd 对内存比较敏感,在高并发扫描时它会占用不少内存。如果观察到系统内存长期告警,常见做法是减少 Rspamd 并发 worker 数量,或在后台关闭不需要的过滤器。不要一味增加 worker,往往效果不大,反而让 MySQL 的缓存被压缩,整体更慢。

第三个是连接数。Dovecot 默认的连接数对于百人团队是绰绰有余的,真正需要调的是客户端短连接频繁建立带来的新建连接压力。我一般会建议客户端保持长连接,并在同一台机器上把文件描述符上限调到足够大:

ulimit -n 65535

检查连接数最简单的方法是看 Dovecot 日志里有没有 “Too many open files”。如果频繁出现,先调系统限制,再调 Dovecot 配置。四个容器同时日志警告时,先加文件描述符,再考虑换更大的机器。

6. 把旧邮箱迁进 Mailcow:一条 dsync 命令和我的迁移顺序

Mailcow 已经能收发新信,但很多团队手里还有旧邮箱里的历史邮件要保留。迁移这些老邮件,我推荐用 imapsync 而不是在客户端里拖拽。客户端拖拽几百封没问题,一旦超过上万封,断点续传和去重会让你崩溃。

先在新 Mailcow 上把邮箱账号建好,然后执行:

imapsync \ --host1 oldmail.example.com --user1 olduser@example.com --password1 '旧密码' \ --host2 mail.example.com --user2 olduser@example.com --password2 '新密码' \ --addheader --ssl1 --ssl2

host1是旧邮箱服务器,host2是 Mailcow 的地址,--addheader会在迁移的邮件头里增加一行标记,方便后续查重和排障。--ssl1 --ssl2表示两端都用加密连接。首次迁移会遍历全部目录和邮件,耗时和邮件数量成正比,建议放到夜间执行。

我自己的迁移顺序是:先在 Mailcow 建一个测试账号,迁一部分邮件进来,客户端连上用两天;确认主要功能没问题后,再把旧域名的 MX 记录切到 Mailcow;MX 切换生效后,再对剩余账号做一次增量同步,把旧服务器上新增的邮件补过来。不要直接改 MX 再慢慢迁,这样新旧服务器都会收到信,邮件会裂成两半。

切换 MX 前三天,我通常会把旧记录的 TTL 从默认的 3600 调低到 600。这样如果 Mailcow 这边出了状况,回滚旧服务器的速度会快得多。等全部账号增量同步完成、旧服务器确认没有遗漏后,再删掉旧账号和旧的 DNS 记录。跑完一段迁移后你会发现,真正让你放心的不是 imapsync 的参数,而是每一步都有回退路径。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 4:55:08

代码评审、智能体运行与AI文本优化的工程实践指南

1. 这期周刊不是“新闻简报”,而是开发者日常痛点的集中爆破现场你有没有过这样的体验:凌晨两点改完最后一行代码,点开 GitHub 提交 PR,心里刚升起一丝欣慰,下一秒就被 Code Review 里密密麻麻的红色批注钉在屏幕前——…

作者头像 李华
网站建设 2026/9/25 4:54:21

机械仪表与自动化会议论文投稿指南:EI/Scopus检索与见刊策略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 4:54:13

IEEE TGRS投稿全攻略:从选题到审稿的实战经验

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 4:54:04

活码系统设计原理:动态路由与生命周期管理实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 4:52:59

Local Human Agent:在 ParlAI 中用命令行键盘与对话模型实时交互

NLP人工智能深度学习 【免费下载链接】ParlAI A framework for training and evaluating AI models on a variety of openly available dialogue datasets. 项目地址: https://gitcode.com/gh_mirrors/pa/ParlAI 点击查看 免费下载 Local Human Agent(l…

作者头像 李华
网站建设 2026/9/25 4:52:15

ESP32-C3 给 RP2040 当管家:远程烧录、自动复位与日志上云方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华