This commit is contained in:
Andras Bacsai
2021-05-16 21:54:44 +02:00
committed by GitHub
parent 23a4ebb74a
commit adcd68c1ab
68 changed files with 2466 additions and 1194 deletions

View File

@@ -1,4 +1,4 @@
import Deployment from '$models/Logs/Deployment';
import Deployment from '$models/Deployment';
import { saveAppLog } from './logging';
import * as packs from './packs';

View File

@@ -1,4 +1,5 @@
import { docker } from '$lib/api/docker';
import Deployment from '$models/Deployment';
import { execShellAsync } from '../common';
export async function deleteSameDeployments(configuration) {
@@ -17,29 +18,49 @@ export async function deleteSameDeployments(configuration) {
});
}
export async function cleanupStuckedDeploymentsInDB() {
// Cleanup stucked deployments.
await Deployment.updateMany(
{ progress: { $in: ['queued', 'inprogress'] } },
{ progress: 'failed' }
);
}
export async function purgeImagesContainers(configuration, deleteAll = false) {
const { name, tag } = configuration.build.container;
await execShellAsync('docker container prune -f');
if (deleteAll) {
const IDsToDelete = (
await execShellAsync(`docker images ls --filter=reference='${name}' --format '{{json .ID }}'`)
)
.trim()
.replace(/"/g, '')
.split('\n');
if (IDsToDelete.length > 0)
await execShellAsync(`docker rmi -f ${IDsToDelete.toString().replace(',', ' ')}`);
} else {
const IDsToDelete = (
await execShellAsync(
`docker images ls --filter=reference='${name}' --filter=before='${name}:${tag}' --format '{{json .ID }}'`
)
)
.trim()
.replace(/"/g, '')
.split('\n');
if (IDsToDelete.length > 1)
await execShellAsync(`docker rmi -f ${IDsToDelete.toString().replace(',', ' ')}`);
try {
await execShellAsync('docker container prune -f');
} catch (error) {
//
}
try {
if (deleteAll) {
const IDsToDelete = (
await execShellAsync(
`docker images ls --filter=reference='${name}' --format '{{json .ID }}'`
)
)
.trim()
.replace(/"/g, '')
.split('\n');
if (IDsToDelete.length > 0) await execShellAsync(`docker rmi -f ${IDsToDelete.join(' ')}`);
} else {
const IDsToDelete = (
await execShellAsync(
`docker images ls --filter=reference='${name}' --filter=before='${name}:${tag}' --format '{{json .ID }}'`
)
)
.trim()
.replace(/"/g, '')
.split('\n');
if (IDsToDelete.length > 1) await execShellAsync(`docker rmi -f ${IDsToDelete.join(' ')}`);
}
} catch (error) {
console.log(error);
}
try {
await execShellAsync('docker image prune -f');
} catch (error) {
//
}
await execShellAsync('docker image prune -f');
}

View File

@@ -1,9 +1,10 @@
import Settings from '$models/Settings';
import ServerLog from '$models/Logs/Server';
import ApplicationLog from '$models/Logs/Application';
import ServerLog from '$models/ServerLog';
import ApplicationLog from '$models/ApplicationLog';
import dayjs from 'dayjs';
import { version } from '../../../../package.json';
function generateTimestamp() {
return `${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} `;
}

View File

@@ -1,20 +1,21 @@
import { docker, streamEvents } from '$lib/api/docker';
import { promises as fs } from 'fs';
const buildImageNodeDocker = (configuration) => {
const buildImageNodeDocker = (configuration, prodBuild) => {
return [
'FROM node:lts',
'WORKDIR /usr/src/app',
`COPY ${configuration.build.directory}/package*.json ./`,
configuration.build.command.installation && `RUN ${configuration.build.command.installation}`,
`COPY ./${configuration.build.directory} ./`,
`RUN ${configuration.build.command.build}`
`RUN ${configuration.build.command.build}`,
prodBuild && `RUN rm -fr node_modules && ${configuration.build.command.installation} --prod`
].join('\n');
};
export async function buildImage(configuration, cacheBuild?: boolean) {
export async function buildImage(configuration, cacheBuild?: boolean, prodBuild?: boolean) {
await fs.writeFile(
`${configuration.general.workdir}/Dockerfile`,
buildImageNodeDocker(configuration)
buildImageNodeDocker(configuration, prodBuild)
);
const stream = await docker.engine.buildImage(
{ src: ['.'], context: configuration.general.workdir },

View File

@@ -7,6 +7,7 @@ import php from './php';
import nuxtjs from './nuxtjs';
import nodejs from './nodejs';
import nextjs from './nextjs';
import nestjs from './nestjs';
import gatsby from './gatsby';
import docker from './docker';
@@ -20,6 +21,7 @@ export {
nuxtjs,
nodejs,
nextjs,
nestjs,
gatsby,
docker
};

View File

@@ -0,0 +1,31 @@
import { docker, streamEvents } from '$lib/api/docker';
import { promises as fs } from 'fs';
import { buildImage } from '../helpers';
// `HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost:${configuration.publish.port}${configuration.publish.path} || exit 1`,
const publishNodejsDocker = (configuration) => {
return [
'FROM node:lts',
'WORKDIR /usr/src/app',
configuration.build.command.build
? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag} /usr/src/app/${configuration.publish.directory} ./`
: `
COPY ${configuration.build.directory}/package*.json ./
RUN ${configuration.build.command.installation}
COPY ./${configuration.build.directory} ./`,
`EXPOSE ${configuration.publish.port}`,
`CMD ${configuration.build.command.start}`
].join('\n');
};
export default async function (configuration) {
if (configuration.build.command.build) await buildImage(configuration, false, true);
await fs.writeFile(
`${configuration.general.workdir}/Dockerfile`,
publishNodejsDocker(configuration)
);
const stream = await docker.engine.buildImage(
{ src: ['.'], context: configuration.general.workdir },
{ t: `${configuration.build.container.name}:${configuration.build.container.tag}` }
);
await streamEvents(stream, configuration);
}

View File

@@ -13,7 +13,7 @@ const publishNodejsDocker = (configuration) => {
RUN ${configuration.build.command.installation}
COPY ./${configuration.build.directory} ./`,
`EXPOSE ${configuration.publish.port}`,
'CMD [ "yarn", "start" ]'
`CMD ${configuration.build.command.start}`
].join('\n');
};
export default async function (configuration) {

View File

@@ -13,7 +13,7 @@ const publishNodejsDocker = (configuration) => {
RUN ${configuration.build.command.installation}
COPY ./${configuration.build.directory} ./`,
`EXPOSE ${configuration.publish.port}`,
'CMD [ "yarn", "start" ]'
`CMD ${configuration.build.command.start}`
].join('\n');
};

View File

@@ -13,7 +13,7 @@ const publishNodejsDocker = (configuration) => {
RUN ${configuration.build.command.installation}
COPY ./${configuration.build.directory} ./`,
`EXPOSE ${configuration.publish.port}`,
'CMD [ "yarn", "start" ]'
`CMD ${configuration.build.command.start}`
].join('\n');
};

View File

@@ -1,6 +1,7 @@
const defaultBuildAndDeploy = {
installation: 'yarn install',
build: 'yarn build'
build: 'yarn build',
start: 'yarn start'
};
const templates = {
@@ -10,6 +11,13 @@ const templates = {
directory: 'public',
name: 'Svelte'
},
'@nestjs/core': {
pack: 'nestjs',
...defaultBuildAndDeploy,
start: 'yarn start:prod',
port: 3000,
name: 'NestJS'
},
next: {
pack: 'nextjs',
...defaultBuildAndDeploy,

View File

@@ -1,4 +1,5 @@
import Deployment from '$models/Logs/Deployment';
import Deployment from '$models/Deployment';
import dayjs from 'dayjs';
import buildContainer from './buildContainer';
import { updateServiceLabels } from './configuration';
@@ -9,23 +10,21 @@ import { saveAppLog } from './logging';
export default async function (configuration, imageChanged) {
const { id, organization, name, branch } = configuration.repository;
const { domain } = configuration.publish;
const { deployId, nickname } = configuration.general;
await new Deployment({
repoId: id,
branch,
deployId,
domain,
organization,
name,
nickname
}).save();
await saveAppLog(`${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} Queued.`, configuration);
await copyFiles(configuration);
await buildContainer(configuration);
await deploy(configuration, imageChanged);
await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'done' }
);
await updateServiceLabels(configuration);
const { deployId} = configuration.general;
try {
await saveAppLog(`${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} Queued.`, configuration);
await copyFiles(configuration);
await buildContainer(configuration);
await deploy(configuration, imageChanged);
await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'done' }
);
await updateServiceLabels(configuration);
} catch (error) {
await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'failed' }
);
}
}