From 067f502d3c7ea2e657a2f0b55d77db97515a331b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 28 Nov 2022 10:21:11 +0100 Subject: [PATCH] feat: custom docker compose file location in repo --- apps/api/src/jobs/deployApplication.ts | 3 ++ apps/api/src/lib/buildPacks/common.ts | 8 ++++ apps/api/src/lib/buildPacks/compose.ts | 22 +++------- .../routes/api/v1/applications/handlers.ts | 3 +- .../src/routes/applications/[id]/index.svelte | 44 ++++++++++++++++--- 5 files changed, 56 insertions(+), 24 deletions(-) diff --git a/apps/api/src/jobs/deployApplication.ts b/apps/api/src/jobs/deployApplication.ts index 67e93aa5a..02609d844 100644 --- a/apps/api/src/jobs/deployApplication.ts +++ b/apps/api/src/jobs/deployApplication.ts @@ -78,6 +78,7 @@ import * as buildpacks from '../lib/buildPacks'; baseDirectory, publishDirectory, dockerFileLocation, + dockerComposeFileLocation, dockerComposeConfiguration, denoMainFile } = application @@ -158,6 +159,7 @@ import * as buildpacks from '../lib/buildPacks'; publishDirectory = configuration.publishDirectory; baseDirectory = configuration.baseDirectory || ''; dockerFileLocation = configuration.dockerFileLocation; + dockerComposeFileLocation = configuration.dockerComposeFileLocation; denoMainFile = configuration.denoMainFile; const commit = await importers[gitSource.type]({ applicationId, @@ -266,6 +268,7 @@ import * as buildpacks from '../lib/buildPacks'; pythonVariable, dockerFileLocation, dockerComposeConfiguration, + dockerComposeFileLocation, denoMainFile, denoOptions, baseImage, diff --git a/apps/api/src/lib/buildPacks/common.ts b/apps/api/src/lib/buildPacks/common.ts index 0defc1303..c8c383564 100644 --- a/apps/api/src/lib/buildPacks/common.ts +++ b/apps/api/src/lib/buildPacks/common.ts @@ -363,6 +363,7 @@ export const setDefaultConfiguration = async (data: any) => { publishDirectory, baseDirectory, dockerFileLocation, + dockerComposeFileLocation, denoMainFile } = data; //@ts-ignore @@ -392,6 +393,12 @@ export const setDefaultConfiguration = async (data: any) => { } else { dockerFileLocation = '/Dockerfile'; } + if (dockerComposeFileLocation) { + if (!dockerComposeFileLocation.startsWith('/')) dockerComposeFileLocation = `/${dockerComposeFileLocation}`; + if (dockerComposeFileLocation.endsWith('/')) dockerComposeFileLocation = dockerComposeFileLocation.slice(0, -1); + } else { + dockerComposeFileLocation = '/Dockerfile'; + } if (!denoMainFile) { denoMainFile = 'main.ts'; } @@ -405,6 +412,7 @@ export const setDefaultConfiguration = async (data: any) => { publishDirectory, baseDirectory, dockerFileLocation, + dockerComposeFileLocation, denoMainFile }; }; diff --git a/apps/api/src/lib/buildPacks/compose.ts b/apps/api/src/lib/buildPacks/compose.ts index d57dba930..2bee70c3f 100644 --- a/apps/api/src/lib/buildPacks/compose.ts +++ b/apps/api/src/lib/buildPacks/compose.ts @@ -17,23 +17,11 @@ export default async function (data) { secrets, pullmergeRequestId, port, - dockerComposeConfiguration + dockerComposeConfiguration, + dockerComposeFileLocation } = data - const fileYml = `${workdir}${baseDirectory}/docker-compose.yml`; - const fileYaml = `${workdir}${baseDirectory}/docker-compose.yaml`; - let dockerComposeRaw = null; - let isYml = false; - try { - dockerComposeRaw = await fs.readFile(`${fileYml}`, 'utf8') - isYml = true - } catch (error) { } - try { - dockerComposeRaw = await fs.readFile(`${fileYaml}`, 'utf8') - } catch (error) { } - - if (!dockerComposeRaw) { - throw ('docker-compose.yml or docker-compose.yaml are not found!'); - } + const fileYaml = `${workdir}${baseDirectory}${dockerComposeFileLocation}` + const dockerComposeRaw = await fs.readFile(fileYaml, 'utf8'); const dockerComposeYaml = yaml.load(dockerComposeRaw) if (!dockerComposeYaml.services) { throw 'No Services found in docker-compose file.' @@ -119,7 +107,7 @@ export default async function (data) { dockerComposeYaml['volumes'] = { ...composeVolumes } } dockerComposeYaml['networks'] = Object.assign({ ...networks }, { [network]: { external: true } }) - await fs.writeFile(`${workdir}/docker-compose.${isYml ? 'yml' : 'yaml'}`, yaml.dump(dockerComposeYaml)); + await fs.writeFile(fileYaml, yaml.dump(dockerComposeYaml)); await executeDockerCmd({ debug, buildId, applicationId, dockerId, command: `docker compose --project-directory ${workdir} pull` }) await saveBuildLog({ line: 'Pulling images from Compose file.', buildId, applicationId }); await executeDockerCmd({ debug, buildId, applicationId, dockerId, command: `docker compose --project-directory ${workdir} build --progress plain` }) diff --git a/apps/api/src/routes/api/v1/applications/handlers.ts b/apps/api/src/routes/api/v1/applications/handlers.ts index 2370a4445..6dd16e2be 100644 --- a/apps/api/src/routes/api/v1/applications/handlers.ts +++ b/apps/api/src/routes/api/v1/applications/handlers.ts @@ -351,6 +351,7 @@ export async function saveApplication(request: FastifyRequest, publishDirectory, baseDirectory, dockerFileLocation, + dockerComposeFileLocation, denoMainFile }); if (baseDatabaseBranch) { @@ -820,7 +821,7 @@ export async function saveRepository(request, reply) { let { repository, branch, projectId, autodeploy, webhookToken, isPublicRepository = false } = request.body repository = repository.toLowerCase(); - + projectId = Number(projectId); if (webhookToken) { await prisma.application.update({ diff --git a/apps/ui/src/routes/applications/[id]/index.svelte b/apps/ui/src/routes/applications/[id]/index.svelte index ab943eade..25eb7cfb4 100644 --- a/apps/ui/src/routes/applications/[id]/index.svelte +++ b/apps/ui/src/routes/applications/[id]/index.svelte @@ -82,8 +82,8 @@ let dockerComposeFile = JSON.parse(application.dockerComposeFile) || null; let dockerComposeServices: any[] = []; - let dockerComposeFileLocation = application.dockerComposeFileLocation; let dockerComposeConfiguration = JSON.parse(application.dockerComposeConfiguration) || {}; + let originalDockerComposeFileLocation = application.dockerComposeFileLocation; let baseDatabaseBranch: any = application?.connectedDatabase?.hostedDatabaseDBName || null; let nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, ''); @@ -243,8 +243,12 @@ if (toast) loading.save = true; try { nonWWWDomain = application.fqdn && getDomain(application.fqdn).replace(/^www\./, ''); - if (application.deploymentType) + if (application.deploymentType) { application.deploymentType = application.deploymentType.toLowerCase(); + } + if (originalDockerComposeFileLocation !== application.dockerComposeFileLocation) { + await reloadCompose(); + } if (!isBot) { await post(`/applications/${id}/check`, { fqdn: application.fqdn, @@ -365,6 +369,9 @@ async function reloadCompose() { if (loading.reloadCompose) return; loading.reloadCompose = true; + const composeLocation = application.dockerComposeFileLocation.startsWith('/') + ? application.dockerComposeFileLocation + : `/${application.dockerComposeFileLocation}`; try { if (application.gitSource.type === 'github') { const headers = isPublicRepository @@ -373,9 +380,10 @@ Authorization: `token ${$appSession.tokens.github}` }; const data = await get( - `${apiUrl}/repos/${repository}/contents/${dockerComposeFileLocation}?ref=${branch}`, + `${apiUrl}/repos/${repository}/contents/${composeLocation}?ref=${branch}`, { ...headers, + 'If-None-Match': '', Accept: 'application/vnd.github.v2.json' } ); @@ -405,7 +413,7 @@ }); const dockerComposeFileYml = files.find( (file: { name: string; type: string }) => - file.name === dockerComposeFileLocation && file.type === 'blob' + file.name === composeLocation && file.type === 'blob' ); const id = dockerComposeFileYml.id; @@ -424,12 +432,17 @@ await handleSubmit(false); } } - + originalDockerComposeFileLocation = application.dockerComposeFileLocation; addToast({ message: 'Compose file reloaded.', type: 'success' }); - } catch (error) { + } catch (error: any) { + if (error.message === 'Not Found') { + error.message = `Can't find ${application.dockerComposeFileLocation} file.`; + errorNotification(error); + throw error; + } errorNotification(error); } finally { loading.reloadCompose = false; @@ -1029,6 +1042,25 @@ {/if}
+
+ +
+ +
+
{#each dockerComposeServices as service}