fix: docker buildpack env
This commit is contained in:
		
							parent
							
								
									295bea37bc
								
							
						
					
					
						commit
						88f3f628ef
					
				| @ -589,7 +589,8 @@ import * as buildpacks from '../lib/buildPacks'; | |||||||
| 												denoOptions, | 												denoOptions, | ||||||
| 												baseImage, | 												baseImage, | ||||||
| 												baseBuildImage, | 												baseBuildImage, | ||||||
| 												deploymentType | 												deploymentType, | ||||||
|  | 												forceRebuild | ||||||
| 											}); | 											}); | ||||||
| 										else { | 										else { | ||||||
| 											await saveBuildLog({ | 											await saveBuildLog({ | ||||||
| @ -716,7 +717,6 @@ import * as buildpacks from '../lib/buildPacks'; | |||||||
| 												} | 												} | ||||||
| 											}); | 											}); | ||||||
| 										} | 										} | ||||||
| 										console.log('hello'); |  | ||||||
| 										await fs.writeFile(`${workdir}/.env`, envs.join('\n')); | 										await fs.writeFile(`${workdir}/.env`, envs.join('\n')); | ||||||
| 										if (dockerRegistry) { | 										if (dockerRegistry) { | ||||||
| 											const { url, username, password } = dockerRegistry; | 											const { url, username, password } = dockerRegistry; | ||||||
|  | |||||||
| @ -1,6 +1,17 @@ | |||||||
| import { base64Encode, decrypt, encrypt, executeCommand, generateTimestamp, getDomain, isARM, isDev, prisma, version } from "../common"; | import { | ||||||
|  | 	base64Encode, | ||||||
|  | 	decrypt, | ||||||
|  | 	encrypt, | ||||||
|  | 	executeCommand, | ||||||
|  | 	generateTimestamp, | ||||||
|  | 	getDomain, | ||||||
|  | 	isARM, | ||||||
|  | 	isDev, | ||||||
|  | 	prisma, | ||||||
|  | 	version | ||||||
|  | } from '../common'; | ||||||
| import { promises as fs } from 'fs'; | import { promises as fs } from 'fs'; | ||||||
| import { day } from "../dayjs"; | import { day } from '../dayjs'; | ||||||
| 
 | 
 | ||||||
| const staticApps = ['static', 'react', 'vuejs', 'svelte', 'gatsby', 'astro', 'eleventy']; | const staticApps = ['static', 'react', 'vuejs', 'svelte', 'gatsby', 'astro', 'eleventy']; | ||||||
| const nodeBased = [ | const nodeBased = [ | ||||||
| @ -17,7 +28,10 @@ const nodeBased = [ | |||||||
| 	'nextjs' | 	'nextjs' | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
| export function setDefaultBaseImage(buildPack: string | null, deploymentType: string | null = null) { | export function setDefaultBaseImage( | ||||||
|  | 	buildPack: string | null, | ||||||
|  | 	deploymentType: string | null = null | ||||||
|  | ) { | ||||||
| 	const nodeVersions = [ | 	const nodeVersions = [ | ||||||
| 		{ | 		{ | ||||||
| 			value: 'node:lts', | 			value: 'node:lts', | ||||||
| @ -316,8 +330,8 @@ export function setDefaultBaseImage(buildPack: string | null, deploymentType: st | |||||||
| 		{ | 		{ | ||||||
| 			value: 'heroku/builder-classic:22', | 			value: 'heroku/builder-classic:22', | ||||||
| 			label: 'heroku/builder-classic:22' | 			label: 'heroku/builder-classic:22' | ||||||
| 		}, | 		} | ||||||
| 	] | 	]; | ||||||
| 	let payload: any = { | 	let payload: any = { | ||||||
| 		baseImage: null, | 		baseImage: null, | ||||||
| 		baseBuildImage: null, | 		baseBuildImage: null, | ||||||
| @ -327,7 +341,9 @@ export function setDefaultBaseImage(buildPack: string | null, deploymentType: st | |||||||
| 	if (nodeBased.includes(buildPack)) { | 	if (nodeBased.includes(buildPack)) { | ||||||
| 		if (deploymentType === 'static') { | 		if (deploymentType === 'static') { | ||||||
| 			payload.baseImage = isARM(process.arch) ? 'nginx:alpine' : 'webdevops/nginx:alpine'; | 			payload.baseImage = isARM(process.arch) ? 'nginx:alpine' : 'webdevops/nginx:alpine'; | ||||||
| 			payload.baseImages = isARM(process.arch) ? staticVersions.filter((version) => !version.value.includes('webdevops')) : staticVersions; | 			payload.baseImages = isARM(process.arch) | ||||||
|  | 				? staticVersions.filter((version) => !version.value.includes('webdevops')) | ||||||
|  | 				: staticVersions; | ||||||
| 			payload.baseBuildImage = 'node:lts'; | 			payload.baseBuildImage = 'node:lts'; | ||||||
| 			payload.baseBuildImages = nodeVersions; | 			payload.baseBuildImages = nodeVersions; | ||||||
| 		} else { | 		} else { | ||||||
| @ -339,7 +355,9 @@ export function setDefaultBaseImage(buildPack: string | null, deploymentType: st | |||||||
| 	} | 	} | ||||||
| 	if (staticApps.includes(buildPack)) { | 	if (staticApps.includes(buildPack)) { | ||||||
| 		payload.baseImage = isARM(process.arch) ? 'nginx:alpine' : 'webdevops/nginx:alpine'; | 		payload.baseImage = isARM(process.arch) ? 'nginx:alpine' : 'webdevops/nginx:alpine'; | ||||||
| 		payload.baseImages = isARM(process.arch) ? staticVersions.filter((version) => !version.value.includes('webdevops')) : staticVersions; | 		payload.baseImages = isARM(process.arch) | ||||||
|  | 			? staticVersions.filter((version) => !version.value.includes('webdevops')) | ||||||
|  | 			: staticVersions; | ||||||
| 		payload.baseBuildImage = 'node:lts'; | 		payload.baseBuildImage = 'node:lts'; | ||||||
| 		payload.baseBuildImages = nodeVersions; | 		payload.baseBuildImages = nodeVersions; | ||||||
| 	} | 	} | ||||||
| @ -357,12 +375,20 @@ export function setDefaultBaseImage(buildPack: string | null, deploymentType: st | |||||||
| 		payload.baseImage = 'denoland/deno:latest'; | 		payload.baseImage = 'denoland/deno:latest'; | ||||||
| 	} | 	} | ||||||
| 	if (buildPack === 'php') { | 	if (buildPack === 'php') { | ||||||
| 		payload.baseImage = isARM(process.arch) ? 'php:8.1-fpm-alpine' : 'webdevops/php-apache:8.2-alpine'; | 		payload.baseImage = isARM(process.arch) | ||||||
| 		payload.baseImages = isARM(process.arch) ? phpVersions.filter((version) => !version.value.includes('webdevops')) : phpVersions | 			? 'php:8.1-fpm-alpine' | ||||||
|  | 			: 'webdevops/php-apache:8.2-alpine'; | ||||||
|  | 		payload.baseImages = isARM(process.arch) | ||||||
|  | 			? phpVersions.filter((version) => !version.value.includes('webdevops')) | ||||||
|  | 			: phpVersions; | ||||||
| 	} | 	} | ||||||
| 	if (buildPack === 'laravel') { | 	if (buildPack === 'laravel') { | ||||||
| 		payload.baseImage = isARM(process.arch) ? 'php:8.1-fpm-alpine' : 'webdevops/php-apache:8.2-alpine'; | 		payload.baseImage = isARM(process.arch) | ||||||
| 		payload.baseImages = isARM(process.arch) ? phpVersions.filter((version) => !version.value.includes('webdevops')) : phpVersions | 			? 'php:8.1-fpm-alpine' | ||||||
|  | 			: 'webdevops/php-apache:8.2-alpine'; | ||||||
|  | 		payload.baseImages = isARM(process.arch) | ||||||
|  | 			? phpVersions.filter((version) => !version.value.includes('webdevops')) | ||||||
|  | 			: phpVersions; | ||||||
| 		payload.baseBuildImage = 'node:18'; | 		payload.baseBuildImage = 'node:18'; | ||||||
| 		payload.baseBuildImages = nodeVersions; | 		payload.baseBuildImages = nodeVersions; | ||||||
| 	} | 	} | ||||||
| @ -405,7 +431,8 @@ export const setDefaultConfiguration = async (data: any) => { | |||||||
| 	if (!publishDirectory) publishDirectory = template?.publishDirectory || null; | 	if (!publishDirectory) publishDirectory = template?.publishDirectory || null; | ||||||
| 	if (baseDirectory) { | 	if (baseDirectory) { | ||||||
| 		if (!baseDirectory.startsWith('/')) baseDirectory = `/${baseDirectory}`; | 		if (!baseDirectory.startsWith('/')) baseDirectory = `/${baseDirectory}`; | ||||||
| 		if (baseDirectory.endsWith('/') && baseDirectory !== '/') baseDirectory = baseDirectory.slice(0, -1); | 		if (baseDirectory.endsWith('/') && baseDirectory !== '/') | ||||||
|  | 			baseDirectory = baseDirectory.slice(0, -1); | ||||||
| 	} | 	} | ||||||
| 	if (dockerFileLocation) { | 	if (dockerFileLocation) { | ||||||
| 		if (!dockerFileLocation.startsWith('/')) dockerFileLocation = `/${dockerFileLocation}`; | 		if (!dockerFileLocation.startsWith('/')) dockerFileLocation = `/${dockerFileLocation}`; | ||||||
| @ -414,8 +441,10 @@ export const setDefaultConfiguration = async (data: any) => { | |||||||
| 		dockerFileLocation = '/Dockerfile'; | 		dockerFileLocation = '/Dockerfile'; | ||||||
| 	} | 	} | ||||||
| 	if (dockerComposeFileLocation) { | 	if (dockerComposeFileLocation) { | ||||||
| 		if (!dockerComposeFileLocation.startsWith('/')) dockerComposeFileLocation = `/${dockerComposeFileLocation}`; | 		if (!dockerComposeFileLocation.startsWith('/')) | ||||||
| 		if (dockerComposeFileLocation.endsWith('/')) dockerComposeFileLocation = dockerComposeFileLocation.slice(0, -1); | 			dockerComposeFileLocation = `/${dockerComposeFileLocation}`; | ||||||
|  | 		if (dockerComposeFileLocation.endsWith('/')) | ||||||
|  | 			dockerComposeFileLocation = dockerComposeFileLocation.slice(0, -1); | ||||||
| 	} else { | 	} else { | ||||||
| 		dockerComposeFileLocation = '/Dockerfile'; | 		dockerComposeFileLocation = '/Dockerfile'; | ||||||
| 	} | 	} | ||||||
| @ -479,7 +508,6 @@ export const scanningTemplates = { | |||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| export const saveBuildLog = async ({ | export const saveBuildLog = async ({ | ||||||
| 	line, | 	line, | ||||||
| 	buildId, | 	buildId, | ||||||
| @ -491,7 +519,7 @@ export const saveBuildLog = async ({ | |||||||
| }): Promise<any> => { | }): Promise<any> => { | ||||||
| 	if (buildId === 'undefined' || buildId === 'null' || !buildId) return; | 	if (buildId === 'undefined' || buildId === 'null' || !buildId) return; | ||||||
| 	if (applicationId === 'undefined' || applicationId === 'null' || !applicationId) return; | 	if (applicationId === 'undefined' || applicationId === 'null' || !applicationId) return; | ||||||
| 	const { default: got } = await import('got') | 	const { default: got } = await import('got'); | ||||||
| 	if (typeof line === 'object' && line) { | 	if (typeof line === 'object' && line) { | ||||||
| 		if (line.shortMessage) { | 		if (line.shortMessage) { | ||||||
| 			line = line.shortMessage + '\n' + line.stderr; | 			line = line.shortMessage + '\n' + line.stderr; | ||||||
| @ -504,7 +532,11 @@ export const saveBuildLog = async ({ | |||||||
| 		line = line.replace(regex, '<SENSITIVE_DATA_DELETED>@'); | 		line = line.replace(regex, '<SENSITIVE_DATA_DELETED>@'); | ||||||
| 	} | 	} | ||||||
| 	const addTimestamp = `[${generateTimestamp()}] ${line}`; | 	const addTimestamp = `[${generateTimestamp()}] ${line}`; | ||||||
| 	const fluentBitUrl = isDev ? process.env.COOLIFY_CONTAINER_DEV === 'true' ? 'http://coolify-fluentbit:24224' : 'http://localhost:24224' : 'http://coolify-fluentbit:24224'; | 	const fluentBitUrl = isDev | ||||||
|  | 		? process.env.COOLIFY_CONTAINER_DEV === 'true' | ||||||
|  | 			? 'http://coolify-fluentbit:24224' | ||||||
|  | 			: 'http://localhost:24224' | ||||||
|  | 		: 'http://coolify-fluentbit:24224'; | ||||||
| 
 | 
 | ||||||
| 	if (isDev && !process.env.COOLIFY_CONTAINER_DEV) { | 	if (isDev && !process.env.COOLIFY_CONTAINER_DEV) { | ||||||
| 		console.debug(`[${applicationId}] ${addTimestamp}`); | 		console.debug(`[${applicationId}] ${addTimestamp}`); | ||||||
| @ -514,15 +546,17 @@ export const saveBuildLog = async ({ | |||||||
| 			json: { | 			json: { | ||||||
| 				line: encrypt(line) | 				line: encrypt(line) | ||||||
| 			} | 			} | ||||||
| 		}) | 		}); | ||||||
| 	} catch (error) { | 	} catch (error) { | ||||||
| 		return await prisma.buildLog.create({ | 		return await prisma.buildLog.create({ | ||||||
| 			data: { | 			data: { | ||||||
| 				line: addTimestamp, buildId, time: Number(day().valueOf()), applicationId | 				line: addTimestamp, | ||||||
|  | 				buildId, | ||||||
|  | 				time: Number(day().valueOf()), | ||||||
|  | 				applicationId | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export async function copyBaseConfigurationFiles( | export async function copyBaseConfigurationFiles( | ||||||
| @ -610,7 +644,7 @@ export function checkPnpm(installCommand = null, buildCommand = null, startComma | |||||||
| 
 | 
 | ||||||
| export async function saveDockerRegistryCredentials({ url, username, password, workdir }) { | export async function saveDockerRegistryCredentials({ url, username, password, workdir }) { | ||||||
| 	if (!username || !password) { | 	if (!username || !password) { | ||||||
| 		return null | 		return null; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	let decryptedPassword = decrypt(password); | 	let decryptedPassword = decrypt(password); | ||||||
| @ -622,14 +656,14 @@ export async function saveDockerRegistryCredentials({ url, username, password, w | |||||||
| 		console.log(error); | 		console.log(error); | ||||||
| 	} | 	} | ||||||
| 	const payload = JSON.stringify({ | 	const payload = JSON.stringify({ | ||||||
| 		"auths": { | 		auths: { | ||||||
| 			[url]: { | 			[url]: { | ||||||
| 				"auth": Buffer.from(`${username}:${decryptedPassword}`).toString('base64') | 				auth: Buffer.from(`${username}:${decryptedPassword}`).toString('base64') | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	}) | 	}); | ||||||
| 	await fs.writeFile(`${location}/config.json`, payload) | 	await fs.writeFile(`${location}/config.json`, payload); | ||||||
| 	return location | 	return location; | ||||||
| } | } | ||||||
| export async function buildImage({ | export async function buildImage({ | ||||||
| 	applicationId, | 	applicationId, | ||||||
| @ -640,29 +674,41 @@ export async function buildImage({ | |||||||
| 	isCache = false, | 	isCache = false, | ||||||
| 	debug = false, | 	debug = false, | ||||||
| 	dockerFileLocation = '/Dockerfile', | 	dockerFileLocation = '/Dockerfile', | ||||||
| 	commit | 	commit, | ||||||
|  | 	forceRebuild = false | ||||||
| }) { | }) { | ||||||
| 	if (isCache) { | 	if (isCache) { | ||||||
| 		await saveBuildLog({ line: `Building cache image...`, buildId, applicationId }); | 		await saveBuildLog({ line: `Building cache image...`, buildId, applicationId }); | ||||||
| 	} else { | 	} else { | ||||||
| 		await saveBuildLog({ line: `Building production image...`, buildId, applicationId }); | 		await saveBuildLog({ line: `Building production image...`, buildId, applicationId }); | ||||||
| 	} | 	} | ||||||
| 	const dockerFile = isCache ? `${dockerFileLocation}-cache` : `${dockerFileLocation}` | 	const dockerFile = isCache ? `${dockerFileLocation}-cache` : `${dockerFileLocation}`; | ||||||
| 	const cache = `${applicationId}:${tag}${isCache ? '-cache' : ''}` | 	const cache = `${applicationId}:${tag}${isCache ? '-cache' : ''}`; | ||||||
|  | 	let location = null; | ||||||
| 
 | 
 | ||||||
| 	let location = null | 	const { dockerRegistry } = await prisma.application.findUnique({ | ||||||
| 
 | 		where: { id: applicationId }, | ||||||
| 	const { dockerRegistry } = await prisma.application.findUnique({ where: { id: applicationId }, select: { dockerRegistry: true } }) | 		select: { dockerRegistry: true } | ||||||
|  | 	}); | ||||||
| 	if (dockerRegistry) { | 	if (dockerRegistry) { | ||||||
| 		const { url, username, password } = dockerRegistry | 		const { url, username, password } = dockerRegistry; | ||||||
| 		location = await saveDockerRegistryCredentials({ url, username, password, workdir }) | 		location = await saveDockerRegistryCredentials({ url, username, password, workdir }); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	await executeCommand({ stream: true, debug, buildId, applicationId, dockerId, command: `docker ${location ? `--config ${location}` : ''} build --progress plain -f ${workdir}/${dockerFile} -t ${cache} --build-arg SOURCE_COMMIT=${commit} ${workdir}` }) | 	await executeCommand({ | ||||||
|  | 		stream: true, | ||||||
|  | 		debug, | ||||||
|  | 		buildId, | ||||||
|  | 		applicationId, | ||||||
|  | 		dockerId, | ||||||
|  | 		command: `docker ${location ? `--config ${location}` : ''} build ${ | ||||||
|  | 			forceRebuild ? '--no-cache' : '' | ||||||
|  | 		} --progress plain -f ${workdir}/${dockerFile} -t ${cache} --build-arg SOURCE_COMMIT=${commit} ${workdir}` | ||||||
|  | 	}); | ||||||
| 
 | 
 | ||||||
| 	const { status } = await prisma.build.findUnique({ where: { id: buildId } }) | 	const { status } = await prisma.build.findUnique({ where: { id: buildId } }); | ||||||
| 	if (status === 'canceled') { | 	if (status === 'canceled') { | ||||||
| 		throw new Error('Canceled.') | 		throw new Error('Canceled.'); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| export function makeLabelForSimpleDockerfile({ applicationId, port, type }) { | export function makeLabelForSimpleDockerfile({ applicationId, port, type }) { | ||||||
| @ -744,7 +790,7 @@ export async function buildCacheImageWithNode(data, imageForBuild) { | |||||||
| 		secrets.forEach((secret) => { | 		secrets.forEach((secret) => { | ||||||
| 			if (secret.isBuildSecret) { | 			if (secret.isBuildSecret) { | ||||||
| 				if (pullmergeRequestId) { | 				if (pullmergeRequestId) { | ||||||
| 					const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret) | 					const isSecretFound = secrets.filter((s) => s.name === secret.name && s.isPRMRSecret); | ||||||
| 					if (isSecretFound.length > 0) { | 					if (isSecretFound.length > 0) { | ||||||
| 						Dockerfile.push(`ARG ${secret.name}='${isSecretFound[0].value}'`); | 						Dockerfile.push(`ARG ${secret.name}='${isSecretFound[0].value}'`); | ||||||
| 					} else { | 					} else { | ||||||
| @ -782,7 +828,7 @@ export async function buildCacheImageForLaravel(data, imageForBuild) { | |||||||
| 		secrets.forEach((secret) => { | 		secrets.forEach((secret) => { | ||||||
| 			if (secret.isBuildSecret) { | 			if (secret.isBuildSecret) { | ||||||
| 				if (pullmergeRequestId) { | 				if (pullmergeRequestId) { | ||||||
| 					const isSecretFound = secrets.filter(s => s.name === secret.name && s.isPRMRSecret) | 					const isSecretFound = secrets.filter((s) => s.name === secret.name && s.isPRMRSecret); | ||||||
| 					if (isSecretFound.length > 0) { | 					if (isSecretFound.length > 0) { | ||||||
| 						Dockerfile.push(`ARG ${secret.name}='${isSecretFound[0].value}'`); | 						Dockerfile.push(`ARG ${secret.name}='${isSecretFound[0].value}'`); | ||||||
| 					} else { | 					} else { | ||||||
| @ -804,11 +850,7 @@ export async function buildCacheImageForLaravel(data, imageForBuild) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function buildCacheImageWithCargo(data, imageForBuild) { | export async function buildCacheImageWithCargo(data, imageForBuild) { | ||||||
| 	const { | 	const { applicationId, workdir, buildId } = data; | ||||||
| 		applicationId, |  | ||||||
| 		workdir, |  | ||||||
| 		buildId, |  | ||||||
| 	} = data; |  | ||||||
| 
 | 
 | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
| 	Dockerfile.push(`FROM ${imageForBuild} as planner-${applicationId}`); | 	Dockerfile.push(`FROM ${imageForBuild} as planner-${applicationId}`); | ||||||
|  | |||||||
| @ -2,24 +2,11 @@ import { promises as fs } from 'fs'; | |||||||
| import { buildImage } from './common'; | import { buildImage } from './common'; | ||||||
| 
 | 
 | ||||||
| export default async function (data) { | export default async function (data) { | ||||||
| 	let { | 	let { workdir, buildId, baseDirectory, secrets, pullmergeRequestId, dockerFileLocation } = data; | ||||||
| 		applicationId, |  | ||||||
| 		debug, |  | ||||||
| 		tag, |  | ||||||
| 		workdir, |  | ||||||
| 		buildId, |  | ||||||
| 		baseDirectory, |  | ||||||
| 		secrets, |  | ||||||
| 		pullmergeRequestId, |  | ||||||
| 		dockerFileLocation |  | ||||||
| 	} = data |  | ||||||
| 	const file = `${workdir}${baseDirectory}${dockerFileLocation}`; | 	const file = `${workdir}${baseDirectory}${dockerFileLocation}`; | ||||||
| 	data.workdir = `${workdir}${baseDirectory}`; | 	data.workdir = `${workdir}${baseDirectory}`; | ||||||
| 	const DockerfileRaw = await fs.readFile(`${file}`, 'utf8') | 	const DockerfileRaw = await fs.readFile(`${file}`, 'utf8'); | ||||||
| 	const Dockerfile: Array<string> = DockerfileRaw | 	const Dockerfile: Array<string> = DockerfileRaw.toString().trim().split('\n'); | ||||||
| 		.toString() |  | ||||||
| 		.trim() |  | ||||||
| 		.split('\n'); |  | ||||||
| 	Dockerfile.forEach((line, index) => { | 	Dockerfile.forEach((line, index) => { | ||||||
| 		if (line.startsWith('FROM')) { | 		if (line.startsWith('FROM')) { | ||||||
| 			Dockerfile.splice(index + 1, 0, `LABEL coolify.buildId=${buildId}`); | 			Dockerfile.splice(index + 1, 0, `LABEL coolify.buildId=${buildId}`); | ||||||
| @ -41,7 +28,6 @@ export default async function (data) { | |||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 	await fs.writeFile(`${data.workdir}${dockerFileLocation}`, Dockerfile.join('\n')); | ||||||
| 	await fs.writeFile(`${workdir}${dockerFileLocation}`, Dockerfile.join('\n')); |  | ||||||
| 	await buildImage(data); | 	await buildImage(data); | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user