commit
0a68a48fc5
@ -261,7 +261,10 @@ import * as buildpacks from '../lib/buildPacks';
|
|||||||
if (secrets.length > 0) {
|
if (secrets.length > 0) {
|
||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
envs.push(`${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
envs.push(`${secret.name}=${secret.value}`);
|
envs.push(`${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -556,7 +556,6 @@ export function checkPnpm(installCommand = null, buildCommand = null, startComma
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function buildImage({
|
export async function buildImage({
|
||||||
applicationId,
|
applicationId,
|
||||||
tag,
|
tag,
|
||||||
@ -677,8 +676,6 @@ export async function buildCacheImageWithNode(data, imageForBuild) {
|
|||||||
secrets,
|
secrets,
|
||||||
pullmergeRequestId
|
pullmergeRequestId
|
||||||
} = data;
|
} = data;
|
||||||
|
|
||||||
|
|
||||||
const isPnpm = checkPnpm(installCommand, buildCommand);
|
const isPnpm = checkPnpm(installCommand, buildCommand);
|
||||||
const Dockerfile: Array<string> = [];
|
const Dockerfile: Array<string> = [];
|
||||||
Dockerfile.push(`FROM ${imageForBuild}`);
|
Dockerfile.push(`FROM ${imageForBuild}`);
|
||||||
@ -688,7 +685,10 @@ export async function buildCacheImageWithNode(data, imageForBuild) {
|
|||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (secret.isBuildSecret) {
|
if (secret.isBuildSecret) {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
Dockerfile.push(`ARG ${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -707,6 +707,7 @@ export async function buildCacheImageWithNode(data, imageForBuild) {
|
|||||||
Dockerfile.push(`RUN ${installCommand}`);
|
Dockerfile.push(`RUN ${installCommand}`);
|
||||||
}
|
}
|
||||||
Dockerfile.push(`RUN ${buildCommand}`);
|
Dockerfile.push(`RUN ${buildCommand}`);
|
||||||
|
console.log(Dockerfile.join('\n'))
|
||||||
await fs.writeFile(`${workdir}/Dockerfile-cache`, Dockerfile.join('\n'));
|
await fs.writeFile(`${workdir}/Dockerfile-cache`, Dockerfile.join('\n'));
|
||||||
await buildImage({ ...data, isCache: true });
|
await buildImage({ ...data, isCache: true });
|
||||||
}
|
}
|
||||||
@ -722,7 +723,10 @@ export async function buildCacheImageForLaravel(data, imageForBuild) {
|
|||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (secret.isBuildSecret) {
|
if (secret.isBuildSecret) {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
Dockerfile.push(`ARG ${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -27,7 +27,10 @@ const createDockerfile = async (data, image): Promise<void> => {
|
|||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (secret.isBuildSecret) {
|
if (secret.isBuildSecret) {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
Dockerfile.push(`ARG ${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -28,6 +28,7 @@ export default async function (data) {
|
|||||||
if (secrets.length > 0) {
|
if (secrets.length > 0) {
|
||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (secret.isBuildSecret) {
|
if (secret.isBuildSecret) {
|
||||||
|
// TODO: fix secrets
|
||||||
if (
|
if (
|
||||||
(pullmergeRequestId && secret.isPRMRSecret) ||
|
(pullmergeRequestId && secret.isPRMRSecret) ||
|
||||||
(!pullmergeRequestId && !secret.isPRMRSecret)
|
(!pullmergeRequestId && !secret.isPRMRSecret)
|
||||||
|
@ -27,7 +27,10 @@ const createDockerfile = async (data, image): Promise<void> => {
|
|||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (secret.isBuildSecret) {
|
if (secret.isBuildSecret) {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
Dockerfile.push(`ARG ${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -23,7 +23,10 @@ const createDockerfile = async (data, image): Promise<void> => {
|
|||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (secret.isBuildSecret) {
|
if (secret.isBuildSecret) {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
Dockerfile.push(`ARG ${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -27,7 +27,10 @@ const createDockerfile = async (data, image): Promise<void> => {
|
|||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (secret.isBuildSecret) {
|
if (secret.isBuildSecret) {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
Dockerfile.push(`ARG ${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -16,7 +16,10 @@ const createDockerfile = async (data, image, htaccessFound): Promise<void> => {
|
|||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (secret.isBuildSecret) {
|
if (secret.isBuildSecret) {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
Dockerfile.push(`ARG ${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -21,7 +21,10 @@ const createDockerfile = async (data, image): Promise<void> => {
|
|||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (secret.isBuildSecret) {
|
if (secret.isBuildSecret) {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
Dockerfile.push(`ARG ${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,7 +24,10 @@ const createDockerfile = async (data, image): Promise<void> => {
|
|||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (secret.isBuildSecret) {
|
if (secret.isBuildSecret) {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
Dockerfile.push(`ARG ${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
Dockerfile.push(`ARG ${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -21,7 +21,7 @@ import { scheduler } from './scheduler';
|
|||||||
import { supportedServiceTypesAndVersions } from './services/supportedVersions';
|
import { supportedServiceTypesAndVersions } from './services/supportedVersions';
|
||||||
import { includeServices } from './services/common';
|
import { includeServices } from './services/common';
|
||||||
|
|
||||||
export const version = '3.10.0';
|
export const version = '3.10.1';
|
||||||
export const isDev = process.env.NODE_ENV === 'development';
|
export const isDev = process.env.NODE_ENV === 'development';
|
||||||
|
|
||||||
const algorithm = 'aes-256-ctr';
|
const algorithm = 'aes-256-ctr';
|
||||||
@ -537,7 +537,7 @@ export async function executeDockerCmd({ debug, buildId, applicationId, dockerId
|
|||||||
}
|
}
|
||||||
export async function startTraefikProxy(id: string): Promise<void> {
|
export async function startTraefikProxy(id: string): Promise<void> {
|
||||||
const { engine, network, remoteEngine, remoteIpAddress } = await prisma.destinationDocker.findUnique({ where: { id } })
|
const { engine, network, remoteEngine, remoteIpAddress } = await prisma.destinationDocker.findUnique({ where: { id } })
|
||||||
const found = await checkContainer({ dockerId: id, container: 'coolify-proxy', remove: true });
|
const { found } = await checkContainer({ dockerId: id, container: 'coolify-proxy', remove: true });
|
||||||
const { id: settingsId, ipv4, ipv6 } = await listSettings();
|
const { id: settingsId, ipv4, ipv6 } = await listSettings();
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
@ -621,7 +621,7 @@ export async function configureNetworkTraefikProxy(destination: any): Promise<vo
|
|||||||
export async function stopTraefikProxy(
|
export async function stopTraefikProxy(
|
||||||
id: string
|
id: string
|
||||||
): Promise<{ stdout: string; stderr: string } | Error> {
|
): Promise<{ stdout: string; stderr: string } | Error> {
|
||||||
const found = await checkContainer({ dockerId: id, container: 'coolify-proxy' });
|
const { found } = await checkContainer({ dockerId: id, container: 'coolify-proxy' });
|
||||||
await prisma.destinationDocker.update({
|
await prisma.destinationDocker.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data: { isCoolifyProxyUsed: false }
|
data: { isCoolifyProxyUsed: false }
|
||||||
@ -1062,7 +1062,7 @@ export async function stopTcpHttpProxy(
|
|||||||
const { id: dockerId } = destinationDocker;
|
const { id: dockerId } = destinationDocker;
|
||||||
let container = `${id}-${publicPort}`;
|
let container = `${id}-${publicPort}`;
|
||||||
if (forceName) container = forceName;
|
if (forceName) container = forceName;
|
||||||
const found = await checkContainer({ dockerId, container });
|
const { found } = await checkContainer({ dockerId, container });
|
||||||
try {
|
try {
|
||||||
if (found) {
|
if (found) {
|
||||||
return await executeDockerCmd({
|
return await executeDockerCmd({
|
||||||
@ -1284,7 +1284,7 @@ export async function startTraefikTCPProxy(
|
|||||||
): Promise<{ stdout: string; stderr: string } | Error> {
|
): Promise<{ stdout: string; stderr: string } | Error> {
|
||||||
const { network, id: dockerId, remoteEngine } = destinationDocker;
|
const { network, id: dockerId, remoteEngine } = destinationDocker;
|
||||||
const container = `${id}-${publicPort}`;
|
const container = `${id}-${publicPort}`;
|
||||||
const found = await checkContainer({ dockerId, container, remove: true });
|
const { found } = await checkContainer({ dockerId, container, remove: true });
|
||||||
const { ipv4, ipv6 } = await listSettings();
|
const { ipv4, ipv6 } = await listSettings();
|
||||||
|
|
||||||
let dependentId = id;
|
let dependentId = id;
|
||||||
|
@ -13,7 +13,7 @@ export function formatLabelsOnDocker(data) {
|
|||||||
return container
|
return container
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export async function checkContainer({ dockerId, container, remove = false }: { dockerId: string, container: string, remove?: boolean }): Promise<boolean> {
|
export async function checkContainer({ dockerId, container, remove = false }: { dockerId: string, container: string, remove?: boolean }): Promise<{ found: boolean, status?: { isExited: boolean, isRunning: boolean, isRestarting: boolean } }> {
|
||||||
let containerFound = false;
|
let containerFound = false;
|
||||||
try {
|
try {
|
||||||
const { stdout } = await executeDockerCmd({
|
const { stdout } = await executeDockerCmd({
|
||||||
@ -21,10 +21,12 @@ export async function checkContainer({ dockerId, container, remove = false }: {
|
|||||||
command:
|
command:
|
||||||
`docker inspect --format '{{json .State}}' ${container}`
|
`docker inspect --format '{{json .State}}' ${container}`
|
||||||
});
|
});
|
||||||
|
containerFound = true
|
||||||
const parsedStdout = JSON.parse(stdout);
|
const parsedStdout = JSON.parse(stdout);
|
||||||
const status = parsedStdout.Status;
|
const status = parsedStdout.Status;
|
||||||
const isRunning = status === 'running';
|
const isRunning = status === 'running';
|
||||||
|
const isRestarting = status === 'restarting'
|
||||||
|
const isExited = status === 'exited'
|
||||||
if (status === 'created') {
|
if (status === 'created') {
|
||||||
await executeDockerCmd({
|
await executeDockerCmd({
|
||||||
dockerId,
|
dockerId,
|
||||||
@ -39,13 +41,23 @@ export async function checkContainer({ dockerId, container, remove = false }: {
|
|||||||
`docker rm ${container}`
|
`docker rm ${container}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (isRunning) {
|
|
||||||
containerFound = true;
|
return {
|
||||||
}
|
found: containerFound,
|
||||||
|
status: {
|
||||||
|
isRunning,
|
||||||
|
isRestarting,
|
||||||
|
isExited
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Container not found
|
// Container not found
|
||||||
}
|
}
|
||||||
return containerFound;
|
return {
|
||||||
|
found: false
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function isContainerExited(dockerId: string, containerName: string): Promise<boolean> {
|
export async function isContainerExited(dockerId: string, containerName: string): Promise<boolean> {
|
||||||
|
@ -10,7 +10,8 @@ export default async function ({
|
|||||||
branch,
|
branch,
|
||||||
buildId,
|
buildId,
|
||||||
privateSshKey,
|
privateSshKey,
|
||||||
customPort
|
customPort,
|
||||||
|
forPublic
|
||||||
}: {
|
}: {
|
||||||
applicationId: string;
|
applicationId: string;
|
||||||
workdir: string;
|
workdir: string;
|
||||||
@ -21,11 +22,15 @@ export default async function ({
|
|||||||
repodir: string;
|
repodir: string;
|
||||||
privateSshKey: string;
|
privateSshKey: string;
|
||||||
customPort: number;
|
customPort: number;
|
||||||
|
forPublic: boolean;
|
||||||
}): Promise<string> {
|
}): Promise<string> {
|
||||||
const url = htmlUrl.replace('https://', '').replace('http://', '').replace(/\/$/, '');
|
const url = htmlUrl.replace('https://', '').replace('http://', '').replace(/\/$/, '');
|
||||||
await saveBuildLog({ line: 'GitLab importer started.', buildId, applicationId });
|
await saveBuildLog({ line: 'GitLab importer started.', buildId, applicationId });
|
||||||
await asyncExecShell(`echo '${privateSshKey}' > ${repodir}/id.rsa`);
|
|
||||||
await asyncExecShell(`chmod 600 ${repodir}/id.rsa`);
|
if (!forPublic) {
|
||||||
|
await asyncExecShell(`echo '${privateSshKey}' > ${repodir}/id.rsa`);
|
||||||
|
await asyncExecShell(`chmod 600 ${repodir}/id.rsa`);
|
||||||
|
}
|
||||||
|
|
||||||
await saveBuildLog({
|
await saveBuildLog({
|
||||||
line: `Cloning ${repository}:${branch} branch.`,
|
line: `Cloning ${repository}:${branch} branch.`,
|
||||||
@ -33,9 +38,16 @@ export default async function ({
|
|||||||
applicationId
|
applicationId
|
||||||
});
|
});
|
||||||
|
|
||||||
await asyncExecShell(
|
if (forPublic) {
|
||||||
`git clone -q -b ${branch} git@${url}:${repository}.git --config core.sshCommand="ssh -p ${customPort} -q -i ${repodir}id.rsa -o StrictHostKeyChecking=no" ${workdir}/ && cd ${workdir}/ && git submodule update --init --recursive && git lfs pull && cd .. `
|
await asyncExecShell(
|
||||||
);
|
`git clone -q -b ${branch} git@${url}:${repository}.git --config core.sshCommand="ssh -p ${customPort} -q -o StrictHostKeyChecking=no" ${workdir}/ && cd ${workdir}/ && git submodule update --init --recursive && git lfs pull && cd .. `
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await asyncExecShell(
|
||||||
|
`git clone -q -b ${branch} git@${url}:${repository}.git --config core.sshCommand="ssh -p ${customPort} -q -i ${repodir}id.rsa -o StrictHostKeyChecking=no" ${workdir}/ && cd ${workdir}/ && git submodule update --init --recursive && git lfs pull && cd .. `
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const { stdout: commit } = await asyncExecShell(`cd ${workdir}/ && git rev-parse HEAD`);
|
const { stdout: commit } = await asyncExecShell(`cd ${workdir}/ && git rev-parse HEAD`);
|
||||||
return commit.replace('\n', '');
|
return commit.replace('\n', '');
|
||||||
}
|
}
|
||||||
|
@ -655,7 +655,7 @@ async function startLanguageToolService(request: FastifyRequest<ServiceStartStop
|
|||||||
image: config.languagetool.image,
|
image: config.languagetool.image,
|
||||||
environment: config.languagetool.environmentVariables,
|
environment: config.languagetool.environmentVariables,
|
||||||
...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}),
|
...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}),
|
||||||
volumes: config.languagetool,
|
volumes: config.languagetool.volumes,
|
||||||
labels: makeLabelForServices('languagetool'),
|
labels: makeLabelForServices('languagetool'),
|
||||||
...defaultComposeConfiguration(network),
|
...defaultComposeConfiguration(network),
|
||||||
}
|
}
|
||||||
@ -710,7 +710,7 @@ async function startN8nService(request: FastifyRequest<ServiceStartStop>) {
|
|||||||
[id]: {
|
[id]: {
|
||||||
container_name: id,
|
container_name: id,
|
||||||
image: config.n8n.image,
|
image: config.n8n.image,
|
||||||
volumes: config.n8n,
|
volumes: config.n8n.volumes,
|
||||||
environment: config.n8n.environmentVariables,
|
environment: config.n8n.environmentVariables,
|
||||||
labels: makeLabelForServices('n8n'),
|
labels: makeLabelForServices('n8n'),
|
||||||
...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}),
|
...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}),
|
||||||
@ -1116,7 +1116,6 @@ async function startUmamiService(request: FastifyRequest<ServiceStartStop>) {
|
|||||||
},
|
},
|
||||||
volumes: volumeMounts
|
volumes: volumeMounts
|
||||||
};
|
};
|
||||||
console.log(composeFile)
|
|
||||||
const composeFileDestination = `${workdir}/docker-compose.yaml`;
|
const composeFileDestination = `${workdir}/docker-compose.yaml`;
|
||||||
await fs.writeFile(composeFileDestination, yaml.dump(composeFile));
|
await fs.writeFile(composeFileDestination, yaml.dump(composeFile));
|
||||||
await startServiceContainers(destinationDocker.id, composeFileDestination)
|
await startServiceContainers(destinationDocker.id, composeFileDestination)
|
||||||
|
@ -74,14 +74,21 @@ export async function getApplicationStatus(request: FastifyRequest<OnlyId>) {
|
|||||||
const { teamId } = request.user
|
const { teamId } = request.user
|
||||||
let isRunning = false;
|
let isRunning = false;
|
||||||
let isExited = false;
|
let isExited = false;
|
||||||
|
let isRestarting = false;
|
||||||
const application: any = await getApplicationFromDB(id, teamId);
|
const application: any = await getApplicationFromDB(id, teamId);
|
||||||
if (application?.destinationDockerId) {
|
if (application?.destinationDockerId) {
|
||||||
isRunning = await checkContainer({ dockerId: application.destinationDocker.id, container: id });
|
const status = await checkContainer({ dockerId: application.destinationDocker.id, container: id });
|
||||||
isExited = await isContainerExited(application.destinationDocker.id, id);
|
if (status?.found) {
|
||||||
|
isRunning = status.status.isRunning;
|
||||||
|
isExited = status.status.isExited;
|
||||||
|
isRestarting = status.status.isRestarting
|
||||||
|
}
|
||||||
|
|
||||||
|
// isExited = await isContainerExited(application.destinationDocker.id, id);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
isRunning,
|
isRunning,
|
||||||
|
isRestarting,
|
||||||
isExited,
|
isExited,
|
||||||
};
|
};
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
@ -339,7 +346,7 @@ export async function stopPreviewApplication(request: FastifyRequest<StopPreview
|
|||||||
if (application?.destinationDockerId) {
|
if (application?.destinationDockerId) {
|
||||||
const container = `${id}-${pullmergeRequestId}`
|
const container = `${id}-${pullmergeRequestId}`
|
||||||
const { id: dockerId } = application.destinationDocker;
|
const { id: dockerId } = application.destinationDocker;
|
||||||
const found = await checkContainer({ dockerId, container });
|
const { found } = await checkContainer({ dockerId, container });
|
||||||
if (found) {
|
if (found) {
|
||||||
await removeContainer({ id: container, dockerId: application.destinationDocker.id });
|
await removeContainer({ id: container, dockerId: application.destinationDocker.id });
|
||||||
}
|
}
|
||||||
@ -366,7 +373,10 @@ export async function restartApplication(request: FastifyRequest<OnlyId>, reply:
|
|||||||
if (secrets.length > 0) {
|
if (secrets.length > 0) {
|
||||||
secrets.forEach((secret) => {
|
secrets.forEach((secret) => {
|
||||||
if (pullmergeRequestId) {
|
if (pullmergeRequestId) {
|
||||||
if (secret.isPRMRSecret) {
|
const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret)
|
||||||
|
if (isSecretFound.length > 0) {
|
||||||
|
envs.push(`${secret.name}=${isSecretFound[0].value}`);
|
||||||
|
} else {
|
||||||
envs.push(`${secret.name}=${secret.value}`);
|
envs.push(`${secret.name}=${secret.value}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -463,7 +473,7 @@ export async function stopApplication(request: FastifyRequest<OnlyId>, reply: Fa
|
|||||||
const application: any = await getApplicationFromDB(id, teamId);
|
const application: any = await getApplicationFromDB(id, teamId);
|
||||||
if (application?.destinationDockerId) {
|
if (application?.destinationDockerId) {
|
||||||
const { id: dockerId } = application.destinationDocker;
|
const { id: dockerId } = application.destinationDocker;
|
||||||
const found = await checkContainer({ dockerId, container: id });
|
const { found } = await checkContainer({ dockerId, container: id });
|
||||||
if (found) {
|
if (found) {
|
||||||
await removeContainer({ id, dockerId: application.destinationDocker.id });
|
await removeContainer({ id, dockerId: application.destinationDocker.id });
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ export async function getDestinationStatus(request: FastifyRequest<OnlyId>) {
|
|||||||
try {
|
try {
|
||||||
const { id } = request.params
|
const { id } = request.params
|
||||||
const destination = await prisma.destinationDocker.findUnique({ where: { id } })
|
const destination = await prisma.destinationDocker.findUnique({ where: { id } })
|
||||||
const isRunning = await checkContainer({ dockerId: destination.id, container: 'coolify-proxy', remove: true })
|
const { found: isRunning } = await checkContainer({ dockerId: destination.id, container: 'coolify-proxy', remove: true })
|
||||||
return {
|
return {
|
||||||
isRunning
|
isRunning
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ export async function cleanupManually(request: FastifyRequest) {
|
|||||||
}
|
}
|
||||||
export async function checkUpdate(request: FastifyRequest) {
|
export async function checkUpdate(request: FastifyRequest) {
|
||||||
try {
|
try {
|
||||||
const isStaging = request.hostname === 'staging.coolify.io'
|
const isStaging = request.hostname === 'staging.coolify.io' || request.hostname === 'arm.coolify.io'
|
||||||
const currentVersion = version;
|
const currentVersion = version;
|
||||||
const { data: versions } = await axios.get(
|
const { data: versions } = await axios.get(
|
||||||
`https://get.coollabs.io/versions.json?appId=${process.env['COOLIFY_APP_ID']}&version=${currentVersion}`
|
`https://get.coollabs.io/versions.json?appId=${process.env['COOLIFY_APP_ID']}&version=${currentVersion}`
|
||||||
|
@ -43,13 +43,17 @@ export async function getServiceStatus(request: FastifyRequest<OnlyId>) {
|
|||||||
|
|
||||||
let isRunning = false;
|
let isRunning = false;
|
||||||
let isExited = false
|
let isExited = false
|
||||||
|
let isRestarting = false;
|
||||||
const service = await getServiceFromDB({ id, teamId });
|
const service = await getServiceFromDB({ id, teamId });
|
||||||
const { destinationDockerId, settings } = service;
|
const { destinationDockerId, settings } = service;
|
||||||
|
|
||||||
if (destinationDockerId) {
|
if (destinationDockerId) {
|
||||||
isRunning = await checkContainer({ dockerId: service.destinationDocker.id, container: id });
|
const status = await checkContainer({ dockerId: service.destinationDocker.id, container: id });
|
||||||
isExited = await isContainerExited(service.destinationDocker.id, id);
|
if (status?.found) {
|
||||||
|
isRunning = status.status.isRunning;
|
||||||
|
isExited = status.status.isExited;
|
||||||
|
isRestarting = status.status.isRestarting
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
isRunning,
|
isRunning,
|
||||||
@ -554,7 +558,7 @@ export async function activateWordpressFtp(request: FastifyRequest<ActivateWordp
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isRunning = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-ftp` });
|
const { found: isRunning } = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-ftp` });
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
await executeDockerCmd({
|
await executeDockerCmd({
|
||||||
dockerId: destinationDocker.id,
|
dockerId: destinationDocker.id,
|
||||||
|
@ -154,7 +154,7 @@ export async function gitHubEvents(request: FastifyRequest<GitHubEvents>): Promi
|
|||||||
|
|
||||||
if (application.settings.previews) {
|
if (application.settings.previews) {
|
||||||
if (application.destinationDockerId) {
|
if (application.destinationDockerId) {
|
||||||
const isRunning = await checkContainer(
|
const { found: isRunning } = await checkContainer(
|
||||||
{
|
{
|
||||||
dockerId: application.destinationDocker.id,
|
dockerId: application.destinationDocker.id,
|
||||||
container: application.id
|
container: application.id
|
||||||
|
@ -107,7 +107,7 @@ export async function gitLabEvents(request: FastifyRequest<GitLabEvents>) {
|
|||||||
const buildId = cuid();
|
const buildId = cuid();
|
||||||
if (application.settings.previews) {
|
if (application.settings.previews) {
|
||||||
if (application.destinationDockerId) {
|
if (application.destinationDockerId) {
|
||||||
const isRunning = await checkContainer(
|
const { found: isRunning } = await checkContainer(
|
||||||
{
|
{
|
||||||
dockerId: application.destinationDocker.id,
|
dockerId: application.destinationDocker.id,
|
||||||
container: application.id
|
container: application.id
|
||||||
|
@ -73,6 +73,7 @@ export const status: Writable<any> = writable({
|
|||||||
application: {
|
application: {
|
||||||
isRunning: false,
|
isRunning: false,
|
||||||
isExited: false,
|
isExited: false,
|
||||||
|
isRestarting: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
initialLoading: true
|
initialLoading: true
|
||||||
},
|
},
|
||||||
|
@ -107,7 +107,7 @@
|
|||||||
$status.application.initialLoading = true;
|
$status.application.initialLoading = true;
|
||||||
try {
|
try {
|
||||||
await del(`/applications/${id}`, { id, force });
|
await del(`/applications/${id}`, { id, force });
|
||||||
return await goto(`/`, { replaceState: true });
|
return await window.location.assign(`/`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.message.startsWith(`Command failed: SSH_AUTH_SOCK=/tmp/coolify-ssh-agent.pid`)) {
|
if (error.message.startsWith(`Command failed: SSH_AUTH_SOCK=/tmp/coolify-ssh-agent.pid`)) {
|
||||||
forceDelete = true;
|
forceDelete = true;
|
||||||
@ -154,6 +154,7 @@
|
|||||||
const data = await get(`/applications/${id}/status`);
|
const data = await get(`/applications/${id}/status`);
|
||||||
$status.application.isRunning = data.isRunning;
|
$status.application.isRunning = data.isRunning;
|
||||||
$status.application.isExited = data.isExited;
|
$status.application.isExited = data.isExited;
|
||||||
|
$status.application.isRestarting = data.isRestarting;
|
||||||
$status.application.loading = false;
|
$status.application.loading = false;
|
||||||
$status.application.initialLoading = false;
|
$status.application.initialLoading = false;
|
||||||
}
|
}
|
||||||
@ -162,6 +163,7 @@
|
|||||||
$status.application.initialLoading = true;
|
$status.application.initialLoading = true;
|
||||||
$status.application.isRunning = false;
|
$status.application.isRunning = false;
|
||||||
$status.application.isExited = false;
|
$status.application.isExited = false;
|
||||||
|
$status.application.isRestarting = false;
|
||||||
$status.application.loading = false;
|
$status.application.loading = false;
|
||||||
$location = null;
|
$location = null;
|
||||||
$isDeploymentEnabled = false;
|
$isDeploymentEnabled = false;
|
||||||
@ -171,6 +173,7 @@
|
|||||||
setLocation(application, settings);
|
setLocation(application, settings);
|
||||||
$status.application.isRunning = false;
|
$status.application.isRunning = false;
|
||||||
$status.application.isExited = false;
|
$status.application.isExited = false;
|
||||||
|
$status.application.isRestarting = false;
|
||||||
$status.application.loading = false;
|
$status.application.loading = false;
|
||||||
if (
|
if (
|
||||||
application.gitSourceId &&
|
application.gitSourceId &&
|
||||||
@ -215,7 +218,7 @@
|
|||||||
<div class="border border-coolgray-500 h-8" />
|
<div class="border border-coolgray-500 h-8" />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if $status.application.isExited}
|
{#if $status.application.isExited || $status.application.isRestarting}
|
||||||
<a
|
<a
|
||||||
id="applicationerror"
|
id="applicationerror"
|
||||||
href={$isDeploymentEnabled ? `/applications/${id}/logs` : null}
|
href={$isDeploymentEnabled ? `/applications/${id}/logs` : null}
|
||||||
@ -240,7 +243,30 @@
|
|||||||
<line x1="12" y1="16" x2="12.01" y2="16" />
|
<line x1="12" y1="16" x2="12.01" y2="16" />
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<Tooltip triggeredBy="#applicationerror">Application exited with an error!</Tooltip>
|
<Tooltip triggeredBy="#applicationerror">Application exited or restarting!</Tooltip>
|
||||||
|
<button
|
||||||
|
id="stop"
|
||||||
|
on:click={stopApplication}
|
||||||
|
type="submit"
|
||||||
|
disabled={!$isDeploymentEnabled}
|
||||||
|
class="icons bg-transparent text-sm flex items-center space-x-2 text-error"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="w-6 h-6"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<rect x="6" y="5" width="4" height="14" rx="1" />
|
||||||
|
<rect x="14" y="5" width="4" height="14" rx="1" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<Tooltip triggeredBy="#stop">Stop</Tooltip>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $status.application.initialLoading}
|
{#if $status.application.initialLoading}
|
||||||
<button
|
<button
|
||||||
|
@ -220,7 +220,6 @@
|
|||||||
loading = true;
|
loading = true;
|
||||||
try {
|
try {
|
||||||
nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, '');
|
nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, '');
|
||||||
console.log({debug: nonWWWDomain})
|
|
||||||
if (application.deploymentType)
|
if (application.deploymentType)
|
||||||
application.deploymentType = application.deploymentType.toLowerCase();
|
application.deploymentType = application.deploymentType.toLowerCase();
|
||||||
!isBot &&
|
!isBot &&
|
||||||
|
@ -103,7 +103,7 @@
|
|||||||
<button
|
<button
|
||||||
id="follow"
|
id="follow"
|
||||||
on:click={followBuild}
|
on:click={followBuild}
|
||||||
class="bg-transparent btn btn-sm btn-linkhover:text-green-500 hover:bg-coolgray-500"
|
class="bg-transparent btn btn-sm btn-link hover:text-green-500 hover:bg-coolgray-500"
|
||||||
class:text-green-500={followingBuild}
|
class:text-green-500={followingBuild}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
import LoadingLogs from '$lib/components/LoadingLogs.svelte';
|
import LoadingLogs from '$lib/components/LoadingLogs.svelte';
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||||
|
import { status } from '$lib/store';
|
||||||
|
import { goto } from '$app/navigation';
|
||||||
let application: any = {};
|
let application: any = {};
|
||||||
let logsLoading = false;
|
let logsLoading = false;
|
||||||
let loadLogsInterval: any = null;
|
let loadLogsInterval: any = null;
|
||||||
@ -16,7 +17,13 @@
|
|||||||
let followingLogs: any;
|
let followingLogs: any;
|
||||||
let logsEl: any;
|
let logsEl: any;
|
||||||
let position = 0;
|
let position = 0;
|
||||||
|
if (
|
||||||
|
!$status.application.isExited &&
|
||||||
|
!$status.application.isRestarting &&
|
||||||
|
!$status.application.isRunning
|
||||||
|
) {
|
||||||
|
goto(`/applications/${$page.params.id}/`, { replaceState: true });
|
||||||
|
}
|
||||||
const { id } = $page.params;
|
const { id } = $page.params;
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
const response = await get(`/applications/${id}`);
|
const response = await get(`/applications/${id}`);
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
$status.database.initialLoading = true;
|
$status.database.initialLoading = true;
|
||||||
try {
|
try {
|
||||||
await del(`/databases/${database.id}`, { id: database.id, force });
|
await del(`/databases/${database.id}`, { id: database.id, force });
|
||||||
return await goto('/', { replaceState: true });
|
return await window.location.assign('/');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -112,7 +112,7 @@
|
|||||||
<button
|
<button
|
||||||
id="follow"
|
id="follow"
|
||||||
on:click={followBuild}
|
on:click={followBuild}
|
||||||
class="bg-transparent btn btn-sm"
|
class="bg-transparent btn btn-sm btn-link"
|
||||||
class:text-green-500={followingLogs}
|
class:text-green-500={followingLogs}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
@ -188,6 +188,7 @@
|
|||||||
return (
|
return (
|
||||||
(service.name && service.name.toLowerCase().includes($search.toLowerCase())) ||
|
(service.name && service.name.toLowerCase().includes($search.toLowerCase())) ||
|
||||||
(service.type && service.type.toLowerCase().includes($search.toLowerCase())) ||
|
(service.type && service.type.toLowerCase().includes($search.toLowerCase())) ||
|
||||||
|
(service.fqdn && service.fqdn.toLowerCase().includes($search.toLowerCase())) ||
|
||||||
(service.version && service.version.toLowerCase().includes($search.toLowerCase())) ||
|
(service.version && service.version.toLowerCase().includes($search.toLowerCase())) ||
|
||||||
(service.destinationDockerId &&
|
(service.destinationDockerId &&
|
||||||
service.destinationDocker.name.toLowerCase().includes($search.toLowerCase()))
|
service.destinationDocker.name.toLowerCase().includes($search.toLowerCase()))
|
||||||
|
@ -85,7 +85,7 @@
|
|||||||
if (service.type && $status.service.isRunning)
|
if (service.type && $status.service.isRunning)
|
||||||
await post(`/services/${service.id}/${service.type}/stop`, {});
|
await post(`/services/${service.id}/${service.type}/stop`, {});
|
||||||
await del(`/services/${service.id}`, { id: service.id });
|
await del(`/services/${service.id}`, { id: service.id });
|
||||||
return await goto(`/`, { replaceState: true });
|
return await window.location.assign(`/`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -128,7 +128,7 @@
|
|||||||
<button
|
<button
|
||||||
id="follow"
|
id="follow"
|
||||||
on:click={followBuild}
|
on:click={followBuild}
|
||||||
class="bg-transparent btn btn-sm"
|
class="bg-transparent btn btn-sm btn-link"
|
||||||
class:text-green-500={followingLogs}
|
class:text-green-500={followingLogs}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
@ -200,21 +200,6 @@
|
|||||||
<input name="name" id="name" required bind:value={source.name} />
|
<input name="name" id="name" required bind:value={source.name} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if source.gitlabApp.groupName}
|
|
||||||
<div class="grid grid-cols-2 items-center">
|
|
||||||
<label for="groupName" class="text-base font-bold text-stone-100"
|
|
||||||
>{$t('source.group_name')}</label
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
name="groupName"
|
|
||||||
id="groupName"
|
|
||||||
disabled={source.gitlabAppId}
|
|
||||||
readonly={source.gitlabAppId}
|
|
||||||
required
|
|
||||||
bind:value={source.gitlabApp.groupName}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<div class="grid grid-cols-2 items-center">
|
<div class="grid grid-cols-2 items-center">
|
||||||
<label for="htmlUrl" class="text-base font-bold text-stone-100">HTML URL</label>
|
<label for="htmlUrl" class="text-base font-bold text-stone-100">HTML URL</label>
|
||||||
<input
|
<input
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "coolify",
|
"name": "coolify",
|
||||||
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
|
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
|
||||||
"version": "3.10.0",
|
"version": "3.10.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": "github:coollabsio/coolify",
|
"repository": "github:coollabsio/coolify",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
Loading…
Reference in New Issue
Block a user