From 18064ef6a24dc7bd72175297fda3d79b4e896690 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 16 Jan 2023 09:44:08 +0100 Subject: [PATCH] fixes related to docker-compose --- apps/api/src/jobs/deployApplication.ts | 3 +- apps/api/src/lib/buildPacks/compose.ts | 9 ++++-- .../src/routes/applications/[id]/+page.svelte | 29 ++++++++++--------- .../applications/[id]/logs/+page.svelte | 2 +- .../applications/[id]/usage/+page.svelte | 2 +- apps/server/src/jobs/applicationBuildQueue.ts | 3 +- apps/server/src/lib/buildPacks/compose.ts | 11 ++++--- .../[id]/configuration/_BuildPack.svelte | 11 ++++--- .../src/routes/applications/[id]/index.svelte | 4 +++ .../applications/[id]/logs/index.svelte | 2 +- .../src/routes/applications/[id]/usage.svelte | 2 +- 11 files changed, 48 insertions(+), 30 deletions(-) diff --git a/apps/api/src/jobs/deployApplication.ts b/apps/api/src/jobs/deployApplication.ts index cc3740af4..f5809c684 100644 --- a/apps/api/src/jobs/deployApplication.ts +++ b/apps/api/src/jobs/deployApplication.ts @@ -601,6 +601,7 @@ import * as buildpacks from '../lib/buildPacks'; } if (buildPack === 'compose') { + const fileYaml = `${workdir}${baseDirectory}${dockerComposeFileLocation}`; try { const { stdout: containers } = await executeCommand({ dockerId: destinationDockerId, @@ -630,7 +631,7 @@ import * as buildpacks from '../lib/buildPacks'; buildId, applicationId, dockerId: destinationDocker.id, - command: `docker compose --project-directory ${workdir} up -d` + command: `docker compose --project-directory ${workdir} -f ${fileYaml} up -d` }); await saveBuildLog({ line: 'Deployed 🎉', buildId, applicationId }); await prisma.build.update({ diff --git a/apps/api/src/lib/buildPacks/compose.ts b/apps/api/src/lib/buildPacks/compose.ts index c8cbc9f16..4e11168f6 100644 --- a/apps/api/src/lib/buildPacks/compose.ts +++ b/apps/api/src/lib/buildPacks/compose.ts @@ -43,7 +43,10 @@ export default async function (data) { let networks = {}; for (let [key, value] of Object.entries(dockerComposeYaml.services)) { value['container_name'] = `${applicationId}-${key}`; - let environment = typeof value['environment'] === 'undefined' ? [] : value['environment'] + let environment = typeof value['environment'] === 'undefined' ? [] : value['environment']; + if (Object.keys(environment).length > 0) { + environment = Object.entries(environment).map(([key, value]) => `${key}=${value}`); + } value['environment'] = [...environment, ...envs]; value['labels'] = labels; // TODO: If we support separated volume for each service, we need to add it here @@ -95,7 +98,7 @@ export default async function (data) { buildId, applicationId, dockerId, - command: `docker compose --project-directory ${workdir} pull` + command: `docker compose --project-directory ${workdir} -f ${fileYaml} pull` }); await saveBuildLog({ line: 'Pulling images from Compose file...', buildId, applicationId }); await executeCommand({ @@ -103,7 +106,7 @@ export default async function (data) { buildId, applicationId, dockerId, - command: `docker compose --project-directory ${workdir} build --progress plain` + command: `docker compose --project-directory ${workdir} -f ${fileYaml} build --progress plain` }); await saveBuildLog({ line: 'Building images from Compose file...', buildId, applicationId }); } diff --git a/apps/client/src/routes/applications/[id]/+page.svelte b/apps/client/src/routes/applications/[id]/+page.svelte index be04741aa..2747090b8 100644 --- a/apps/client/src/routes/applications/[id]/+page.svelte +++ b/apps/client/src/routes/applications/[id]/+page.svelte @@ -351,13 +351,17 @@ } async function reloadCompose() { if (loading.reloadCompose) return; + if (!$appSession.tokens.github) { + const { token } = await get(`/applications/${id}/configuration/githubToken`); + $appSession.tokens.github = token; + } loading.reloadCompose = true; try { if (application.gitSource.type === 'github') { const composeLocation = application.dockerComposeFileLocation.startsWith('/') - ? application.dockerComposeFileLocation - : `/${application.dockerComposeFileLocation}`; - + ? application.dockerComposeFileLocation + : `/${application.dockerComposeFileLocation}`; + const headers = isPublicRepository ? {} : { @@ -384,17 +388,17 @@ if (!$appSession.tokens.gitlab) { await getGitlabToken(); } - + const composeLocation = application.dockerComposeFileLocation.startsWith('/') - ? application.dockerComposeFileLocation.substring(1) // Remove the '/' from the start - : application.dockerComposeFileLocation; - + ? application.dockerComposeFileLocation.substring(1) // Remove the '/' from the start + : application.dockerComposeFileLocation; + // If the file is in a subdirectory, lastIndex will be > 0 // Otherwise it will be -1 and path will be an empty string - const lastIndex = composeLocation.lastIndexOf('/') + 1 - const path = composeLocation.substring(0, lastIndex) - const fileName = composeLocation.substring(lastIndex) - + const lastIndex = composeLocation.lastIndexOf('/') + 1; + const path = composeLocation.substring(0, lastIndex); + const fileName = composeLocation.substring(lastIndex); + const headers = isPublicRepository ? {} : { @@ -407,8 +411,7 @@ ...headers }); const dockerComposeFileYml = files.find( - (file: { name: string; type: string }) => - file.name === fileName && file.type === 'blob' + (file: { name: string; type: string }) => file.name === fileName && file.type === 'blob' ); const id = dockerComposeFileYml.id; diff --git a/apps/client/src/routes/applications/[id]/logs/+page.svelte b/apps/client/src/routes/applications/[id]/logs/+page.svelte index 310d65b32..2448ab296 100644 --- a/apps/client/src/routes/applications/[id]/logs/+page.svelte +++ b/apps/client/src/routes/applications/[id]/logs/+page.svelte @@ -21,7 +21,7 @@ onMount(async () => { const { data } = await trpc.applications.getApplicationById.query({ id }); application = data; - if (data.dockerComposeFile) { + if (application.dockerComposeFile && application.buildPack === 'compose') { services = normalizeDockerServices(JSON.parse(data.dockerComposeFile).services); } else { services = [ diff --git a/apps/client/src/routes/applications/[id]/usage/+page.svelte b/apps/client/src/routes/applications/[id]/usage/+page.svelte index 656c697e3..446f5abf5 100644 --- a/apps/client/src/routes/applications/[id]/usage/+page.svelte +++ b/apps/client/src/routes/applications/[id]/usage/+page.svelte @@ -55,7 +55,7 @@ clearInterval(usageInterval); }); onMount(async () => { - if (application.dockerComposeFile) { + if (application.dockerComposeFile && application.buildPack === 'compose') { services = normalizeDockerServices(JSON.parse(application.dockerComposeFile).services); } else { services = [ diff --git a/apps/server/src/jobs/applicationBuildQueue.ts b/apps/server/src/jobs/applicationBuildQueue.ts index 92ddc3b84..ff94f01db 100644 --- a/apps/server/src/jobs/applicationBuildQueue.ts +++ b/apps/server/src/jobs/applicationBuildQueue.ts @@ -640,6 +640,7 @@ import { defaultComposeConfiguration } from '../lib/docker'; } if (buildPack === 'compose') { + const fileYaml = `${workdir}${baseDirectory}${dockerComposeFileLocation}`; try { const { stdout: containers } = await executeCommand({ dockerId: destinationDockerId, @@ -669,7 +670,7 @@ import { defaultComposeConfiguration } from '../lib/docker'; buildId, applicationId, dockerId: destinationDocker.id, - command: `docker compose --project-directory ${workdir} up -d` + command: `docker compose --project-directory ${workdir} -f ${fileYaml} up -d` }); await saveBuildLog({ line: 'Deployed 🎉', buildId, applicationId }); await prisma.build.update({ diff --git a/apps/server/src/lib/buildPacks/compose.ts b/apps/server/src/lib/buildPacks/compose.ts index 695e205c9..9aa2d7b79 100644 --- a/apps/server/src/lib/buildPacks/compose.ts +++ b/apps/server/src/lib/buildPacks/compose.ts @@ -1,7 +1,7 @@ import { promises as fs } from 'fs'; -import { generateSecrets } from '../common'; import { saveBuildLog } from './common'; import yaml from 'js-yaml'; +import { generateSecrets } from '../common'; import { defaultComposeConfiguration } from '../docker'; import { executeCommand } from '../executeCommand'; @@ -45,7 +45,10 @@ export default async function (data) { let networks = {}; for (let [key, value] of Object.entries(dockerComposeYaml.services)) { value['container_name'] = `${applicationId}-${key}`; - let environment = typeof value['environment'] === 'undefined' ? [] : value['environment'] + let environment = typeof value['environment'] === 'undefined' ? [] : value['environment']; + if (Object.keys(environment).length > 0) { + environment = Object.entries(environment).map(([key, value]) => `${key}=${value}`); + } value['environment'] = [...environment, ...envs]; value['labels'] = labels; // TODO: If we support separated volume for each service, we need to add it here @@ -97,7 +100,7 @@ export default async function (data) { buildId, applicationId, dockerId, - command: `docker compose --project-directory ${workdir} pull` + command: `docker compose --project-directory ${workdir} -f ${fileYaml} pull` }); await saveBuildLog({ line: 'Pulling images from Compose file...', buildId, applicationId }); await executeCommand({ @@ -105,7 +108,7 @@ export default async function (data) { buildId, applicationId, dockerId, - command: `docker compose --project-directory ${workdir} build --progress plain` + command: `docker compose --project-directory ${workdir} -f ${fileYaml} build --progress plain` }); await saveBuildLog({ line: 'Building images from Compose file...', buildId, applicationId }); } diff --git a/apps/ui/src/routes/applications/[id]/configuration/_BuildPack.svelte b/apps/ui/src/routes/applications/[id]/configuration/_BuildPack.svelte index fb913b5a9..c6872dede 100644 --- a/apps/ui/src/routes/applications/[id]/configuration/_BuildPack.svelte +++ b/apps/ui/src/routes/applications/[id]/configuration/_BuildPack.svelte @@ -28,12 +28,15 @@ delete tempBuildPack.fancyName; delete tempBuildPack.color; delete tempBuildPack.hoverColor; - let composeConfiguration: any = {} - if (!dockerComposeConfiguration && dockerComposeFile) { - for (const [name, _] of Object.entries(JSON.parse(dockerComposeFile).services)) { + let composeConfiguration: any = {}; + if (!dockerComposeConfiguration && dockerComposeFile && buildPack.name === 'compose') { + const parsed = JSON.parse(dockerComposeFile); + if (!parsed?.services) { + throw new Error('No services found in docker-compose file.
Choose a different buildpack.'); + } + for (const [name, _] of Object.entries(parsed.services)) { composeConfiguration[name] = {}; } - } await post(`/applications/${id}`, { ...tempBuildPack, diff --git a/apps/ui/src/routes/applications/[id]/index.svelte b/apps/ui/src/routes/applications/[id]/index.svelte index e630106f4..5dd50825a 100644 --- a/apps/ui/src/routes/applications/[id]/index.svelte +++ b/apps/ui/src/routes/applications/[id]/index.svelte @@ -366,6 +366,10 @@ async function reloadCompose() { if (loading.reloadCompose) return; loading.reloadCompose = true; + if (!$appSession.tokens.github) { + const { token } = await get(`/applications/${id}/configuration/githubToken`); + $appSession.tokens.github = token; + } try { if (application.gitSource.type === 'github') { const composeLocation = application.dockerComposeFileLocation.startsWith('/') diff --git a/apps/ui/src/routes/applications/[id]/logs/index.svelte b/apps/ui/src/routes/applications/[id]/logs/index.svelte index 84fabd7b9..48922e660 100644 --- a/apps/ui/src/routes/applications/[id]/logs/index.svelte +++ b/apps/ui/src/routes/applications/[id]/logs/index.svelte @@ -21,7 +21,7 @@ onMount(async () => { const response = await get(`/applications/${id}`); application = response.application; - if (response.application.dockerComposeFile) { + if (response.application.dockerComposeFile && application.buildPack === 'compose') { services = normalizeDockerServices( JSON.parse(response.application.dockerComposeFile).services ); diff --git a/apps/ui/src/routes/applications/[id]/usage.svelte b/apps/ui/src/routes/applications/[id]/usage.svelte index b0f10a63d..a2e09ff14 100644 --- a/apps/ui/src/routes/applications/[id]/usage.svelte +++ b/apps/ui/src/routes/applications/[id]/usage.svelte @@ -55,7 +55,7 @@ onMount(async () => { const response = await get(`/applications/${id}`); application = response.application; - if (response.application.dockerComposeFile) { + if (response.application.dockerComposeFile && application.buildPack === 'compose') { services = normalizeDockerServices( JSON.parse(response.application.dockerComposeFile).services );