diff --git a/apps/api/src/jobs/checkProxies.ts b/apps/api/src/jobs/checkProxies.ts index e307ef858..992281c3a 100644 --- a/apps/api/src/jobs/checkProxies.ts +++ b/apps/api/src/jobs/checkProxies.ts @@ -1,10 +1,11 @@ import { parentPort } from 'node:worker_threads'; -import { prisma, startTraefikTCPProxy, generateDatabaseConfiguration, startTraefikProxy, executeDockerCmd } from '../lib/common'; +import { prisma, startTraefikTCPProxy, generateDatabaseConfiguration, startTraefikProxy, executeDockerCmd, listSettings } from '../lib/common'; import { checkContainer } from '../lib/docker'; (async () => { if (parentPort) { try { + const { arch } = await listSettings(); // Coolify Proxy local const engine = '/var/run/docker.sock'; const localDocker = await prisma.destinationDocker.findFirst({ @@ -30,7 +31,7 @@ import { checkContainer } from '../lib/docker'; for (const database of databasesWithPublicPort) { const { destinationDockerId, destinationDocker, publicPort, id } = database; if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { - const { privatePort } = generateDatabaseConfiguration(database); + const { privatePort } = generateDatabaseConfiguration(database, arch); // Remove HAProxy const found = await checkContainer({ dockerId: localDocker.id, container: `haproxy-for-${publicPort}` diff --git a/apps/api/src/lib/common.ts b/apps/api/src/lib/common.ts index ccbd969c9..dc8066239 100644 --- a/apps/api/src/lib/common.ts +++ b/apps/api/src/lib/common.ts @@ -17,7 +17,7 @@ import { checkContainer, removeContainer } from './docker'; import { day } from './dayjs'; import * as serviceFields from './serviceFields' -export const version = '3.2.3'; +export const version = '3.3.0'; export const isDev = process.env.NODE_ENV === 'development'; const algorithm = 'aes-256-ctr'; @@ -460,28 +460,50 @@ export const supportedDatabaseTypesAndVersions = [ name: 'mongodb', fancyName: 'MongoDB', baseImage: 'bitnami/mongodb', - versions: ['5.0', '4.4', '4.2'] + baseImageARM: 'mongo', + versions: ['5.0', '4.4', '4.2'], + versionsARM: ['5.0', '4.4', '4.2'] + }, + { + name: 'mysql', + fancyName: 'MySQL', + baseImage: 'bitnami/mysql', + baseImageARM: 'mysql', + versions: ['8.0', '5.7'], + versionsARM: ['8.0', '5.7'] }, - { name: 'mysql', fancyName: 'MySQL', baseImage: 'bitnami/mysql', versions: ['8.0', '5.7'] }, { name: 'mariadb', fancyName: 'MariaDB', baseImage: 'bitnami/mariadb', - versions: ['10.8', '10.7', '10.6', '10.5', '10.4', '10.3', '10.2'] + baseImageARM: 'mariadb', + versions: ['10.8', '10.7', '10.6', '10.5', '10.4', '10.3', '10.2'], + versionsARM: ['10.8', '10.7', '10.6', '10.5', '10.4', '10.3', '10.2'] }, { name: 'postgresql', fancyName: 'PostgreSQL', baseImage: 'bitnami/postgresql', - versions: ['14.4.0', '13.6.0', '12.10.0', '11.15.0', '10.20.0'] + baseImageARM: 'postgres', + versions: ['14.5.0', '13.8.0', '12.12.0', '11.17.0', '10.22.0'], + versionsARM: ['14.5', '13.8', '12.12', '11.17', '10.22'] }, { name: 'redis', fancyName: 'Redis', baseImage: 'bitnami/redis', - versions: ['7.0', '6.2', '6.0', '5.0'] + baseImageARM: 'redis', + versions: ['7.0', '6.2', '6.0', '5.0'], + versionsARM: ['7.0', '6.2', '6.0', '5.0'] }, - { name: 'couchdb', fancyName: 'CouchDB', baseImage: 'bitnami/couchdb', versions: ['3.2.2'] } + { + name: 'couchdb', + fancyName: 'CouchDB', + baseImage: 'bitnami/couchdb', + baseImageARM: 'couchdb', + versions: ['3.2.2', '3.1.2', '2.3.1'], + versionsARM: ['3.2.2', '3.1.2', '2.3.1'] + } ]; export async function getFreeSSHLocalPort(id: string): Promise { @@ -674,10 +696,11 @@ export function generatePassword(length = 24, symbols = false): string { }); } -export function generateDatabaseConfiguration(database: any): +export function generateDatabaseConfiguration(database: any, arch: string): | { volume: string; image: string; + command?: string; ulimits: Record; privatePort: number; environmentVariables: { @@ -691,16 +714,20 @@ export function generateDatabaseConfiguration(database: any): | { volume: string; image: string; + command?: string; ulimits: Record; privatePort: number; environmentVariables: { - MONGODB_ROOT_USER: string; - MONGODB_ROOT_PASSWORD: string; + MONGO_INITDB_ROOT_USERNAME?: string; + MONGO_INITDB_ROOT_PASSWORD?: string; + MONGODB_ROOT_USER?: string; + MONGODB_ROOT_PASSWORD?: string; }; } | { volume: string; image: string; + command?: string; ulimits: Record; privatePort: number; environmentVariables: { @@ -714,6 +741,7 @@ export function generateDatabaseConfiguration(database: any): | { volume: string; image: string; + command?: string; ulimits: Record; privatePort: number; environmentVariables: { @@ -726,6 +754,19 @@ export function generateDatabaseConfiguration(database: any): | { volume: string; image: string; + command?: string; + ulimits: Record; + privatePort: number; + environmentVariables: { + POSTGRES_USER: string; + POSTGRES_PASSWORD: string; + POSTGRES_DB: string; + }; + } + | { + volume: string; + image: string; + command?: string; ulimits: Record; privatePort: number; environmentVariables: { @@ -736,6 +777,7 @@ export function generateDatabaseConfiguration(database: any): | { volume: string; image: string; + command?: string; ulimits: Record; privatePort: number; environmentVariables: { @@ -754,9 +796,9 @@ export function generateDatabaseConfiguration(database: any): type, settings: { appendOnly } } = database; - const baseImage = getDatabaseImage(type); + const baseImage = getDatabaseImage(type, arch); if (type === 'mysql') { - return { + const configuration = { privatePort: 3306, environmentVariables: { MYSQL_USER: dbUser, @@ -768,9 +810,13 @@ export function generateDatabaseConfiguration(database: any): image: `${baseImage}:${version}`, volume: `${id}-${type}-data:/bitnami/mysql/data`, ulimits: {} - }; + } + if (isARM(arch)) { + configuration.volume = `${id}-${type}-data:/var/lib/mysql`; + } + return configuration } else if (type === 'mariadb') { - return { + const configuration = { privatePort: 3306, environmentVariables: { MARIADB_ROOT_USER: rootUser, @@ -783,8 +829,12 @@ export function generateDatabaseConfiguration(database: any): volume: `${id}-${type}-data:/bitnami/mariadb`, ulimits: {} }; + if (isARM(arch)) { + configuration.volume = `${id}-${type}-data:/var/lib/mysql`; + } + return configuration } else if (type === 'mongodb') { - return { + const configuration = { privatePort: 27017, environmentVariables: { MONGODB_ROOT_USER: rootUser, @@ -794,8 +844,16 @@ export function generateDatabaseConfiguration(database: any): volume: `${id}-${type}-data:/bitnami/mongodb`, ulimits: {} }; + if (isARM(arch)) { + configuration.environmentVariables = { + MONGO_INITDB_ROOT_USERNAME: rootUser, + MONGO_INITDB_ROOT_PASSWORD: rootUserPassword + } + configuration.volume = `${id}-${type}-data:/data/db`; + } + return configuration } else if (type === 'postgresql') { - return { + const configuration = { privatePort: 5432, environmentVariables: { POSTGRESQL_POSTGRES_PASSWORD: rootUserPassword, @@ -806,10 +864,15 @@ export function generateDatabaseConfiguration(database: any): image: `${baseImage}:${version}`, volume: `${id}-${type}-data:/bitnami/postgresql`, ulimits: {} - }; + } + if (isARM(arch)) { + configuration.volume = `${id}-${type}-data:/var/lib/postgresql`; + } + return configuration } else if (type === 'redis') { - return { + const configuration = { privatePort: 6379, + command: undefined, environmentVariables: { REDIS_PASSWORD: dbUserPassword, REDIS_AOF_ENABLED: appendOnly ? 'yes' : 'no' @@ -818,8 +881,13 @@ export function generateDatabaseConfiguration(database: any): volume: `${id}-${type}-data:/bitnami/redis/data`, ulimits: {} }; + if (isARM(arch)) { + configuration.volume = `${id}-${type}-data:/data`; + configuration.command = `/usr/local/bin/redis-server --appendonly ${appendOnly ? 'yes' : 'no'} --requirepass ${dbUserPassword}`; + } + return configuration } else if (type === 'couchdb') { - return { + const configuration = { privatePort: 5984, environmentVariables: { COUCHDB_PASSWORD: dbUserPassword, @@ -829,20 +897,35 @@ export function generateDatabaseConfiguration(database: any): volume: `${id}-${type}-data:/bitnami/couchdb`, ulimits: {} }; + if (isARM(arch)) { + configuration.volume = `${id}-${type}-data:/opt/couchdb/data`; + } + return configuration } } - -export function getDatabaseImage(type: string): string { +export function isARM(arch) { + if (arch === 'arm' || arch === 'arm64') { + return true + } + return false +} +export function getDatabaseImage(type: string, arch: string): string { const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type); if (found) { + if (isARM(arch)) { + return found.baseImageARM || found.baseImage + } return found.baseImage; } return ''; } -export function getDatabaseVersions(type: string): string[] { +export function getDatabaseVersions(type: string, arch: string): string[] { const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type); if (found) { + if (isARM(arch)) { + return found.versionsARM || found.versions + } return found.versions; } return []; diff --git a/apps/api/src/routes/api/v1/databases/handlers.ts b/apps/api/src/routes/api/v1/databases/handlers.ts index ca5fc67c0..5d3bcac51 100644 --- a/apps/api/src/routes/api/v1/databases/handlers.ts +++ b/apps/api/src/routes/api/v1/databases/handlers.ts @@ -3,7 +3,7 @@ import type { FastifyRequest } from 'fastify'; import { FastifyReply } from 'fastify'; import yaml from 'js-yaml'; import fs from 'fs/promises'; -import { ComposeFile, createDirectories, decrypt, encrypt, errorHandler, executeDockerCmd, generateDatabaseConfiguration, generatePassword, getContainerUsage, getDatabaseImage, getDatabaseVersions, getFreePublicPort, listSettings, makeLabelForStandaloneDatabase, prisma, startTraefikTCPProxy, stopDatabaseContainer, stopTcpHttpProxy, supportedDatabaseTypesAndVersions, uniqueName, updatePasswordInDb } from '../../../../lib/common'; +import { ComposeFile, createDirectories, decrypt, encrypt, errorHandler, executeDockerCmd, generateDatabaseConfiguration, generatePassword, getContainerUsage, getDatabaseImage, getDatabaseVersions, getFreePublicPort, isARM, listSettings, makeLabelForStandaloneDatabase, prisma, startTraefikTCPProxy, stopDatabaseContainer, stopTcpHttpProxy, supportedDatabaseTypesAndVersions, uniqueName, updatePasswordInDb } from '../../../../lib/common'; import { checkContainer } from '../../../../lib/docker'; import { day } from '../../../../lib/dayjs'; @@ -93,14 +93,15 @@ export async function getDatabase(request: FastifyRequest) { if (!database) { throw { status: 404, message: 'Database not found.' } } + const { arch } = await listSettings(); if (database.dbUserPassword) database.dbUserPassword = decrypt(database.dbUserPassword); if (database.rootUserPassword) database.rootUserPassword = decrypt(database.rootUserPassword); - const configuration = generateDatabaseConfiguration(database); + const configuration = generateDatabaseConfiguration(database, arch); const settings = await listSettings(); return { privatePort: configuration?.privatePort, database, - versions: await getDatabaseVersions(database.type), + versions: await getDatabaseVersions(database.type, arch), settings }; } catch ({ status, message }) { @@ -137,8 +138,10 @@ export async function getVersions(request: FastifyRequest) { where: { id, teams: { some: { id: teamId === '0' ? undefined : teamId } } }, include: { destinationDocker: true, settings: true } }); + const { arch } = await listSettings(); + const versions = getDatabaseVersions(type, arch); return { - versions: supportedDatabaseTypesAndVersions.find((name) => name.name === type).versions + versions } } catch ({ status, message }) { return errorHandler({ status, message }) @@ -219,6 +222,7 @@ export async function startDatabase(request: FastifyRequest) { where: { id, teams: { some: { id: teamId === '0' ? undefined : teamId } } }, include: { destinationDocker: true, settings: true } }); + const { arch } = await listSettings(); if (database.dbUserPassword) database.dbUserPassword = decrypt(database.dbUserPassword); if (database.rootUserPassword) database.rootUserPassword = decrypt(database.rootUserPassword); const { @@ -228,8 +232,8 @@ export async function startDatabase(request: FastifyRequest) { publicPort, settings: { isPublic } } = database; - const { privatePort, environmentVariables, image, volume, ulimits } = - generateDatabaseConfiguration(database); + const { privatePort, command, environmentVariables, image, volume, ulimits } = + generateDatabaseConfiguration(database, arch); const network = destinationDockerId && destinationDocker.network; const volumeName = volume.split(':')[0]; @@ -243,6 +247,7 @@ export async function startDatabase(request: FastifyRequest) { [id]: { container_name: id, image, + command, networks: [network], environment: environmentVariables, volumes: [volume], @@ -270,6 +275,7 @@ export async function startDatabase(request: FastifyRequest) { } } }; + const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); try { @@ -282,6 +288,7 @@ export async function startDatabase(request: FastifyRequest) { if (isPublic) await startTraefikTCPProxy(destinationDocker, id, publicPort, privatePort); return {}; } catch (error) { + console.log(error) throw { error }; @@ -440,11 +447,12 @@ export async function saveDatabaseSettings(request: FastifyRequest { const serviceType = supportedServiceTypesAndVersions.find((s) => s.name === service); if (serviceType) { diff --git a/apps/ui/src/lib/components/Toast.svelte b/apps/ui/src/lib/components/Toast.svelte index dd5547a46..282bc159f 100644 --- a/apps/ui/src/lib/components/Toast.svelte +++ b/apps/ui/src/lib/components/Toast.svelte @@ -1,10 +1,16 @@
dispatch('pause')} + on:focus={() => dispatch('pause')} + on:mouseout={() => dispatch('resume')} + on:blur={() => dispatch('resume')} class="alert shadow-lg text-white rounded" - class:alert-success={type === 'success'} + class:bg-coollabs={type === 'success'} class:alert-error={type === 'error'} class:alert-info={type === 'info'} > diff --git a/apps/ui/src/lib/components/Toasts.svelte b/apps/ui/src/lib/components/Toasts.svelte index 856b0c261..2e53c6287 100644 --- a/apps/ui/src/lib/components/Toasts.svelte +++ b/apps/ui/src/lib/components/Toasts.svelte @@ -2,14 +2,18 @@ import { fade } from 'svelte/transition'; import Toast from './Toast.svelte'; - import { toasts } from '$lib/store'; + import { pauseToast, resumeToast, toasts } from '$lib/store'; {#if $toasts}
-
@@ -17,6 +21,6 @@ diff --git a/apps/ui/src/lib/components/Usage.svelte b/apps/ui/src/lib/components/Usage.svelte index 79b69662d..6868322ad 100644 --- a/apps/ui/src/lib/components/Usage.svelte +++ b/apps/ui/src/lib/components/Usage.svelte @@ -22,11 +22,10 @@ usage: false, cleanup: false }; - import { addToast, appSession } from '$lib/store'; + import { appSession } from '$lib/store'; import { onDestroy, onMount } from 'svelte'; - import { get, post } from '$lib/api'; + import { get } from '$lib/api'; import { errorNotification } from '$lib/common'; - import Trend from './Trend.svelte'; async function getStatus() { if (loading.usage) return; loading.usage = true; @@ -49,118 +48,66 @@ return errorNotification(error); } }); - - let warning = { - memory: false, - cpu: false, - disk: false - }; - let trends = { - memory: 'stable', - cpu: 'stable', - disk: 'stable' - }; - async function manuallyCleanupStorage() { - try { - loading.cleanup = true - await post('/internal/cleanup', {}); - return addToast({ - message: "Cleanup done.", - type:"success" - }) - } catch(error) { - return errorNotification(error); - } finally { - loading.cleanup = false - } - } -{#if $appSession.teamId === '0'} -
Server Usage
-
-
-
Total Memory
-
- {(usage?.memory.totalMemMb).toFixed(0)}MB -
+
+
Hardware Details
+
+
+
+
Total Memory
+
+ {(usage?.memory.totalMemMb).toFixed(0)}MB +
+
+
+
Used Memory
+
+ {(usage?.memory.usedMemMb).toFixed(0)}MB +
+
+
+
Free Memory
+
+ {usage?.memory.freeMemPercentage}% +
+
- -
-
Used Memory
-
- {(usage?.memory.usedMemMb).toFixed(0)}MB -
+
+
+
Total CPUs
+
+ {usage?.cpu.count} +
+
+
+
CPU Usage
+
+ {usage?.cpu.usage}% +
+
+
+
Load Average (5,10,30mins)
+
{usage?.cpu.load}
+
- -
-
Free Memory
-
- {usage?.memory.freeMemPercentage}% - {#if !warning.memory} - - {/if} -
+
+
+
Total Disk
+
+ {usage?.disk.totalGb}GB +
+
+
+
Used Disk
+
+ {usage?.disk.usedGb}GB +
+
+
+
Free Disk
+
{usage?.disk.freePercentage}%
+
-
-
-
-
Total CPUs
-
- {usage?.cpu.count} -
-
-
-
CPU Usage
-
- {usage?.cpu.usage}% - {#if !warning.cpu} - - {/if} -
-
-
-
Load Average (5/10/30mins)
-
- {usage?.cpu.load.join('/')} -
-
-
-
-
-
Total Disk
-
- {usage?.disk.totalGb}GB -
-
-
-
Used Disk
-
- {usage?.disk.usedGb}GB -
- -
-
-
Free Disk
-
- {usage?.disk.freePercentage}% - {#if !warning.disk} - - {/if} -
-
-
- -
Resources
-{/if} +
+ diff --git a/apps/ui/src/lib/components/svg/applications/ApplicationIcons.svelte b/apps/ui/src/lib/components/svg/applications/ApplicationIcons.svelte new file mode 100644 index 000000000..a633375b7 --- /dev/null +++ b/apps/ui/src/lib/components/svg/applications/ApplicationIcons.svelte @@ -0,0 +1,41 @@ + + +{#if application.buildPack.toLowerCase() === 'rust'} + +{:else if application.buildPack.toLowerCase() === 'node'} + +{:else if application.buildPack.toLowerCase() === 'react'} + +{:else if application.buildPack.toLowerCase() === 'svelte'} + +{:else if application.buildPack.toLowerCase() === 'vuejs'} + +{:else if application.buildPack.toLowerCase() === 'php'} + +{:else if application.buildPack.toLowerCase() === 'python'} + +{:else if application.buildPack.toLowerCase() === 'static'} + +{:else if application.buildPack.toLowerCase() === 'nestjs'} + +{:else if application.buildPack.toLowerCase() === 'nuxtjs'} + +{:else if application.buildPack.toLowerCase() === 'nextjs'} + +{:else if application.buildPack.toLowerCase() === 'gatsby'} + +{:else if application.buildPack.toLowerCase() === 'docker'} + +{:else if application.buildPack.toLowerCase() === 'astro'} + +{:else if application.buildPack.toLowerCase() === 'eleventy'} + +{:else if application.buildPack.toLowerCase() === 'deno'} + +{:else if application.buildPack.toLowerCase() === 'laravel'} + +{/if} diff --git a/apps/ui/src/lib/components/svg/applications/Astro.svelte b/apps/ui/src/lib/components/svg/applications/Astro.svelte index df8d0804f..2344372ab 100644 --- a/apps/ui/src/lib/components/svg/applications/Astro.svelte +++ b/apps/ui/src/lib/components/svg/applications/Astro.svelte @@ -1,5 +1,9 @@ + + + export let isAbsolute = true; + +
Application Usage
-
-
-
-
Used Memory / Memory Limit
-
- {usage?.MemUsage} -
-
+
+
+
Used Memory / Memory Limit
+
{usage?.MemUsage}
+
-
-
Used CPU
-
- {usage?.CPUPerc} -
-
+
+
Used CPU
+
{usage?.CPUPerc}
+
-
-
Network IO
-
- {usage?.NetIO} -
-
-
+
+
Network IO
+
{usage?.NetIO}
+
@@ -324,11 +316,10 @@ class="btn btn-sm" type="submit" class:bg-applications={!loading} - class:loading={loading} + class:loading class:bg-orange-600={forceSave} class:hover:bg-orange-400={forceSave} - disabled={loading} - >{$t('forms.save')}{$t('forms.save')} {/if}
diff --git a/apps/ui/src/routes/applications/index.svelte b/apps/ui/src/routes/applications/index.svelte index c321b267c..8c7b8fe73 100644 --- a/apps/ui/src/routes/applications/index.svelte +++ b/apps/ui/src/routes/applications/index.svelte @@ -26,24 +26,8 @@ import { t } from '$lib/translations'; import { getDomain } from '$lib/common'; import { appSession } from '$lib/store'; + import ApplicationsIcons from '$lib/components/svg/applications/ApplicationIcons.svelte'; - import Rust from '$lib/components/svg/applications/Rust.svelte'; - import Nodejs from '$lib/components/svg/applications/Nodejs.svelte'; - import React from '$lib/components/svg/applications/React.svelte'; - import Svelte from '$lib/components/svg/applications/Svelte.svelte'; - import Vuejs from '$lib/components/svg/applications/Vuejs.svelte'; - import PHP from '$lib/components/svg/applications/PHP.svelte'; - import Python from '$lib/components/svg/applications/Python.svelte'; - import Static from '$lib/components/svg/applications/Static.svelte'; - import Nestjs from '$lib/components/svg/applications/Nestjs.svelte'; - import Nuxtjs from '$lib/components/svg/applications/Nuxtjs.svelte'; - import Nextjs from '$lib/components/svg/applications/Nextjs.svelte'; - import Gatsby from '$lib/components/svg/applications/Gatsby.svelte'; - import Docker from '$lib/components/svg/applications/Docker.svelte'; - import Astro from '$lib/components/svg/applications/Astro.svelte'; - import Eleventy from '$lib/components/svg/applications/Eleventy.svelte'; - import Deno from '$lib/components/svg/applications/Deno.svelte'; - import Laravel from '$lib/components/svg/applications/Laravel.svelte'; ownApplications = applications.filter((application) => { if (application.teams[0].id === $appSession.teamId) { return application; @@ -63,10 +47,7 @@
{$t('index.applications')}
{#if $appSession.isAdmin} - diff --git a/apps/ui/src/routes/databases/[id]/configuration/type.svelte b/apps/ui/src/routes/databases/[id]/configuration/type.svelte index 48666f391..006ad0a14 100644 --- a/apps/ui/src/routes/databases/[id]/configuration/type.svelte +++ b/apps/ui/src/routes/databases/[id]/configuration/type.svelte @@ -31,18 +31,11 @@ const { id } = $page.params; const from = $page.url.searchParams.get('from'); - - import Clickhouse from '$lib/components/svg/databases/Clickhouse.svelte'; - import CouchDB from '$lib/components/svg/databases/CouchDB.svelte'; - import MongoDB from '$lib/components/svg/databases/MongoDB.svelte'; - import MariaDB from '$lib/components/svg/databases/MariaDB.svelte'; - import MySQL from '$lib/components/svg/databases/MySQL.svelte'; - import PostgreSQL from '$lib/components/svg/databases/PostgreSQL.svelte'; - import Redis from '$lib/components/svg/databases/Redis.svelte'; import { goto } from '$app/navigation'; import { get, post } from '$lib/api'; import { t } from '$lib/translations'; import { errorNotification } from '$lib/common'; + import DatabaseIcons from '$lib/components/svg/databases/DatabaseIcons.svelte'; async function handleSubmit(type: any) { try { await post(`/databases/${id}/configuration/type`, { type }); @@ -62,21 +55,8 @@
handleSubmit(type.name)}>
diff --git a/apps/ui/src/routes/databases/[id]/index.svelte b/apps/ui/src/routes/databases/[id]/index.svelte index 8faa8ccc4..cb70d1eb9 100644 --- a/apps/ui/src/routes/databases/[id]/index.svelte +++ b/apps/ui/src/routes/databases/[id]/index.svelte @@ -48,7 +48,7 @@ }); -
+
Configuration @@ -60,29 +60,21 @@
Database Usage
-
-
-
-
Used Memory / Memory Limit
-
- {usage?.MemUsage} -
-
+
+
+
Used Memory / Memory Limit
+
{usage?.MemUsage}
+
-
-
Used CPU
-
- {usage?.CPUPerc} -
-
+
+
Used CPU
+
{usage?.CPUPerc}
+
-
-
Network IO
-
- {usage?.NetIO} -
-
-
+
+
Network IO
+
{usage?.NetIO}
+
- + diff --git a/apps/ui/src/routes/databases/index.svelte b/apps/ui/src/routes/databases/index.svelte index 9cd404138..c14c9c3f3 100644 --- a/apps/ui/src/routes/databases/index.svelte +++ b/apps/ui/src/routes/databases/index.svelte @@ -19,17 +19,11 @@
{$t('index.dashboard')}
+
-
- -
- -
{$t('index.applications')}
-
- {applicationsCount} -
-
- -
{$t('index.destinations')}
-
- {destinationsCount} -
-
+
+
+
+
Resources
+
+ + + {#each applications as application} + + + + + + + {/each} - -
{$t('index.git_sources')}
-
- {sourcesCount} -
-
- -
- -
{$t('index.databases')}
-
- {databasesCount} -
-
+ {#each services as service} +
+ + + - -
{$t('index.services')}
-
- {servicesCount} -
-
- - -
{$t('index.teams')}
-
- {teamsCount} -
-
- + + + {/each} + {#each databases as database} + + + + + + + {/each} + +
+ {#await getStatus(application)} +
+ {:then status} + {#if status === 'Running'} +
+ {:else} +
+ {/if} + {/await} +
{application.name}
+
+ + +
+ Application +
+ {#if application.fqdn} + + + + + + + {/if} + + + + + + + + + + + + + + +
+ {#await getStatus(service)} +
+ {:then status} + {#if status === 'Running'} +
+ {:else} +
+ {/if} + {/await} +
{service.name}
+
+ +
+ Service +
+
+ {#if service.fqdn} + + + + + + + {/if} + + + + + + + + + + + + + + +
+ {#await getStatus(database)} +
+ {:then status} + {#if status === 'Running'} +
+ {:else} +
+ {/if} + {/await} +
{database.name}
+
+ + +
+ Database +
+
+ + + + + + + + + + + + + + +
+
+
+ {#if $appSession.teamId === '0'} + + {/if} +
diff --git a/apps/ui/src/routes/services/[id]/configuration/type.svelte b/apps/ui/src/routes/services/[id]/configuration/type.svelte index 6764eaa08..ef3d0fad3 100644 --- a/apps/ui/src/routes/services/[id]/configuration/type.svelte +++ b/apps/ui/src/routes/services/[id]/configuration/type.svelte @@ -32,7 +32,7 @@ import { get, post } from '$lib/api'; import { t } from '$lib/translations'; import { errorNotification } from '$lib/common'; - import Services from '../_Services.svelte'; + import ServiceIcons from '$lib/components/svg/services/ServiceIcons.svelte'; const { id } = $page.params; const from = $page.url.searchParams.get('from'); @@ -56,7 +56,7 @@
handleSubmit(type.name)}>
diff --git a/apps/ui/src/routes/services/[id]/index.svelte b/apps/ui/src/routes/services/[id]/index.svelte index c503e3552..f2ed2852f 100644 --- a/apps/ui/src/routes/services/[id]/index.svelte +++ b/apps/ui/src/routes/services/[id]/index.svelte @@ -61,29 +61,21 @@
Service Usage
-
-
-
-
Used Memory / Memory Limit
-
- {usage?.MemUsage} -
-
+
+
+
Used Memory / Memory Limit
+
{usage?.MemUsage}
+
-
-
Used CPU
-
- {usage?.CPUPerc} -
-
+
+
Used CPU
+
{usage?.CPUPerc}
+
-
-
Network IO
-
- {usage?.NetIO} -
-
-
+
+
Network IO
+
{usage?.NetIO}
+
diff --git a/apps/ui/src/routes/services/index.svelte b/apps/ui/src/routes/services/index.svelte index be784b453..cb9f4ad55 100644 --- a/apps/ui/src/routes/services/index.svelte +++ b/apps/ui/src/routes/services/index.svelte @@ -24,9 +24,8 @@ import { t } from '$lib/translations'; import { appSession } from '$lib/store'; - import * as Icons from '$lib/components/svg/services'; import { getDomain } from '$lib/common'; - import Services from './[id]/_Services.svelte'; + import ServiceIcons from '$lib/components/svg/services/ServiceIcons.svelte'; async function newService() { const { id } = await post('/services/new', {}); @@ -46,24 +45,21 @@
{$t('index.services')}
- +
@@ -78,7 +74,7 @@ {#each ownServices as service}
- +
{service.name}
diff --git a/apps/ui/src/routes/sources/[id]/_Github.svelte b/apps/ui/src/routes/sources/[id]/_Github.svelte index 82522092d..8ed240cf2 100644 --- a/apps/ui/src/routes/sources/[id]/_Github.svelte +++ b/apps/ui/src/routes/sources/[id]/_Github.svelte @@ -34,31 +34,6 @@ } } - async function installRepositories(source: any) { - const { htmlUrl } = source; - let endpoint = 'apps' - if (htmlUrl !== 'https://github.com') { - endpoint = 'github-apps' - } - const left = screen.width / 2 - 1020 / 2; - const top = screen.height / 2 - 1000 / 2; - const newWindow = open( - `${htmlUrl}/${endpoint}/${source.githubApp.name}/installations/new`, - 'GitHub', - 'resizable=1, scrollbars=1, fullscreen=0, height=1000, width=1020,top=' + - top + - ', left=' + - left + - ', toolbar=0, menubar=0, status=0' - ); - const timer = setInterval(() => { - if (newWindow?.closed) { - clearInterval(timer); - window.location.reload(); - } - }, 100); - } - async function newGithubApp() { loading = true; try { @@ -183,7 +158,7 @@ >
{$t('source.change_app_settings', { name: 'GitHub' })} {/if} @@ -254,8 +229,8 @@ {:else}
- - diff --git a/apps/ui/src/tailwind.css b/apps/ui/src/tailwind.css index 66dcfd1b2..ebc6b69d6 100644 --- a/apps/ui/src/tailwind.css +++ b/apps/ui/src/tailwind.css @@ -192,4 +192,13 @@ a { .sub-menu-active { @apply bg-coolgray-500 text-white; +} + +.table tbody td, +.table tbody th, +.table thead th{ + background-color: transparent; +} +.table *{ + border: none; } \ No newline at end of file diff --git a/package.json b/package.json index 751b76f3b..cc558daff 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "coolify", "description": "An open-source & self-hostable Heroku / Netlify alternative.", - "version": "3.2.3", + "version": "3.3.0", "license": "Apache-2.0", "repository": "github:coollabsio/coolify", "scripts": {