Fixes: 
- Default Nuxt port changed to 3000 (thanks to @yurgeman).
- Cleanup old images effectively.
- More attempts on container startups (3->6).
- Always clean up server logs on restart/redeploy.
This commit is contained in:
Andras Bacsai 2021-04-26 11:45:04 +02:00 committed by GitHub
parent e16b7d65d4
commit b416e3ab3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 22 additions and 25 deletions

View File

@ -2,9 +2,12 @@ const { docker } = require('../../docker')
const { execShellAsync } = require('../../common') const { execShellAsync } = require('../../common')
const Deployment = require('../../../models/Deployment') const Deployment = require('../../../models/Deployment')
async function purgeImagesContainers () { async function purgeImagesContainers (configuration) {
const { name, tag } = configuration.build.container
await execShellAsync('docker container prune -f') await execShellAsync('docker container prune -f')
await execShellAsync('docker image prune -f --filter=label!=coolify-reserve=true') 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 !== 0) for (const id of IDsToDelete) await execShellAsync(`docker rmi -f ${id}`)
await execShellAsync('docker image prune -f')
} }
async function cleanupStuckedDeploymentsInDB () { async function cleanupStuckedDeploymentsInDB () {

View File

@ -1,19 +1,16 @@
const dayjs = require('dayjs') const dayjs = require('dayjs')
const { cleanupTmp } = require('../common')
const { saveAppLog } = require('../logging') const { saveAppLog } = require('../logging')
const copyFiles = require('./deploy/copyFiles') const copyFiles = require('./deploy/copyFiles')
const buildContainer = require('./build/container') const buildContainer = require('./build/container')
const deploy = require('./deploy/deploy') const deploy = require('./deploy/deploy')
const Deployment = require('../../models/Deployment') const Deployment = require('../../models/Deployment')
const { purgeImagesContainers } = require('./cleanup')
const { updateServiceLabels } = require('./configuration') const { updateServiceLabels } = require('./configuration')
async function queueAndBuild (configuration, imageChanged) { async function queueAndBuild (configuration, imageChanged) {
const { id, organization, name, branch } = configuration.repository const { id, organization, name, branch } = configuration.repository
const { domain } = configuration.publish const { domain } = configuration.publish
const { deployId, nickname, workdir } = configuration.general const { deployId, nickname } = configuration.general
await new Deployment({ await new Deployment({
repoId: id, branch, deployId, domain, organization, name, nickname repoId: id, branch, deployId, domain, organization, name, nickname
}).save() }).save()
@ -25,8 +22,6 @@ async function queueAndBuild (configuration, imageChanged) {
{ repoId: id, branch, deployId, organization, name, domain }, { repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'done' }) { repoId: id, branch, deployId, organization, name, domain, progress: 'done' })
await updateServiceLabels(configuration) await updateServiceLabels(configuration)
cleanupTmp(workdir)
await purgeImagesContainers()
} }
module.exports = { queueAndBuild } module.exports = { queueAndBuild }

View File

@ -10,7 +10,7 @@ const baseServiceConfiguration = {
replicas: 1, replicas: 1,
restart_policy: { restart_policy: {
condition: 'any', condition: 'any',
max_attempts: 3 max_attempts: 6
}, },
update_config: { update_config: {
parallelism: 1, parallelism: 1,

View File

@ -2,6 +2,7 @@
const Deployment = require('../../../../models/Deployment') const Deployment = require('../../../../models/Deployment')
const ApplicationLog = require('../../../../models/Logs/Application') const ApplicationLog = require('../../../../models/Logs/Application')
const { verifyUserId, cleanupTmp } = require('../../../../libs/common') const { verifyUserId, cleanupTmp } = require('../../../../libs/common')
const { purgeImagesContainers } = require('../../../../libs/applications/cleanup')
const { queueAndBuild } = require('../../../../libs/applications') const { queueAndBuild } = require('../../../../libs/applications')
const { setDefaultConfiguration, precheckDeployment } = require('../../../../libs/applications/configuration') const { setDefaultConfiguration, precheckDeployment } = require('../../../../libs/applications/configuration')
const { docker } = require('../../../../libs/docker') const { docker } = require('../../../../libs/docker')
@ -55,12 +56,14 @@ module.exports = async function (fastify) {
await Deployment.findOneAndUpdate( await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain }, { repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'failed' }) { repoId: id, branch, deployId, organization, name, domain, progress: 'failed' })
cleanupTmp(configuration.general.workdir)
if (error.name) { if (error.name) {
if (error.message && error.stack) await saveServerLog(error) if (error.message && error.stack) await saveServerLog(error)
if (reply.sent) await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save() if (reply.sent) await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save()
} }
throw new Error(error) throw new Error(error)
} finally {
cleanupTmp(configuration.general.workdir)
await purgeImagesContainers(configuration)
} }
}) })
} }

View File

@ -9,6 +9,7 @@ const { queueAndBuild } = require('../../../libs/applications')
const { setDefaultConfiguration, precheckDeployment } = require('../../../libs/applications/configuration') const { setDefaultConfiguration, precheckDeployment } = require('../../../libs/applications/configuration')
const { docker } = require('../../../libs/docker') const { docker } = require('../../../libs/docker')
const cloneRepository = require('../../../libs/applications/github/cloneRepository') const cloneRepository = require('../../../libs/applications/github/cloneRepository')
const { purgeImagesContainers } = require('../../../libs/applications/cleanup')
module.exports = async function (fastify) { module.exports = async function (fastify) {
// TODO: Add this to fastify plugin // TODO: Add this to fastify plugin
@ -93,9 +94,9 @@ module.exports = async function (fastify) {
reply.code(200).send({ message: 'Already in the queue.' }) reply.code(200).send({ message: 'Already in the queue.' })
return return
} }
queueAndBuild(configuration, imageChanged)
reply.code(201).send({ message: 'Deployment queued.', nickname: configuration.general.nickname, name: configuration.build.container.name }) reply.code(201).send({ message: 'Deployment queued.', nickname: configuration.general.nickname, name: configuration.build.container.name })
await queueAndBuild(configuration, imageChanged)
} catch (error) { } catch (error) {
const { id, organization, name, branch } = configuration.repository const { id, organization, name, branch } = configuration.repository
const { domain } = configuration.publish const { domain } = configuration.publish
@ -103,7 +104,6 @@ module.exports = async function (fastify) {
await Deployment.findOneAndUpdate( await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain }, { repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'failed' }) { repoId: id, branch, deployId, organization, name, domain, progress: 'failed' })
cleanupTmp(configuration.general.workdir)
if (error.name === 'Error') { if (error.name === 'Error') {
// Error during runtime // Error during runtime
await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save() await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save()
@ -114,6 +114,9 @@ module.exports = async function (fastify) {
if (reply.sent) await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save() if (reply.sent) await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save()
} }
throw new Error(error) throw new Error(error)
} finally {
cleanupTmp(configuration.general.workdir)
await purgeImagesContainers(configuration)
} }
}) })
} }

View File

@ -85,10 +85,8 @@ mongoose.connection.once('open', async function () {
console.log('Coolify API is up and running in development.') console.log('Coolify API is up and running in development.')
} }
try { try {
const { main } = (await axios.get('https://get.coollabs.io/version.json')).data.coolify // Always cleanup server logs
if (main.clearServerLogs) { await mongoose.connection.db.dropCollection('logs-servers')
await mongoose.connection.db.dropCollection('logs-servers')
}
} catch (error) { } catch (error) {
// Could not cleanup logs-servers collection // Could not cleanup logs-servers collection
} }
@ -102,16 +100,11 @@ mongoose.connection.once('open', async function () {
// Doing because I do not want to prune these images. Prune skips coolify-reserve labeled images. // Doing because I do not want to prune these images. Prune skips coolify-reserve labeled images.
const basicImages = ['nginx:stable-alpine', 'node:lts', 'ubuntu:20.04', 'php:apache', 'rust:latest'] const basicImages = ['nginx:stable-alpine', 'node:lts', 'ubuntu:20.04', 'php:apache', 'rust:latest']
for (const image of basicImages) { for (const image of basicImages) {
await execShellAsync(`echo "FROM ${image}" | docker build --label coolify-reserve=true -t ${image} -`) // await execShellAsync(`echo "FROM ${image}" | docker build --label coolify-reserve=true -t ${image} -`)
await execShellAsync(`docker pull ${image}`)
} }
} catch (error) { } catch (error) {
console.log('Could not pull some basic images from Docker Hub.') console.log('Could not pull some basic images from Docker Hub.')
console.log(error) console.log(error)
} }
try {
await purgeImagesContainers()
} catch (error) {
console.log('Could not purge containers/images.')
console.log(error)
}
}) })

View File

@ -1,7 +1,7 @@
{ {
"name": "coolify", "name": "coolify",
"description": "An open-source, hassle-free, self-hostable Heroku & Netlify alternative.", "description": "An open-source, hassle-free, self-hostable Heroku & Netlify alternative.",
"version": "1.0.9", "version": "1.0.10",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
"lint": "standard", "lint": "standard",

View File

@ -13,7 +13,7 @@ const templates = {
nuxt: { nuxt: {
pack: 'nodejs', pack: 'nodejs',
...defaultBuildAndDeploy, ...defaultBuildAndDeploy,
port: 8080, port: 3000,
name: 'Nuxt' name: 'Nuxt'
}, },
'react-scripts': { 'react-scripts': {