feat(dns): rework provider management and support all record types - #5150
Merged
Siumauricio merged 7 commits intoSep 1, 2026
Merged
Conversation
Providers, domains and records now each have their own page instead of a stack of modals. A provider opens its domains as cards, with the record count loading separately so the domains appear right away. A domain opens its records as a table with search, type filter and pagination. Creating or editing a record happens in a panel that slides in next to the table. The type list was capped at A and CNAME in the zod schema, so widening the dropdown alone would not have worked. AAAA, MX, TXT, NS, SRV, CAA and PTR work now. MX carries a priority that Cloudflare takes as a separate field and Route53 takes inline in the value, so the Cloudflare client splits it out on write and puts it back on read. The form keeps one value field for both providers. Cloudflare proxy status is now editable and visible. A, AAAA and CNAME records get a Proxied / DNS only toggle in the form and a cloud icon in the table. The proxy field only goes to the API when the caller sets it, so an update from another path cannot silently disable the proxy. Tests cover the MX priority round trip and the proxy rules in the Cloudflare client.
Cloudflare treats content as read-only for SRV and CAA and expects a data object instead, so both types were rejected on write. The client now parses the inline value into the fields Cloudflare wants, and builds the payload before the lookup request so a malformed value fails without spending an API call. The form rejects a malformed SRV or CAA value up front and shows the expected shape, so the error lands on the field instead of coming back from the provider.
Filtering from a later page left pageIndex past the end of the filtered set, so the table said no records matched while the counter above it reported matches. The page index is clamped to the available page count, and changing the search or the type filter goes back to the first page.
Route53 returns a record set as a list of values, but listing joined them into one string and writing sent that string back as a single ResourceRecord. Editing a multi-value NS, MX or TXT set therefore either failed validation or collapsed the set into one bogus value, and creating a record for a name that already had values replaced them silently. Values are now newline separated end to end: listing joins with a newline, writing splits back into one ResourceRecord per line, and creating merges into the existing set instead of replacing it. Unquoted TXT values get the quotes Route53 requires. The record panel shows a textarea for Route53 and validates every line.
…ators in DNS-related components
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is this PR about?
DNS providers, domains and records each get their own page instead of a
stack of modals. Clicking a provider opens its domains. Clicking a domain
opens its records. Creating or editing a record happens in a panel that
slides in next to the table, so the record you are editing stays visible.
Two limits are lifted along the way. Record types were capped at A and
CNAME in the zod schema, and Cloudflare proxy status was not reachable at
all.
Provider list
Each provider is a row that opens its domains. The row carries three
actions with matching styling and tooltips: view domains, edit, delete.
Add Provider moved to the header, on the same line as the title.
Domain list
Domains render as cards. The record count on each card loads on its own
request, so the domain names appear as soon as the zone list arrives
instead of waiting for every count.
Record table
Records are a table with search, a type filter built from the types
present in that zone, a rows-per-page selector defaulting to 10, and
sortable columns. Record types are colour coded rather than uniform grey
badges.
Record editing
The create and edit form opens in a panel beside the table. Cloudflare
zones get a Proxied / DNS only control for A, AAAA and CNAME records,
with the proxy status also shown as a cloud icon in the table.
Record types
A, AAAA, CNAME, MX, TXT, NS, SRV, CAA and PTR are accepted now. The type
list lives in
dnsRecordTypesin the schema, and bothDnsRecordInputand the Route53 client read from it.
MX needs a priority. Cloudflare takes it as a separate field, Route53
takes it inline in the value. The Cloudflare client splits the priority
out of the value on write and puts it back on read, so a single value
field behaves the same on both providers. A value with no leading number
falls back to priority 10.
Cloudflare proxy status
proxiedwas added to the record schema,DnsRecordInputandDnsRecord. The Cloudflare client reads it inlistRecordsand sends iton create and update, but only for the three proxiable types and only
when the caller sets the field. Sending
proxied: falseby default wouldhave turned the proxy off on any record updated through a path that does
not set it.
Proxied records force automatic TTL on Cloudflare, so the TTL input is
disabled while Proxied is selected and the request omits the TTL.
Testing
Tested locally against a real Cloudflare zone and a Route53 hosted zone.
Created, edited and deleted records of several types, switched the proxy
toggle both ways, and confirmed the changes landed in the provider
dashboard.
Automated coverage in
apps/dokploy/__test__/dns/cloudflare.test.ts:when writing, with a fallback to 10 when the value has no leading
number
the caller does not set it
listRecordspnpm typecheckpasses inapps/dokployandpackages/server, Biome isclean, and the 40 tests in
__test__/dnspass.Notes for reviewers
Automated coverage in
apps/dokploy/__test__/dns/cloudflare.test.ts:when writing, with a fallback to 10 when the value has no leading
number
the caller does not set it
listRecordspnpm typecheckpasses inapps/dokployandpackages/server, Biome isclean, and the 40 tests in
__test__/dnspass.Notes for reviewers
Route53 ignores
proxied, since the concept does not exist there. TheProxy column and the toggle are hidden for Route53 providers.
Checklist
Before submitting this PR, please make sure that:
canarybranch.Screenshots (if applicable)
Greptile Summary
The PR reorganizes DNS provider management into dedicated provider, domain, and record pages while expanding record-type support and Cloudflare proxy controls.
Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Reviews (3): Last reviewed commit: "fix(dns): preserve every value of a Rout..." | Re-trigger Greptile
Context used: