fix: show restarting application & logs
This commit is contained in:
parent
871d1e2440
commit
c5bcff0e10
@ -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,9 +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' || status === 'restarting';
|
const isRunning = status === 'running';
|
||||||
|
const isRestarting = status === 'restarting'
|
||||||
|
const isExited = status === 'exited'
|
||||||
if (status === 'created') {
|
if (status === 'created') {
|
||||||
await executeDockerCmd({
|
await executeDockerCmd({
|
||||||
dockerId,
|
dockerId,
|
||||||
@ -38,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', '');
|
||||||
}
|
}
|
||||||
|
@ -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 });
|
||||||
}
|
}
|
||||||
@ -463,7 +470,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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
},
|
},
|
||||||
|
@ -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
|
||||||
|
@ -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}`);
|
||||||
|
Loading…
Reference in New Issue
Block a user