Conversation
| args.length > 0 && { | ||
| Args: args, | ||
| }), | ||
| ...buildContainerCommand(application), |
There was a problem hiding this comment.
Rollbacks lose custom shell commands
The rollback snapshot captures customCommand and customShell, but rollbackApplication still constructs its container command solely from the legacy command field. Rolling back a deployment configured with a startup script therefore runs the old Single command—or the image default when command is empty—instead of the saved script. This can skip required startup work and restore a different runtime configuration. Use buildContainerCommand when constructing the rollback ContainerSpec too, and add a rollback regression test.
Knowledge Base Used: Applications and deployments
| customCommand: z.string().max(20000).optional(), | ||
| customShell: z.enum(["sh", "bash"]).optional(), | ||
| args: z | ||
| .array( | ||
| z.object({ | ||
| value: z.string().min(1, "Argument cannot be empty"), | ||
| }), | ||
| ) | ||
| .optional(), |
There was a problem hiding this comment.
Click Add Argument in Single mode, leave it blank, then switch to Custom shell and enter a valid script: the retained empty argument fails min(1), but its error is hidden because SingleCommandFields is unmounted, so Save appears to do nothing. A script exceeding 20,000 characters similarly blocks saving after switching back to Single. Make validation conditional on commandMode while preserving stored values, and cover these mode-switch cases in a form test.
| <FormLabel>Mode</FormLabel> | ||
| <FormControl> | ||
| <Input placeholder="/bin/sh" {...field} /> | ||
| <RadioGroup | ||
| onValueChange={field.onChange} | ||
| value={field.value} | ||
| className="flex flex-row gap-6" |
There was a problem hiding this comment.
Mode group lacks accessible name
FormLabel associates “Mode” through htmlFor, but the RadioGroup root is not a labelable control, and no aria-label or aria-labelledby is supplied. The individual options are labeled, but assistive technology cannot identify the group by its visible heading. Give the Mode label an ID and reference it with aria-labelledby on RadioGroup.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Custom script runs through sh -c or bash -c. Legacy command plus args stays as fallback.
5df0d07 to
ee6e61a
Compare
API rejects empty scripts and shell without script. Helper types shell as sh or bash. UI warns the image must include the shell.
| if (data.customShell !== undefined && data.customShell !== null) { | ||
| if (data.customCommand === undefined || data.customCommand === null) { | ||
| ctx.addIssue({ | ||
| code: "custom", | ||
| path: ["customCommand"], | ||
| message: "Enter a script", |
There was a problem hiding this comment.
Shell-only updates are rejected
For an application with a saved script, { applicationId, customShell: "bash" } now fails with “Enter a script” because customCommand is absent from the request. application.update performs partial updates, so the existing script should remain unchanged, but this validation prevents changing just the shell. Validate the resulting stored configuration, or allow an omitted script when updating the shell.
| } | ||
| } else { | ||
| data.args?.forEach((arg, i) => { | ||
| if (!arg.value.trim()) { |
There was a problem hiding this comment.
Whitespace arguments are rejected
Using arg.value.trim() rejects legitimate whitespace-only arguments in Single mode. For example, an application configured with --separator followed by a literal space can no longer save its command, although that argument was previously accepted and is passed unchanged to Docker. Keep validation conditional on the mode, but check the original string’s length rather than its trimmed length.
| if (!arg.value.trim()) { | |
| if (arg.value.length === 0) { |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Reject whitespace-only scripts. Length checks use raw length. Add regression tests for the apiUpdateApplication superRefine.
What is this PR about?
I add a Custom shell mode to the Application Run Command card. I pick
shorbashand I paste a startup script. Dokploy sets my container Command to[shell, -c, script]and skips Args in that mode. Single mode keeps its current behavior. I verified live: my service inspects as[sh, -c, <script>]and my script output leads the container logs.Checklist
Before submitting this PR, please make sure that:
canarybranch.Issues related (if applicable)
Fixes #5433
Screenshots (if applicable)
Redeploy recording to attach.
Fix the rejection of valid shell-only partial updates before merging; whitespace argument validation also needs adjustment.
Summary
Reviews (2) · Last reviewed commit: "fix(application): harden custom shell mo..."