New features:
- Automatic error reporting (enabled by default)
- Increase build times by leveraging docker build caches
- 
Fixes:
- Fix error handling
- Fix vue autodetect
- Custom dockerfile is not the default

Others:
- Cleanup `logs-servers` collection, because old errors are not standardized
- New Traefik proxy version
- Standardized directory configurations
This commit is contained in:
Andras Bacsai
2021-04-19 09:46:05 +02:00
committed by GitHub
parent bad84289c4
commit 142b83cc13
51 changed files with 1300 additions and 837 deletions

View File

@@ -1,15 +1,11 @@
const { verifyUserId } = require('../../../libs/common')
const { setDefaultConfiguration } = require('../../../libs/applications/configuration')
const { docker } = require('../../../libs/docker')
const { saveServerLog } = require('../../../libs/logging')
module.exports = async function (fastify) {
fastify.post('/', async (request, reply) => {
try {
if (!await verifyUserId(request.headers.authorization)) {
reply.code(500).send({ error: 'Invalid request' })
return
}
const configuration = setDefaultConfiguration(request.body)
const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application')
@@ -34,7 +30,8 @@ module.exports = async function (fastify) {
}
return { message: 'OK' }
} catch (error) {
throw { error, type: 'server' }
await saveServerLog(error)
throw new Error(error)
}
})
}

View File

@@ -1,37 +1,16 @@
const { verifyUserId, cleanupTmp } = require('../../../../libs/common')
const Deployment = require('../../../../models/Deployment')
const ApplicationLog = require('../../../../models/Logs/Application')
const { verifyUserId, cleanupTmp } = require('../../../../libs/common')
const { queueAndBuild } = require('../../../../libs/applications')
const { setDefaultConfiguration, precheckDeployment } = require('../../../../libs/applications/configuration')
const { docker } = require('../../../../libs/docker')
const { saveServerLog } = require('../../../../libs/logging')
const cloneRepository = require('../../../../libs/applications/github/cloneRepository')
module.exports = async function (fastify) {
// const postSchema = {
// body: {
// type: "object",
// properties: {
// ref: { type: "string" },
// repository: {
// type: "object",
// properties: {
// id: { type: "number" },
// full_name: { type: "string" },
// },
// required: ["id", "full_name"],
// },
// installation: {
// type: "object",
// properties: {
// id: { type: "number" },
// },
// required: ["id"],
// },
// },
// required: ["ref", "repository", "installation"],
// },
// };
fastify.post('/', async (request, reply) => {
let configuration
try {
await verifyUserId(request.headers.authorization)
} catch (error) {
@@ -40,7 +19,10 @@ module.exports = async function (fastify) {
}
try {
const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application')
const configuration = setDefaultConfiguration(request.body)
configuration = setDefaultConfiguration(request.body)
if (!configuration) {
throw new Error('Whaat?')
}
await cloneRepository(configuration)
const { foundService, imageChanged, configChanged, forceUpdate } = await precheckDeployment({ services, configuration })
@@ -64,11 +46,21 @@ module.exports = async function (fastify) {
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, deployId: configuration.general.deployId })
await queueAndBuild(configuration, imageChanged)
} catch (error) {
throw { error, type: 'server' }
const { id, organization, name, branch } = configuration.repository
const { domain } = configuration.publish
const { deployId } = configuration.general
await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'failed' })
cleanupTmp(configuration.general.workdir)
if (error.name) {
if (error.message && error.stack) await saveServerLog(error)
if (reply.sent) await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save()
}
throw new Error(error)
}
})
}

View File

@@ -39,7 +39,7 @@ module.exports = async function (fastify) {
})
return finalLogs
} catch (error) {
throw { error, type: 'server' }
throw new Error(error)
}
})

View File

@@ -1,4 +1,5 @@
const { docker } = require('../../../libs/docker')
const { saveServerLog } = require('../../../libs/logging')
module.exports = async function (fastify) {
fastify.get('/', async (request, reply) => {
@@ -8,7 +9,8 @@ module.exports = async function (fastify) {
const logs = (await service.logs({ stdout: true, stderr: true, timestamps: true })).toString().split('\n').map(l => l.slice(8)).filter((a) => a)
return { logs }
} catch (error) {
throw { error, type: 'server' }
await saveServerLog(error)
throw new Error(error)
}
})
}

View File

@@ -1,6 +1,7 @@
const { docker } = require('../../../libs/docker')
const Deployment = require('../../../models/Deployment')
const ServerLog = require('../../../models/Logs/Server')
const { saveServerLog } = require('../../../libs/logging')
module.exports = async function (fastify) {
fastify.get('/', async (request, reply) => {
@@ -21,10 +22,8 @@ module.exports = async function (fastify) {
}
}
])
const serverLogs = await ServerLog.find()
const services = await docker.engine.listServices()
let applications = services.filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application' && r.Spec.Labels.configuration)
let databases = services.filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'database' && r.Spec.Labels.configuration)
applications = applications.map(r => {
@@ -56,7 +55,8 @@ module.exports = async function (fastify) {
if (error.code === 'ENOENT' && error.errno === -2) {
throw new Error(`Docker service unavailable at ${error.address}.`)
} else {
throw { error, type: 'server' }
await saveServerLog(error)
throw new Error(error)
}
}
})

View File

@@ -3,6 +3,7 @@ const fs = require('fs').promises
const cuid = require('cuid')
const { docker } = require('../../../libs/docker')
const { execShellAsync } = require('../../../libs/common')
const { saveServerLog } = require('../../../libs/logging')
const { uniqueNamesGenerator, adjectives, colors, animals } = require('unique-names-generator')
const generator = require('generate-password')
@@ -165,7 +166,8 @@ module.exports = async function (fastify) {
`cat ${configuration.general.workdir}/stack.yml | docker stack deploy -c - ${configuration.general.deployId}`
)
} catch (error) {
throw { error, type: 'server' }
await saveServerLog(error)
throw new Error(error)
}
})

View File

@@ -4,6 +4,8 @@ const Settings = require('../../../models/Settings')
const cuid = require('cuid')
const mongoose = require('mongoose')
const jwt = require('jsonwebtoken')
const { saveServerLog } = require('../../../libs/logging')
module.exports = async function (fastify) {
const githubCodeSchema = {
schema: {
@@ -59,8 +61,12 @@ module.exports = async function (fastify) {
avatar: avatar_url,
uid
})
const defaultSettings = new Settings({
_id: new mongoose.Types.ObjectId()
})
try {
await newUser.save()
await defaultSettings.save()
} catch (e) {
console.log(e)
reply.code(500).send({ success: false, error: e })
@@ -111,8 +117,8 @@ module.exports = async function (fastify) {
return
}
} catch (error) {
console.log(error)
reply.code(500).send({ success: false, error: error.message })
await saveServerLog(error)
throw new Error(error)
}
})
fastify.get('/success', async (request, reply) => {

View File

@@ -8,7 +8,7 @@ module.exports = async function (fastify) {
serverLogs
}
} catch (error) {
throw { error, type: 'server' }
throw new Error(error)
}
})
}

View File

@@ -1,13 +1,16 @@
const Settings = require('../../../models/Settings')
const { saveServerLog } = require('../../../libs/logging')
module.exports = async function (fastify) {
const applicationName = 'coolify'
const postSchema = {
body: {
type: 'object',
properties: {
allowRegistration: { type: 'boolean' }
allowRegistration: { type: 'boolean' },
sendErrors: { type: 'boolean' }
},
required: ['allowRegistration']
required: []
}
}
@@ -25,7 +28,8 @@ module.exports = async function (fastify) {
settings
}
} catch (error) {
throw { error, type: 'server' }
await saveServerLog(error)
throw new Error(error)
}
})
@@ -38,7 +42,8 @@ module.exports = async function (fastify) {
).select('-_id -__v')
reply.code(201).send({ settings })
} catch (error) {
throw { error, type: 'server' }
await saveServerLog(error)
throw new Error(error)
}
})
}

View File

@@ -4,9 +4,9 @@ const { saveServerLog } = require('../../../libs/logging')
module.exports = async function (fastify) {
fastify.get('/', async (request, reply) => {
const upgradeP1 = await execShellAsync('bash -c "$(curl -fsSL https://get.coollabs.io/coolify/upgrade-p1.sh)"')
await saveServerLog({ event: upgradeP1, type: 'UPGRADE-P-1' })
await saveServerLog({ message: upgradeP1, type: 'UPGRADE-P-1' })
reply.code(200).send('I\'m trying, okay?')
const upgradeP2 = await execShellAsync('docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -u root coolify bash -c "$(curl -fsSL https://get.coollabs.io/coolify/upgrade-p2.sh)"')
await saveServerLog({ event: upgradeP2, type: 'UPGRADE-P-2' })
await saveServerLog({ message: upgradeP2, type: 'UPGRADE-P-2' })
})
}

View File

@@ -1,6 +1,10 @@
const crypto = require('crypto')
const { cleanupTmp } = require('../../../libs/common')
const Deployment = require('../../../models/Deployment')
const ApplicationLog = require('../../../models/Logs/Application')
const ServerLog = require('../../../models/Logs/Server')
const { queueAndBuild } = require('../../../libs/applications')
const { setDefaultConfiguration, precheckDeployment } = require('../../../libs/applications/configuration')
const { docker } = require('../../../libs/docker')
@@ -33,6 +37,7 @@ module.exports = async function (fastify) {
}
}
fastify.post('/', { schema: postSchema }, async (request, reply) => {
let configuration
const hmac = crypto.createHmac('sha256', fastify.config.GITHUP_APP_WEBHOOK_SECRET)
const digest = Buffer.from('sha256=' + hmac.update(JSON.stringify(request.body)).digest('hex'), 'utf8')
const checksum = Buffer.from(request.headers['x-hub-signature-256'], 'utf8')
@@ -48,7 +53,7 @@ module.exports = async function (fastify) {
try {
const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application')
let configuration = services.find(r => {
configuration = services.find(r => {
if (request.body.ref.startsWith('refs')) {
const branch = request.body.ref.split('/')[2]
if (
@@ -88,12 +93,27 @@ module.exports = async function (fastify) {
reply.code(200).send({ message: 'Already in the queue.' })
return
}
queueAndBuild(configuration, imageChanged)
reply.code(201).send({ message: 'Deployment queued.', nickname: configuration.general.nickname, name: configuration.build.container.name })
} catch (error) {
throw { error, type: 'server' }
const { id, organization, name, branch } = configuration.repository
const { domain } = configuration.publish
const { deployId } = configuration.general
await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'failed' })
cleanupTmp(configuration.general.workdir)
if (error.name === 'Error') {
// Error during runtime
await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save()
} else {
// Error in my code
const payload = { message: error.message, stack: error.stack, type: 'spaghetticode' }
if (error.message && error.stack) await new ServerLog(payload).save()
if (reply.sent) await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save()
}
throw new Error(error)
}
})
}