mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-15 20:25:23 +02:00
- Added FormDescription to clarify user requirements in the server handling component. - Updated alert messages to inform users about connecting as root or non-root with passwordless sudo access. - Introduced new status rows in the validation component to display privilege mode and Docker group membership. - Implemented validation functions for sudo access and Docker group membership in the server setup scripts, ensuring proper permissions are checked during setup.
191 lines
5.5 KiB
TypeScript
191 lines
5.5 KiB
TypeScript
import { Client } from "ssh2";
|
|
import { findServerById } from "../services/server";
|
|
|
|
export const validateDocker = () => `
|
|
if command_exists docker; then
|
|
echo "$(docker --version | awk '{print $3}' | sed 's/,//') true"
|
|
else
|
|
echo "0.0.0 false"
|
|
fi
|
|
`;
|
|
|
|
export const validateRClone = () => `
|
|
if command_exists rclone; then
|
|
echo "$(rclone --version | head -n 1 | awk '{print $2}' | sed 's/^v//') true"
|
|
else
|
|
echo "0.0.0 false"
|
|
fi
|
|
`;
|
|
|
|
export const validateSwarm = () => `
|
|
if docker info --format '{{.Swarm.LocalNodeState}}' | grep -q 'active'; then
|
|
echo true
|
|
else
|
|
echo false
|
|
fi
|
|
`;
|
|
|
|
export const validateNixpacks = () => `
|
|
if command_exists nixpacks; then
|
|
version=$(nixpacks --version | awk '{print $2}')
|
|
if [ -n "$version" ]; then
|
|
echo "$version true"
|
|
else
|
|
echo "0.0.0 false"
|
|
fi
|
|
else
|
|
echo "0.0.0 false"
|
|
fi
|
|
`;
|
|
|
|
export const validateRailpack = () => `
|
|
if command_exists railpack; then
|
|
version=$(railpack --version | awk '{print $3}')
|
|
if [ -n "$version" ]; then
|
|
echo "$version true"
|
|
else
|
|
echo "0.0.0 false"
|
|
fi
|
|
else
|
|
echo "0.0.0 false"
|
|
fi
|
|
`;
|
|
export const validateBuildpacks = () => `
|
|
if command_exists pack; then
|
|
version=$(pack --version | awk '{print $1}')
|
|
if [ -n "$version" ]; then
|
|
echo "$version true"
|
|
else
|
|
echo "0.0.0 false"
|
|
fi
|
|
else
|
|
echo "0.0.0 false"
|
|
fi
|
|
`;
|
|
|
|
export const validateMainDirectory = () => `
|
|
if [ -d "/etc/dokploy" ]; then
|
|
echo true
|
|
else
|
|
echo false
|
|
fi
|
|
`;
|
|
|
|
export const validateDokployNetwork = () => `
|
|
if docker network ls | grep -q 'dokploy-network'; then
|
|
echo true
|
|
else
|
|
echo false
|
|
fi
|
|
`;
|
|
|
|
export const validateSudoAccess = () => `
|
|
if [ "$(id -u)" -eq 0 ]; then
|
|
echo "root true"
|
|
elif sudo -n true 2>/dev/null; then
|
|
echo "sudo true"
|
|
else
|
|
echo "none false"
|
|
fi
|
|
`;
|
|
|
|
export const validateDockerGroup = () => `
|
|
if groups | grep -qw docker; then
|
|
echo true
|
|
else
|
|
echo false
|
|
fi
|
|
`;
|
|
|
|
export const serverValidate = async (serverId: string) => {
|
|
const client = new Client();
|
|
const server = await findServerById(serverId);
|
|
if (!server.sshKeyId) {
|
|
throw new Error("No SSH Key found");
|
|
}
|
|
|
|
return new Promise<string>((resolve, reject) => {
|
|
client
|
|
.once("ready", () => {
|
|
const bashCommand = `
|
|
command_exists() {
|
|
command -v "$@" > /dev/null 2>&1
|
|
}
|
|
|
|
dockerVersionEnabled=$(${validateDocker()})
|
|
rcloneVersionEnabled=$(${validateRClone()})
|
|
nixpacksVersionEnabled=$(${validateNixpacks()})
|
|
buildpacksVersionEnabled=$(${validateBuildpacks()})
|
|
railpackVersionEnabled=$(${validateRailpack()})
|
|
dockerVersion=$(echo $dockerVersionEnabled | awk '{print $1}')
|
|
dockerEnabled=$(echo $dockerVersionEnabled | awk '{print $2}')
|
|
|
|
rcloneVersion=$(echo $rcloneVersionEnabled | awk '{print $1}')
|
|
rcloneEnabled=$(echo $rcloneVersionEnabled | awk '{print $2}')
|
|
|
|
nixpacksVersion=$(echo $nixpacksVersionEnabled | awk '{print $1}')
|
|
nixpacksEnabled=$(echo $nixpacksVersionEnabled | awk '{print $2}')
|
|
|
|
railpackVersion=$(echo $railpackVersionEnabled | awk '{print $1}')
|
|
railpackEnabled=$(echo $railpackVersionEnabled | awk '{print $2}')
|
|
|
|
buildpacksVersion=$(echo $buildpacksVersionEnabled | awk '{print $1}')
|
|
buildpacksEnabled=$(echo $buildpacksVersionEnabled | awk '{print $2}')
|
|
|
|
isDokployNetworkInstalled=$(${validateDokployNetwork()})
|
|
isSwarmInstalled=$(${validateSwarm()})
|
|
isMainDirectoryInstalled=$(${validateMainDirectory()})
|
|
|
|
sudoAccessResult=$(${validateSudoAccess()})
|
|
privilegeMode=$(echo $sudoAccessResult | awk '{print $1}')
|
|
isDockerGroupMember=$(${validateDockerGroup()})
|
|
|
|
echo "{\\"docker\\": {\\"version\\": \\"$dockerVersion\\", \\"enabled\\": $dockerEnabled}, \\"rclone\\": {\\"version\\": \\"$rcloneVersion\\", \\"enabled\\": $rcloneEnabled}, \\"nixpacks\\": {\\"version\\": \\"$nixpacksVersion\\", \\"enabled\\": $nixpacksEnabled}, \\"buildpacks\\": {\\"version\\": \\"$buildpacksVersion\\", \\"enabled\\": $buildpacksEnabled}, \\"railpack\\": {\\"version\\": \\"$railpackVersion\\", \\"enabled\\": $railpackEnabled}, \\"isDokployNetworkInstalled\\": $isDokployNetworkInstalled, \\"isSwarmInstalled\\": $isSwarmInstalled, \\"isMainDirectoryInstalled\\": $isMainDirectoryInstalled, \\"privilegeMode\\": \\"$privilegeMode\\", \\"dockerGroupMember\\": $isDockerGroupMember}"
|
|
`;
|
|
client.exec(bashCommand, (err, stream) => {
|
|
if (err) {
|
|
reject(err);
|
|
return;
|
|
}
|
|
let output = "";
|
|
stream
|
|
.on("close", () => {
|
|
client.end();
|
|
try {
|
|
const result = JSON.parse(output.trim());
|
|
resolve(result);
|
|
} catch (parseError) {
|
|
reject(
|
|
new Error(
|
|
`Failed to parse output: ${parseError instanceof Error ? parseError.message : parseError}`,
|
|
),
|
|
);
|
|
}
|
|
})
|
|
.on("data", (data: string) => {
|
|
output += data;
|
|
})
|
|
.stderr.on("data", (_data) => {});
|
|
});
|
|
})
|
|
.on("error", (err) => {
|
|
client.end();
|
|
if (err.level === "client-authentication") {
|
|
reject(
|
|
new Error(
|
|
`Authentication failed: Invalid SSH private key. ❌ Error: ${err.message} ${err.level}`,
|
|
),
|
|
);
|
|
} else {
|
|
reject(new Error(`SSH connection error: ${err.message}`));
|
|
}
|
|
})
|
|
.connect({
|
|
host: server.ipAddress,
|
|
port: server.port,
|
|
username: server.username,
|
|
privateKey: server.sshKey?.privateKey,
|
|
});
|
|
});
|
|
};
|