Skip to content

Commit bf7a75d

Browse files
authored
Merge pull request #3882 from aak-lear/fix/rollback-registry-auth
fix: add docker login before rollback and fix execAsyncRemote argument order
2 parents d316aa4 + d2fabc9 commit bf7a75d

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

packages/server/src/services/registry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function shEscape(s: string | undefined): string {
1616
return `'${s.replace(/'/g, `'\\''`)}'`;
1717
}
1818

19-
function safeDockerLoginCommand(
19+
export function safeDockerLoginCommand(
2020
registry: string | undefined,
2121
user: string | undefined,
2222
pass: string | undefined,

packages/server/src/services/rollbacks.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { findDeploymentById } from "./deployment";
2323
import type { Mount } from "./mount";
2424
import type { Port } from "./port";
2525
import type { Project } from "./project";
26-
import type { Registry } from "./registry";
26+
import { type Registry, safeDockerLoginCommand } from "./registry";
2727

2828
export const createRollback = async (
2929
input: z.infer<typeof createRollbackSchema>,
@@ -111,7 +111,7 @@ const deleteRollbackImage = async (image: string, serverId?: string | null) => {
111111
const command = `docker image rm ${image} --force`;
112112

113113
if (serverId) {
114-
await execAsyncRemote(command, serverId);
114+
await execAsyncRemote(serverId, command);
115115
} else {
116116
await execAsync(command);
117117
}
@@ -171,6 +171,23 @@ export const rollback = async (rollbackId: string) => {
171171
);
172172
};
173173

174+
const dockerLoginForRegistry = async (
175+
registry: Registry,
176+
serverId?: string | null,
177+
) => {
178+
const loginCommand = safeDockerLoginCommand(
179+
registry.registryUrl,
180+
registry.username,
181+
registry.password,
182+
);
183+
184+
if (serverId) {
185+
await execAsyncRemote(serverId, loginCommand);
186+
} else {
187+
await execAsync(loginCommand);
188+
}
189+
};
190+
174191
const rollbackApplication = async (
175192
appName: string,
176193
image: string,
@@ -188,6 +205,14 @@ const rollbackApplication = async (
188205
throw new Error("Full context is required for rollback");
189206
}
190207

208+
// Ensure Docker daemon is authenticated with the rollback registry
209+
// before updating the swarm service. The authconfig in CreateServiceOptions
210+
// alone is not sufficient — Docker Swarm also relies on the daemon's
211+
// cached credentials (~/.docker/config.json) to distribute auth to nodes.
212+
if (fullContext.rollbackRegistry) {
213+
await dockerLoginForRegistry(fullContext.rollbackRegistry, serverId);
214+
}
215+
191216
const docker = await getRemoteDocker(serverId);
192217

193218
// Use the same configuration as mechanizeDockerContainer

0 commit comments

Comments
 (0)