2021-03-24 21:11:14 +00:00
const yaml = require ( 'js-yaml' )
const { execShellAsync } = require ( '../../common' )
const { docker } = require ( '../../docker' )
const { saveAppLog } = require ( '../../logging' )
const { deleteSameDeployments } = require ( '../cleanup' )
2021-03-30 20:15:37 +00:00
const fs = require ( 'fs' ) . promises
2021-03-24 21:11:14 +00:00
module . exports = async function ( configuration , configChanged , imageChanged ) {
try {
const generateEnvs = { }
for ( const secret of configuration . publish . secrets ) {
generateEnvs [ secret . name ] = secret . value
}
const containerName = configuration . build . container . name
const stack = {
version : '3.8' ,
services : {
[ containerName ] : {
image : ` ${ configuration . build . container . name } : ${ configuration . build . container . tag } ` ,
networks : [ ` ${ docker . network } ` ] ,
environment : generateEnvs ,
deploy : {
2021-03-30 20:15:37 +00:00
replicas : 1 ,
restart _policy : {
condition : 'on-failure' ,
delay : '5s' ,
max _attempts : 1 ,
window : '120s'
} ,
update _config : {
parallelism : 1 ,
delay : '10s' ,
order : 'start-first'
} ,
rollback _config : {
parallelism : 1 ,
delay : '10s' ,
order : 'start-first'
} ,
2021-03-24 21:11:14 +00:00
labels : [
'managedBy=coolify' ,
'type=application' ,
'configuration=' + JSON . stringify ( configuration ) ,
'traefik.enable=true' ,
'traefik.http.services.' +
configuration . build . container . name +
` .loadbalancer.server.port= ${ configuration . publish . port } ` ,
'traefik.http.routers.' +
configuration . build . container . name +
'.entrypoints=websecure' ,
'traefik.http.routers.' +
configuration . build . container . name +
'.rule=Host(`' +
configuration . publish . domain +
'`) && PathPrefix(`' +
configuration . publish . path +
'`)' ,
'traefik.http.routers.' +
configuration . build . container . name +
'.tls.certresolver=letsencrypt' ,
'traefik.http.routers.' +
configuration . build . container . name +
'.middlewares=global-compress'
]
}
}
} ,
networks : {
[ ` ${ docker . network } ` ] : {
external : true
}
}
}
await saveAppLog ( '### Publishing.' , configuration )
await fs . writeFile ( ` ${ configuration . general . workdir } /stack.yml ` , yaml . dump ( stack ) )
if ( configChanged ) {
// console.log('configuration changed')
await execShellAsync (
` cat ${ configuration . general . workdir } /stack.yml | docker stack deploy --prune -c - ${ containerName } `
)
} else if ( imageChanged ) {
// console.log('image changed')
await execShellAsync ( ` docker service update --image ${ configuration . build . container . name } : ${ configuration . build . container . tag } ${ configuration . build . container . name } _ ${ configuration . build . container . name } ` )
} else {
// console.log('new deployment or force deployment')
await deleteSameDeployments ( configuration )
await execShellAsync (
` cat ${ configuration . general . workdir } /stack.yml | docker stack deploy --prune -c - ${ containerName } `
)
}
await saveAppLog ( '### Published done!' , configuration )
} catch ( error ) {
await saveAppLog ( ` Error occured during deployment: ${ error . message } ` , configuration )
throw { error , type : 'server' }
}
}