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