Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…rver Co-authored-by: Cursor <cursoragent@cursor.com>
iam4x
force-pushed
the
feat/duplicate-target-server
branch
from
September 13, 2026 06:06
00951cc to
7e86ea9
Compare
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?
The Duplicate Services dialog gets a Target Server select. Today every duplicated application, compose stack and database keeps its source
serverId, so duplication cannot be used to stage a copy on another host. This adds the missing piece asked for in #5170: a copy that lands on a different remote server, or back on the Dokploy host, while the source keeps running. #5396 (transfer) moves a service and its data; this copies configuration only, the same way duplication always has.Behavior
remoteServersOnlyis on) and the organization's servers that have an SSH key, the same sourceadd-applicationuses.serverIdon every copy. Networks that are scoped to another server are dropped fromnetworkIds(applications, databases) and from each composeserviceNetworksentry, through the sameresolveNetworkIdsrule the transfer feature uses. The dialog says so before you confirm.API
project.duplicateaccepts an optionaltargetServer:The target is validated before any project or service row is written:
dokployis rejected in cloud mode or withremoteServersOnly;remoterequires a server the session can access (owner, or a member with thatserverIdinaccessedServers) that isactiveand of typedeploy. Existing callers that omittargetServerare unaffected.Changes
packages/server/src/services/duplicate.ts(new).assertDuplicateTargetServer,duplicateServerOverride, andduplicateService. The per-service duplication switch moved here from the router; each arm builds its payload through one helper, so the target-server override is applied in one place instead of eight.project.tsshrinks by ~390 lines.packages/server/src/db/schema/duplicate.ts(new).apiDuplicateTargetServerzod union and its type.packages/server/src/services/network.ts.resolveNetworkIdsmoved here fromtransfer.tsso both features share it. No behavior change.apps/dokploy/server/api/routers/project.ts.duplicatetakestargetServer, validates it up front, callsduplicateService, rethrowsTRPCErrorinstead of flattening every failure toBAD_REQUEST, and records the target in the audit metadata. The hand-written service type enum is nowz.enum(serviceType.enumValues).apps/dokploy/components/dashboard/project/duplicate-project.tsx. The select and the network warning.apps/dokploy/__test__/services/duplicate-target-server.test.ts(new). 15 cases covering the three target kinds, cloud andremoteServersOnlyrejection, inaccessible and inactive servers, and network filtering fornetworkIdsand composeserviceNetworks.Tested
Local instance on
canarywith two seeded remote servers, an application on each, a Postgres on the Dokploy host, a compose stack withserviceNetworks, and one server-scoped network per remote. Driven through the real dialog with Playwright and read back from Postgres:serviceNetworksentry, the remote-b network is kept,detachDokployNetworkis preserved, the source rows are untouched.serverIdreturnsUNAUTHORIZEDbefore any project row is created. An unknownkindis rejected by zod. OmittingtargetServerbehaves as before.pnpm typecheck,pnpm server:build,biome checkon the changed files clean.pnpm test: 1044 passed; the 4 failures inapplication.real.test.tsare pre-existing oncanaryon this machine (nixpacks/railpack not installed) and unrelated.Notes for review
project.duplicatenow rethrowsTRPCErroras is. Callers that keyed on every failure beingBAD_REQUESTwill seeUNAUTHORIZED,NOT_FOUNDorCONFLICTwhere those apply.Checklist
Before submitting this PR, please make sure that:
canarybranch.Issues related (if applicable)
Related to #5170 (closed with #5396, which its description calls a different operation).
Screenshots (if applicable)
See above.
The PR appears safe to merge; no actionable new issues remain, and both previous findings are resolved.
Summary
Adds cross-server service duplication while preserving the existing configuration-only duplication behavior.
Reviews (3) · Last reviewed commit: "fix(duplicate): offer the Dokploy target..."