From d03fbd9224c60e5e40882c81d3b4146d1fb229ec Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 26 Apr 2022 14:51:08 +0200 Subject: [PATCH] feat: select base image for buildpacks --- README.md | 10 +- package.json | 2 +- .../migration.sql | 3 + prisma/schema.prisma | 1 + src/lib/buildPacks/common.ts | 222 +++++++++++++++++- src/lib/buildPacks/deno.ts | 4 +- src/lib/buildPacks/gatsby.ts | 14 +- src/lib/buildPacks/nestjs.ts | 8 +- src/lib/buildPacks/nextjs.ts | 4 +- src/lib/buildPacks/node.ts | 4 +- src/lib/buildPacks/nuxtjs.ts | 4 +- src/lib/buildPacks/php.ts | 7 +- src/lib/buildPacks/python.ts | 4 +- src/lib/buildPacks/react.ts | 13 +- src/lib/buildPacks/rust.ts | 8 +- src/lib/buildPacks/static.ts | 14 +- src/lib/buildPacks/svelte.ts | 14 +- src/lib/buildPacks/vuejs.ts | 13 +- src/lib/database/applications.ts | 45 ++-- src/lib/locales/en.json | 1 + src/lib/queues/builder.ts | 10 +- src/lib/types/builderJob.ts | 2 + .../[id]/configuration/baseimage.svelte | 0 src/routes/applications/[id]/index.json.ts | 4 +- src/routes/applications/[id]/index.svelte | 51 +++- src/tailwind.css | 6 +- 26 files changed, 359 insertions(+), 109 deletions(-) create mode 100644 prisma/migrations/20220426125053_select_base_image/migration.sql delete mode 100644 src/routes/applications/[id]/configuration/baseimage.svelte diff --git a/README.md b/README.md index d214d42b7..ef747034f 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,16 @@ https://demo.coolify.io/ Installation is automated with the following command: ```bash -/bin/bash -c "$(curl -fsSL https://get.coollabs.io/coolify/install.sh)" +wget -q https://get.coollabs.io/coolify/install.sh -O install.sh; sudo bash ./install.sh ``` -If you would like no questions during installation +If you would like no questions during installation: + +```bash +wget -q https://get.coollabs.io/coolify/install.sh -O install.sh; sudo bash ./install.sh -f +``` + +For more details goto the [docs](https://docs.coollabs.io/coolify/installation). ## Features diff --git a/package.json b/package.json index 9f38331ad..bb6f7d86c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "coolify", "description": "An open-source & self-hostable Heroku / Netlify alternative.", - "version": "2.5.2", + "version": "2.5.3", "license": "AGPL-3.0", "scripts": { "dev": "docker-compose -f docker-compose-dev.yaml up -d && cross-env NODE_ENV=development & svelte-kit dev --host 0.0.0.0", diff --git a/prisma/migrations/20220426125053_select_base_image/migration.sql b/prisma/migrations/20220426125053_select_base_image/migration.sql new file mode 100644 index 000000000..37209d82f --- /dev/null +++ b/prisma/migrations/20220426125053_select_base_image/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "Application" ADD COLUMN "baseBuildImage" TEXT; +ALTER TABLE "Application" ADD COLUMN "baseImage" TEXT; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 77f2e1297..267dd1991 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -106,6 +106,7 @@ model Application { secrets Secret[] persistentStorage ApplicationPersistentStorage[] baseImage String? + baseBuildImage String? } model ApplicationSettings { diff --git a/src/lib/buildPacks/common.ts b/src/lib/buildPacks/common.ts index 05313a3d2..eb67a73bd 100644 --- a/src/lib/buildPacks/common.ts +++ b/src/lib/buildPacks/common.ts @@ -5,6 +5,9 @@ import { scanningTemplates } from '$lib/components/templates'; import { promises as fs } from 'fs'; import { staticDeployments } from '$lib/components/common'; +const staticApps = ['static', 'react', 'vuejs', 'svelte', 'gatsby', 'astro', 'eleventy']; +const nodeBased = ['react', 'vuejs', 'svelte', 'gatsby', 'php', 'astro', 'eleventy', 'node']; + export function makeLabelForStandaloneApplication({ applicationId, fqdn, @@ -137,7 +140,13 @@ export const setDefaultConfiguration = async (data) => { }; }; -export async function copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId) { +export async function copyBaseConfigurationFiles( + buildPack, + workdir, + buildId, + applicationId, + baseImage +) { try { if (buildPack === 'php') { await fs.writeFile(`${workdir}/entrypoint.sh`, `chown -R 1000 /app`); @@ -146,7 +155,7 @@ export async function copyBaseConfigurationFiles(buildPack, workdir, buildId, ap buildId, applicationId }); - } else if (staticDeployments.includes(buildPack)) { + } else if (staticDeployments.includes(buildPack) && baseImage.includes('nginx')) { await fs.writeFile( `${workdir}/nginx.conf`, `user nginx; @@ -199,11 +208,6 @@ export async function copyBaseConfigurationFiles(buildPack, workdir, buildId, ap } ` ); - await saveBuildLog({ - line: 'Copied default configuration file for Nginx.', - buildId, - applicationId - }); } } catch (error) { console.log(error); @@ -218,3 +222,207 @@ export function checkPnpm(installCommand = null, buildCommand = null, startComma startCommand?.includes('pnpm') ); } + +export function setDefaultBaseImage(buildPack) { + const nodeVersions = [ + { + value: 'node:lts', + label: 'node:lts' + }, + { + value: 'node:18', + label: 'node:18' + }, + { + value: 'node:17', + label: 'node:17' + }, + { + value: 'node:16', + label: 'node:16' + }, + { + value: 'node:14', + label: 'node:14' + }, + { + value: 'node:12', + label: 'node:12' + } + ]; + const staticVersions = [ + { + value: 'webdevops/nginx:alpine', + label: 'webdevops/nginx:alpine' + }, + { + value: 'webdevops/apache:alpine', + label: 'webdevops/apache:alpine' + } + ]; + const rustVersions = [ + { + value: 'rust:latest', + label: 'rust:latest' + }, + { + value: 'rust:1.60', + label: 'rust:1.60' + }, + { + value: 'rust:1.60-buster', + label: 'rust:1.60-buster' + }, + { + value: 'rust:1.60-bullseye', + label: 'rust:1.60-bullseye' + }, + { + value: 'rust:1.60-slim-buster', + label: 'rust:1.60-slim-buster' + }, + { + value: 'rust:1.60-slim-bullseye', + label: 'rust:1.60-slim-bullseye' + }, + { + value: 'rust:1.60-alpine3.14', + label: 'rust:1.60-alpine3.14' + }, + { + value: 'rust:1.60-alpine3.15', + label: 'rust:1.60-alpine3.15' + } + ]; + const phpVersions = [ + { + value: 'webdevops/php-apache:8.0', + label: 'webdevops/php-apache:8.0' + }, + { + value: 'webdevops/php-nginx:8.0', + label: 'webdevops/php-nginx:8.0' + }, + { + value: 'webdevops/php-apache:7.4', + label: 'webdevops/php-apache:7.4' + }, + { + value: 'webdevops/php-nginx:7.4', + label: 'webdevops/php-nginx:7.4' + }, + { + value: 'webdevops/php-apache:7.3', + label: 'webdevops/php-apache:7.3' + }, + { + value: 'webdevops/php-nginx:7.3', + label: 'webdevops/php-nginx:7.3' + }, + { + value: 'webdevops/php-apache:7.2', + label: 'webdevops/php-apache:7.2' + }, + { + value: 'webdevops/php-nginx:7.2', + label: 'webdevops/php-nginx:7.2' + }, + { + value: 'webdevops/php-apache:7.1', + label: 'webdevops/php-apache:7.1' + }, + { + value: 'webdevops/php-nginx:7.1', + label: 'webdevops/php-nginx:7.1' + }, + { + value: 'webdevops/php-apache:7.0', + label: 'webdevops/php-apache:7.0' + }, + { + value: 'webdevops/php-nginx:7.0', + label: 'webdevops/php-nginx:7.0' + }, + { + value: 'webdevops/php-apache:5.6', + label: 'webdevops/php-apache:5.6' + }, + { + value: 'webdevops/php-nginx:5.6', + label: 'webdevops/php-nginx:5.6' + }, + { + value: 'webdevops/php-apache:8.0-alpine', + label: 'webdevops/php-apache:8.0-alpine' + }, + { + value: 'webdevops/php-nginx:8.0-alpine', + label: 'webdevops/php-nginx:8.0-alpine' + }, + { + value: 'webdevops/php-apache:7.4-alpine', + label: 'webdevops/php-apache:7.4-alpine' + }, + { + value: 'webdevops/php-nginx:7.4-alpine', + label: 'webdevops/php-nginx:7.4-alpine' + }, + { + value: 'webdevops/php-apache:7.3-alpine', + label: 'webdevops/php-apache:7.3-alpine' + }, + { + value: 'webdevops/php-nginx:7.3-alpine', + label: 'webdevops/php-nginx:7.3-alpine' + }, + { + value: 'webdevops/php-apache:7.2-alpine', + label: 'webdevops/php-apache:7.2-alpine' + }, + { + value: 'webdevops/php-nginx:7.2-alpine', + label: 'webdevops/php-nginx:7.2-alpine' + }, + { + value: 'webdevops/php-apache:7.1-alpine', + label: 'webdevops/php-apache:7.1-alpine' + }, + { + value: 'webdevops/php-nginx:7.1-alpine', + label: 'webdevops/php-nginx:7.1-alpine' + } + ]; + let payload = { + baseImage: null, + baseBuildImage: null, + baseImages: [], + baseBuildImages: [] + }; + if (nodeBased.includes(buildPack)) { + payload.baseImage = 'node:lts'; + payload.baseImages = nodeVersions; + } + if (staticApps.includes(buildPack)) { + payload.baseImage = 'webdevops/nginx:alpine'; + payload.baseImages = staticVersions; + payload.baseBuildImage = 'node:lts'; + payload.baseBuildImages = nodeVersions; + } + if (buildPack === 'python') { + payload.baseImage = 'python:3-alpine'; + } + if (buildPack === 'rust') { + payload.baseImage = 'rust:latest'; + payload.baseBuildImage = 'rust:latest'; + payload.baseImages = rustVersions; + payload.baseBuildImages = rustVersions; + } + if (buildPack === 'deno') { + payload.baseImage = 'denoland/deno:latest'; + } + if (buildPack === 'php') { + payload.baseImage = 'webdevops/php-apache:8.0-alpine'; + payload.baseImages = phpVersions; + } + return payload; +} diff --git a/src/lib/buildPacks/deno.ts b/src/lib/buildPacks/deno.ts index 2e5569438..8b7e30b5a 100644 --- a/src/lib/buildPacks/deno.ts +++ b/src/lib/buildPacks/deno.ts @@ -45,8 +45,8 @@ const createDockerfile = async (data, image): Promise => { export default async function (data) { try { - const image = 'denoland/deno:latest'; - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + await createDockerfile(data, baseImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/gatsby.ts b/src/lib/buildPacks/gatsby.ts index 38989626d..0cba2a48d 100644 --- a/src/lib/buildPacks/gatsby.ts +++ b/src/lib/buildPacks/gatsby.ts @@ -2,25 +2,25 @@ import { buildCacheImageWithNode, buildImage } from '$lib/docker'; import { promises as fs } from 'fs'; const createDockerfile = async (data, imageforBuild): Promise => { - const { applicationId, tag, workdir, publishDirectory } = data; + const { applicationId, tag, workdir, publishDirectory, baseImage } = data; const Dockerfile: Array = []; Dockerfile.push(`FROM ${imageforBuild}`); Dockerfile.push('WORKDIR /app'); Dockerfile.push(`LABEL coolify.image=true`); Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); - Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + if (baseImage.includes('nginx')) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } Dockerfile.push(`EXPOSE 80`); await fs.writeFile(`${workdir}/Dockerfile`, Dockerfile.join('\n')); }; export default async function (data) { try { - const image = 'webdevops/nginx:alpine'; - const imageForBuild = 'node:lts'; - - await buildCacheImageWithNode(data, imageForBuild); - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + await buildCacheImageWithNode(data, baseImage); + await createDockerfile(data, baseBuildImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/nestjs.ts b/src/lib/buildPacks/nestjs.ts index 915bdd3d7..f529d7645 100644 --- a/src/lib/buildPacks/nestjs.ts +++ b/src/lib/buildPacks/nestjs.ts @@ -22,11 +22,9 @@ const createDockerfile = async (data, image): Promise => { export default async function (data) { try { - const image = 'node:lts'; - const imageForBuild = 'node:lts'; - - await buildCacheImageWithNode(data, imageForBuild); - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + await buildCacheImageWithNode(data, baseBuildImage); + await createDockerfile(data, baseImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/nextjs.ts b/src/lib/buildPacks/nextjs.ts index 0f58b3b84..59c50d7f1 100644 --- a/src/lib/buildPacks/nextjs.ts +++ b/src/lib/buildPacks/nextjs.ts @@ -50,8 +50,8 @@ const createDockerfile = async (data, image): Promise => { export default async function (data) { try { - const image = 'node:lts'; - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + await createDockerfile(data, baseImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/node.ts b/src/lib/buildPacks/node.ts index 869e28b5d..1231892b2 100644 --- a/src/lib/buildPacks/node.ts +++ b/src/lib/buildPacks/node.ts @@ -50,8 +50,8 @@ const createDockerfile = async (data, image): Promise => { export default async function (data) { try { - const image = 'node:lts'; - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + await createDockerfile(data, baseImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/nuxtjs.ts b/src/lib/buildPacks/nuxtjs.ts index bfa48bf73..9120b7d5c 100644 --- a/src/lib/buildPacks/nuxtjs.ts +++ b/src/lib/buildPacks/nuxtjs.ts @@ -49,8 +49,8 @@ const createDockerfile = async (data, image): Promise => { export default async function (data) { try { - const image = 'node:lts'; - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + await createDockerfile(data, baseImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/php.ts b/src/lib/buildPacks/php.ts index cfb39d20a..4bdfaf923 100644 --- a/src/lib/buildPacks/php.ts +++ b/src/lib/buildPacks/php.ts @@ -27,7 +27,7 @@ const createDockerfile = async (data, image, htaccessFound): Promise => { }; export default async function (data) { - const { workdir, baseDirectory } = data; + const { workdir, baseDirectory, baseImage } = data; try { let htaccessFound = false; try { @@ -36,10 +36,7 @@ export default async function (data) { } catch (e) { // } - const image = htaccessFound - ? 'webdevops/php-apache:8.0-alpine' - : 'webdevops/php-nginx:8.0-alpine'; - await createDockerfile(data, image, htaccessFound); + await createDockerfile(data, baseImage, htaccessFound); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/python.ts b/src/lib/buildPacks/python.ts index 1c6bdf6bf..f13965cf0 100644 --- a/src/lib/buildPacks/python.ts +++ b/src/lib/buildPacks/python.ts @@ -62,8 +62,8 @@ const createDockerfile = async (data, image): Promise => { export default async function (data) { try { - const image = 'python:3-alpine'; - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + await createDockerfile(data, baseImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/react.ts b/src/lib/buildPacks/react.ts index 719f782eb..4aca45621 100644 --- a/src/lib/buildPacks/react.ts +++ b/src/lib/buildPacks/react.ts @@ -2,24 +2,25 @@ import { buildCacheImageWithNode, buildImage } from '$lib/docker'; import { promises as fs } from 'fs'; const createDockerfile = async (data, image): Promise => { - const { applicationId, tag, workdir, publishDirectory } = data; + const { applicationId, tag, workdir, publishDirectory, baseImage } = data; const Dockerfile: Array = []; Dockerfile.push(`FROM ${image}`); Dockerfile.push(`LABEL coolify.image=true`); Dockerfile.push('WORKDIR /app'); Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); - Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + if (baseImage.includes('nginx')) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } Dockerfile.push(`EXPOSE 80`); await fs.writeFile(`${workdir}/Dockerfile`, Dockerfile.join('\n')); }; export default async function (data) { try { - const image = 'webdevops/nginx:alpine'; - const imageForBuild = 'node:lts'; - await buildCacheImageWithNode(data, imageForBuild); - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + await buildCacheImageWithNode(data, baseBuildImage); + await createDockerfile(data, baseImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/rust.ts b/src/lib/buildPacks/rust.ts index 586d63140..5db5ad9b5 100644 --- a/src/lib/buildPacks/rust.ts +++ b/src/lib/buildPacks/rust.ts @@ -27,14 +27,12 @@ const createDockerfile = async (data, image, name): Promise => { export default async function (data) { try { - const { workdir } = data; - const image = 'rust:latest'; - const imageForBuild = 'rust:latest'; + const { workdir, baseImage, baseBuildImage } = data; const { stdout: cargoToml } = await asyncExecShell(`cat ${workdir}/Cargo.toml`); const parsedToml: any = TOML.parse(cargoToml); const name = parsedToml.package.name; - await buildCacheImageWithCargo(data, imageForBuild); - await createDockerfile(data, image, name); + await buildCacheImageWithCargo(data, baseBuildImage); + await createDockerfile(data, baseImage, name); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/static.ts b/src/lib/buildPacks/static.ts index e9e7179d5..20afefbba 100644 --- a/src/lib/buildPacks/static.ts +++ b/src/lib/buildPacks/static.ts @@ -10,7 +10,8 @@ const createDockerfile = async (data, image): Promise => { baseDirectory, publishDirectory, secrets, - pullmergeRequestId + pullmergeRequestId, + baseImage } = data; const Dockerfile: Array = []; @@ -37,17 +38,18 @@ const createDockerfile = async (data, image): Promise => { } else { Dockerfile.push(`COPY .${baseDirectory || ''} ./`); } - Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + if (baseImage.includes('nginx')) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } Dockerfile.push(`EXPOSE 80`); await fs.writeFile(`${workdir}/Dockerfile`, Dockerfile.join('\n')); }; export default async function (data) { try { - const image = 'webdevops/nginx:alpine'; - const imageForBuild = 'node:lts'; - if (data.buildCommand) await buildCacheImageWithNode(data, imageForBuild); - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + if (data.buildCommand) await buildCacheImageWithNode(data, baseBuildImage); + await createDockerfile(data, baseImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/svelte.ts b/src/lib/buildPacks/svelte.ts index fbcf36abb..b63560a5d 100644 --- a/src/lib/buildPacks/svelte.ts +++ b/src/lib/buildPacks/svelte.ts @@ -2,25 +2,25 @@ import { buildCacheImageWithNode, buildImage } from '$lib/docker'; import { promises as fs } from 'fs'; const createDockerfile = async (data, image): Promise => { - const { applicationId, tag, workdir, publishDirectory } = data; + const { applicationId, tag, workdir, publishDirectory, baseImage } = data; const Dockerfile: Array = []; Dockerfile.push(`FROM ${image}`); Dockerfile.push('WORKDIR /app'); Dockerfile.push(`LABEL coolify.image=true`); Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); - Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + if (baseImage.includes('nginx')) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } Dockerfile.push(`EXPOSE 80`); await fs.writeFile(`${workdir}/Dockerfile`, Dockerfile.join('\n')); }; export default async function (data) { try { - const image = 'webdevops/nginx:alpine'; - const imageForBuild = 'node:lts'; - - await buildCacheImageWithNode(data, imageForBuild); - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + await buildCacheImageWithNode(data, baseBuildImage); + await createDockerfile(data, baseImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/buildPacks/vuejs.ts b/src/lib/buildPacks/vuejs.ts index fa80ac435..b63560a5d 100644 --- a/src/lib/buildPacks/vuejs.ts +++ b/src/lib/buildPacks/vuejs.ts @@ -2,24 +2,25 @@ import { buildCacheImageWithNode, buildImage } from '$lib/docker'; import { promises as fs } from 'fs'; const createDockerfile = async (data, image): Promise => { - const { applicationId, tag, workdir, publishDirectory } = data; + const { applicationId, tag, workdir, publishDirectory, baseImage } = data; const Dockerfile: Array = []; Dockerfile.push(`FROM ${image}`); Dockerfile.push('WORKDIR /app'); Dockerfile.push(`LABEL coolify.image=true`); Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); - Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + if (baseImage.includes('nginx')) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } Dockerfile.push(`EXPOSE 80`); await fs.writeFile(`${workdir}/Dockerfile`, Dockerfile.join('\n')); }; export default async function (data) { try { - const image = 'webdevops/nginx:alpine'; - const imageForBuild = 'node:lts'; - await buildCacheImageWithNode(data, imageForBuild); - await createDockerfile(data, image); + const { baseImage, baseBuildImage } = data; + await buildCacheImageWithNode(data, baseBuildImage); + await createDockerfile(data, baseImage); await buildImage(data); } catch (error) { throw error; diff --git a/src/lib/database/applications.ts b/src/lib/database/applications.ts index f02300bd2..d64537b69 100644 --- a/src/lib/database/applications.ts +++ b/src/lib/database/applications.ts @@ -12,17 +12,7 @@ import type { Application, ApplicationPersistentStorage } from '@prisma/client'; -const nodeBased = [ - 'react', - 'vuejs', - 'static', - 'svelte', - 'gatsby', - 'php', - 'astro', - 'eleventy', - 'node' -]; +import { setDefaultBaseImage } from '$lib/buildPacks/common'; export async function listApplications(teamId: string): Promise { if (teamId === '0') { @@ -206,26 +196,18 @@ export async function getApplication({ id, teamId }: { id: string; teamId: strin return s; }); } + const { baseImage, baseBuildImage, baseBuildImages, baseImages } = setDefaultBaseImage( + body.buildPack + ); + // Set default build images if (!body.baseImage) { - if (nodeBased.includes(body.buildPack)) { - body.baseImage = 'node:lts'; - } - if (body.buildPack === 'python') { - body.baseImage = 'python:3-alpine'; - } - if (body.buildPack === 'rust') { - body.baseImage = 'rust:latest'; - } - if (body.buildPack === 'deno') { - body.baseImage = 'denoland/deno:latest'; - } - if (body.buildPack === 'php') { - body.baseImage = 'webdevops/php-apache:8.0-alpine'; - } + body.baseImage = baseImage; } - - return { ...body }; + if (!body.baseBuildImage) { + body.baseBuildImage = baseBuildImage; + } + return { ...body, baseBuildImages, baseImages }; } export async function configureGitRepository({ @@ -296,7 +278,8 @@ export async function configureApplication({ dockerFileLocation, denoMainFile, denoOptions, - baseImage + baseImage, + baseBuildImage }: { id: string; buildPack: string; @@ -315,6 +298,7 @@ export async function configureApplication({ denoMainFile: string; denoOptions: string; baseImage: string; + baseBuildImage: string; }): Promise { return await prisma.application.update({ where: { id }, @@ -334,7 +318,8 @@ export async function configureApplication({ dockerFileLocation, denoMainFile, denoOptions, - baseImage + baseImage, + baseBuildImage } }); } diff --git a/src/lib/locales/en.json b/src/lib/locales/en.json index 17f210b52..a5d6cbd50 100644 --- a/src/lib/locales/en.json +++ b/src/lib/locales/en.json @@ -185,6 +185,7 @@ "git_repository": "Git Repository", "build_pack": "Build Pack", "base_image": "Base Image", + "base_build_image": "Base Build Image", "destination": "Destination", "application": "Application", "url_fqdn": "URL (FQDN)", diff --git a/src/lib/queues/builder.ts b/src/lib/queues/builder.ts index 8e1650106..3a74320ef 100644 --- a/src/lib/queues/builder.ts +++ b/src/lib/queues/builder.ts @@ -47,7 +47,9 @@ export default async function (job: Job): Promise): Promise): Promise { dockerFileLocation, denoMainFile, denoOptions, - baseImage + baseImage, + baseBuildImage } = await event.request.json(); if (port) port = Number(port); if (denoOptions) denoOptions = denoOptions.trim(); @@ -98,6 +99,7 @@ export const post: RequestHandler = async (event) => { denoMainFile, denoOptions, baseImage, + baseBuildImage, ...defaultConfiguration }); return { status: 201 }; diff --git a/src/routes/applications/[id]/index.svelte b/src/routes/applications/[id]/index.svelte index f5d9f8c97..f2c5aa97c 100644 --- a/src/routes/applications/[id]/index.svelte +++ b/src/routes/applications/[id]/index.svelte @@ -33,6 +33,8 @@ gitlabApp: Prisma.GitlabApp; gitSource: Prisma.GitSource; destinationDocker: Prisma.DestinationDocker; + baseImages: Array<{ value: string; label: string }>; + baseBuildImages: Array<{ value: string; label: string }>; }; export let isRunning; import { page, session } from '$app/stores'; @@ -71,11 +73,14 @@ label: 'Gunicorn' } ]; - + function containerClass() { + if (!$session.isAdmin || isRunning) { + return 'text-white border border-dashed border-coolgray-300 bg-transparent font-thin px-0'; + } + } if (browser && window.location.hostname === 'demo.coolify.io' && !application.fqdn) { application.fqdn = `http://${cuid()}.demo.coolify.io`; } - onMount(() => { domainEl.focus(); }); @@ -138,6 +143,14 @@ async function selectWSGI(event) { application.pythonWSGI = event.detail.value; } + async function selectBaseImage(event) { + application.baseImage = event.detail.value; + await handleSubmit(); + } + async function selectBaseBuildImage(event) { + application.baseBuildImage = event.detail.value; + await handleSubmit(); + }
@@ -310,14 +323,42 @@ />
-
+
-
- +
+ +
+
+ {/if}
{$t('application.application')}
diff --git a/src/tailwind.css b/src/tailwind.css index 1e48bb81b..529c91cb9 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -46,14 +46,14 @@ textarea { } #svelte .custom-select-wrapper .selectContainer { - @apply h-12 w-96 rounded border-none bg-coolgray-200 p-2 text-xs font-bold tracking-tight outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 md:text-sm; + @apply h-12 w-96 rounded border-none bg-coolgray-200 p-2 px-0 text-xs tracking-tight outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 md:text-sm; } #svelte .listContainer { @apply bg-coolgray-400 text-white scrollbar-w-2 scrollbar-thumb-green-500 scrollbar-track-coolgray-200; } #svelte .selectedItem { - @apply pl-3; + @apply pl-2; } #svelte .item.hover { @@ -64,7 +64,7 @@ textarea { } select { - @apply h-12 w-96 rounded bg-coolgray-200 p-2 text-xs font-bold tracking-tight text-white placeholder-stone-600 outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 disabled:text-stone-600 md:text-sm; + @apply h-12 w-96 rounded bg-coolgray-200 p-2 text-xs font-bold tracking-tight text-white placeholder-stone-600 outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 disabled:text-stone-600 md:text-sm; } .svelte-select { --background: rgb(32 32 32);