Files
dokploy/packages/server/src/utils/cluster/upload.ts

145 lines
4.3 KiB
TypeScript

import { findAllDeploymentsByApplicationId } from "@dokploy/server/services/deployment";
import {
findRegistryByIdWithCredentials,
safeDockerLoginCommand,
type Registry,
} from "@dokploy/server/services/registry";
import { createRollback } from "@dokploy/server/services/rollbacks";
import type { ApplicationNested } from "../builders";
export const uploadImageRemoteCommand = async (
application: ApplicationNested,
) => {
const registry = application.registry;
const buildRegistry = application.buildRegistry;
const rollbackRegistry = application.rollbackRegistry;
if (!registry && !buildRegistry && !rollbackRegistry) {
throw new Error("No registry found");
}
const { appName } = application;
const imageName =
application.sourceType === "docker"
? application.dockerImage || ""
: `${appName}:latest`;
const commands: string[] = [];
if (registry) {
const r = await findRegistryByIdWithCredentials(registry.registryId);
const registryTag = getRegistryTag(r, imageName);
if (registryTag) {
commands.push(`echo "📦 [Enabled Registry Swarm]"`);
commands.push(getRegistryCommands(r, imageName, registryTag));
}
}
if (buildRegistry) {
const r = await findRegistryByIdWithCredentials(buildRegistry.registryId);
const buildRegistryTag = getRegistryTag(r, imageName);
if (buildRegistryTag) {
commands.push(`echo "🔑 [Enabled Build Registry]"`);
commands.push(getRegistryCommands(r, imageName, buildRegistryTag));
commands.push(
`echo "⚠️ INFO: After the build is finished, you need to wait a few seconds for the server to download the image and run the container."`,
);
commands.push(
`echo "📊 Check the Logs tab to see when the container starts running."`,
);
}
}
if (rollbackRegistry && application.rollbackActive) {
const deployment = await findAllDeploymentsByApplicationId(
application.applicationId,
);
if (!deployment || !deployment[0]) {
throw new Error("Deployment not found");
}
const deploymentId = deployment[0].deploymentId;
const rollback = await createRollback({
appName: appName,
deploymentId: deploymentId,
});
const r = await findRegistryByIdWithCredentials(
rollbackRegistry.registryId,
);
const rollbackRegistryTag = getRegistryTag(r, rollback?.image || "");
if (rollbackRegistryTag) {
commands.push(`echo "🔄 [Enabled Rollback Registry]"`);
commands.push(getRegistryCommands(r, imageName, rollbackRegistryTag));
}
}
try {
return commands.join("\n");
} catch (error) {
throw error;
}
};
/**
* Extract the repository name from imageName by taking the last part after '/'
* Examples:
* - "nginx" -> "nginx"
* - "nginx:latest" -> "nginx:latest"
* - "myuser/myrepo" -> "myrepo"
* - "myuser/myrepo:tag" -> "myrepo:tag"
* - "docker.io/myuser/myrepo" -> "myrepo"
*/
const extractRepositoryName = (imageName: string): string => {
const lastSlashIndex = imageName.lastIndexOf("/");
// If no '/', return the imageName as is
if (lastSlashIndex === -1) {
return imageName;
}
// Extract everything after the last '/'
return imageName.substring(lastSlashIndex + 1);
};
export const getRegistryTag = (registry: Registry, imageName: string) => {
const { registryUrl, imagePrefix, username } = registry;
// Extract the repository name (last part after '/')
const repositoryName = extractRepositoryName(imageName);
// Build the final tag using registry's username/prefix (must be lowercase for valid image refs)
const targetPrefix = (imagePrefix || username).toLowerCase();
const finalRegistry = registryUrl || "";
return finalRegistry
? `${finalRegistry}/${targetPrefix}/${repositoryName}`
: `${targetPrefix}/${repositoryName}`;
};
const getRegistryCommands = (
registry: Registry,
imageName: string,
registryTag: string,
): string => {
const loginCmd = safeDockerLoginCommand(
registry.registryUrl,
registry.username,
registry.password,
);
return `
echo "📦 [Enabled Registry] Uploading image to '${registry.registryType}' | '${registryTag}'" ;
${loginCmd} || {
echo "❌ DockerHub Failed" ;
exit 1;
}
echo "✅ Registry Login Success" ;
docker tag ${imageName} ${registryTag} || {
echo "❌ Error tagging image" ;
exit 1;
}
echo "✅ Image Tagged" ;
docker push ${registryTag} || {
echo "❌ Error pushing image" ;
exit 1;
}
echo "✅ Image Pushed" ;
`;
};