Skip to content

Fix: extractImageTag misidentifies registry port as image tag#4110

Open
mahdirajaee wants to merge 64 commits intoDokploy:canaryfrom
mahdirajaee:fix/extract-image-tag
Open

Fix: extractImageTag misidentifies registry port as image tag#4110
mahdirajaee wants to merge 64 commits intoDokploy:canaryfrom
mahdirajaee:fix/extract-image-tag

Conversation

@mahdirajaee
Copy link
Copy Markdown

@mahdirajaee mahdirajaee commented Mar 30, 2026

Summary

Fixes #4082

extractImageTag uses a naive split(":") approach that misidentifies the registry port as a tag for private registry images without explicit tags (e.g., myregistry:5000/myapp returns "5000/myapp" instead of "latest").

Changes

Replaced the split(":").pop() logic with lastIndexOf + port-number detection, matching the pattern already used in extractImageName.

Test Cases

Input Before After
myregistry:5000/myapp "5000/myapp" "latest"
myregistry:5000/myapp:v2 "v2" "v2"
nginx:latest "latest" "latest"
nginx "latest" "latest"

Greptile Summary

This PR attempts to fix extractImageTag misidentifying the registry port as a tag for images like myregistry:5000/myapp, mirroring the lastIndexOf + port-detection pattern already used in extractImageName.

However, the fix is incomplete: the regex /^\d{1,5}$/ only matches a bare port number with nothing following it. For "myregistry:5000/myapp" — the PR's own headline example — afterColon evaluates to "5000/myapp", which fails the digit-only test because of the /myapp suffix. The function therefore falls through and returns "5000/myapp", identical to the broken behaviour before the change.

  • The fix works correctly for registry:port (no image path), image:tag, image (no colon), and registry:port/image:tag.
  • The fix does not work for registry:port/image (port followed by a path component with no explicit tag), which is the primary scenario reported in issue extractImageTag misidentifies registry port as tag for private registry images without explicit tags #4082.
  • The extractImageName function has the same gap (it would return "myregistry" for the same input instead of the full image name), suggesting this is a systemic issue in the port-detection logic shared across the file.
  • Suggested one-line fix: change the regex to /^\d{1,5}(\/|$)/ to also match a port followed by a path separator.

Confidence Score: 4/5

Safe to merge once the regex is widened to cover registry:port/image — a one-character change fixes the incomplete match.

There is one P1 defect: the port-detection regex /^\d{1,5}$/ does not match the primary use-case (registry:port/image) because the afterColon substring includes the path component. The PR's own test table claims 'latest' for this input but the code still returns '5000/myapp'. The fix is structurally correct and almost complete; it just needs the regex extended to /^\d{1,5}(/|$)/. All other test cases (explicit tag, no tag, bare port) behave correctly.

apps/dokploy/pages/api/deploy/[refreshToken].ts — specifically the regex on line 328

Important Files Changed

Filename Overview
apps/dokploy/pages/api/deploy/[refreshToken].ts Replaces split(':').pop() with lastIndexOf + regex in extractImageTag, but the regex /^\d{1,5}$/ only matches a bare port number and fails for registry:5000/image — the primary case the PR targets — because afterColon becomes '5000/myapp' which contains a slash and letters.

Reviews (1): Last reviewed commit: "Fix extractImageTag parsing registry por..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!

Siumauricio and others added 26 commits November 19, 2025 02:45
refactor(deployments): enhance deployment worker and queue handling f…
@dosubot dosubot bot added size:S This PR changes 10-29 lines, ignoring generated files. bug Something isn't working labels Mar 30, 2026
Comment on lines +327 to +332
const afterColon = dockerImage.substring(lastColonIndex + 1);
if (/^\d{1,5}$/.test(afterColon)) {
return "latest";
}

return afterColon;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Port-with-path regex doesn't match the primary fix case

The PR's headline fix case — myregistry:5000/myapp — is not actually fixed by this code.

For "myregistry:5000/myapp":

  • lastIndexOf(":") → index 10 (the only colon, after myregistry)
  • afterColon"5000/myapp"
  • /^\d{1,5}$/.test("5000/myapp")false (the $ anchor requires the entire substring to be digits; the /myapp suffix breaks the match)
  • The function falls through and returns "5000/myapp" — identical to the old behaviour

The regex correctly handles myregistry:5000 (bare registry with port, no image path) but misses the registry:port/imagepath pattern, which is the dominant real-world form.

A minimal fix is to also accept a digit sequence followed by a /:

Suggested change
const afterColon = dockerImage.substring(lastColonIndex + 1);
if (/^\d{1,5}$/.test(afterColon)) {
return "latest";
}
return afterColon;
const afterColon = dockerImage.substring(lastColonIndex + 1);
// Matches a port number either alone (registry:5000) or followed by a path
// (registry:5000/image). Pure-digit tags without a slash are ambiguous but
// consistent with the behaviour of extractImageName.
if (/^\d{1,5}(\/|$)/.test(afterColon)) {
return "latest";
}
return afterColon;

With this regex "5000/myapp" matches ^\d{1,5}\/ and returns "latest" as expected, while "v2", "latest", and "1.0.0" are unaffected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

extractImageTag misidentifies registry port as tag for private registry images without explicit tags

2 participants