thunderbird / thunderbird/dns-scripts
Add DigitalOcean provider support
@rtanglao is already working on this.
Since Jul 22, 2026.
- Dominant language
- HTML
- Stars
- 3
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Add DigitalOcean provider support
Add digitalocean as a remediation provider in records.json so both the CLI
(--provider digitalocean) and the web app emit DigitalOcean-control-panel-specific
fix instructions for the 13-record Thundermail set (1 MX, 5 SRV, 4 TXT, 3 DKIM CNAME).
Internal ticket: TBPRO 7012
(7012_DNS_DIGITAL_OCEAN).
⚠️ Ship as UNVERIFIED first. The SRV field layout below is confirmed from a
screenshot of the live DigitalOcean Create a record dialog; the MX/TXT/CNAME field
labels come from DigitalOcean's official
How to Create, Edit, and Delete DNS Records
docs, not a live add-record screenshot. Follow the godaddy/ionos/ovh/hover precedent:
prefix each header stringUNVERIFIED —until confirmed end-to-end, then drop the
prefix.
🎯
example.comis the verification target — it's DigitalOcean-hosted
(ns1/ns2/ns3.digitalocean.com). Query it authoritatively with
--resolver ns1.digitalocean.com.
✅ The trailing-dot rule is now confirmed live on
example.com. Its 5 SRV records were
entered without a trailing dot, so DigitalOcean appended the zone name to the target:$ dig +short SRV _jmap._tcp.example.com 0 1 443 mail.thundermail.com.example.com. # should be mail.thundermail.comThis proves DigitalOcean SRV targets must be entered as
{target}.with the trailing
dot. (Its MX target came back correctly asmail.thundermail.com., so confirm whether MX
tolerates a missing dot or was simply entered with one.) ⚠️ Note the checker currently
reportsexample.comas a false 13/13 because of an unanchored substring match — see
#10; that bug should be fixed so these broken SRV targets show as FAIL.
Add-record model
DigitalOcean uses a single "Create a record" dialog with a Record Type dropdown (like
bunny/godaddy/hover, not per-type sections like cosmotown).
Path: Control Panel → Networking → Domains → select your domain → Create a record →
choose Record Type, fill fields, Create Record. TTL defaults to 3600.
Key conventions (from the docs + the live SRV screenshot):
- Apex host = literal
@for MX and TXT ("Use @ to create the record at the domain
root"). This is the{host}/@pattern likegodaddy/ionos/hover, not the
blank-apex pattern ofbunny/cosmotown/ovh. - SRV keeps the
_service._protocollabel combined in the Hostname field (the
screenshot placeholder is literallye.g. _service._protocol, one field). DigitalOcean
does NOT split Service/Protocol into separate inputs the waygodaddy/ionos/hover
do — so use{host}and not the{service}/{protocol}tokens. - ⚠️ Targets require a trailing dot. The SRV Will direct to doc is explicit: an FQDN
must be entered "with a period (.) at the end. This distinguishes it from a subdomain
prefix" — otherwise DigitalOcean appends your domain. Since all our targets are external
FQDNs (mail.thundermail.com,tmN.<domain>.dkim.thunderhosted.com), encode targets as
{target}.(same trailing-dot handling asovh). Confirm this also applies to the MX
"Mail provider's mail server" and CNAME "Is an alias of" fields (the docs only spell it
out for SRV, but DO's general behaviour is to append the domain when no dot is present). - No new interpreter token needed —
{host},{target},{value},{priority},
{weight},{port}already cover everything.
Field mapping
SRV field order matches the screenshot (Record Type → Hostname → Will direct to → Port →
Priority → Weight → TTL):
| Type | Fields (DigitalOcean label → value) |
|---|---|
| MX | Type=MX, Hostname={host} (@), Mail provider's mail server={target}., Priority={priority} |
| SRV | Type=SRV, Hostname={host} (_jmap._tcp), Will direct to={target}., Port={port}, Priority={priority}, Weight={weight} |
| TXT | Type=TXT, Hostname={host} (@), TXT Value={value} |
| CNAME | Type=CNAME, Hostname={host}, Is an alias of={target}. |
Note: SPF, MTA-STS, TLSRPT and DMARC are all plain TXT records on DigitalOcean (the
docs note SPF/DKIM are "special TXT records" created via the TXT option) — DKIM here is a
CNAME, so it uses the CNAME form.
Work items
- Add the
digitaloceanprovider block torecords.json(headersUNVERIFIED —
prefixed), using{host}for apex/SRV and{target}.for MX/SRV/CNAME targets. - Confirm no interpreter change is needed (existing tokens cover DigitalOcean).
-
uv run verify_thundermail_dns.py example.com --provider digitaloceanrenders all 13
records in both--fix-formattable and long without error. - Web app "DigitalOcean" provider mirrors the CLI output (table + detailed).
- Update
README.mdprovider list + RELEASE_NOTES / RELEASE_NOTES.html. - Update
CLAUDE.mdcrucial-decisions with DigitalOcean's quirks (combined SRV
Hostname,@apex, trailing-dot targets). - Verify against
example.com(--resolver ns1.digitalocean.com): confirm the
trailing-dot rule on MX/CNAME targets against a live panel (SRV already confirmed),
then drop theUNVERIFIED —prefixes. NB:example.com's SRV records are currently
broken (target has.example.comappended) — fixing them there is itself a good live
test of the emitteddigitaloceanSRV fix strings.
Reference docs
- How to Create, Edit, and Delete DNS Records — https://docs.digitalocean.com/products/networking/dns/how-to/manage-records/
- Docs index for AI agents — https://docs.digitalocean.com/llms.txt
Local source: THUNDERBIRD_2023/TBPRO/7012_DNS_DIGITAL_OCEAN/7012-DNS-digitalocean-srv.png
(live SRV Create a record dialog).
🤖 Generated with Claude Code
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.