From 91fa7629856edf399daa6b8613b04a055c612f3b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 16 Aug 2022 09:13:22 +0000 Subject: [PATCH] fix: appwrite --- apps/api/src/lib/services.ts | 4 +- .../src/routes/api/v1/databases/handlers.ts | 3 +- .../src/routes/api/v1/services/handlers.ts | 887 ++++-------------- .../components/svg/services/Appwrite.svelte | 21 + .../svg/services/ServiceIcons.svelte | 2 + .../src/lib/components/svg/services/index.ts | 30 +- .../routes/services/[id]/_ServiceLinks.svelte | 2 +- .../services/[id]/_Services/_Wordpress.svelte | 2 +- 8 files changed, 202 insertions(+), 749 deletions(-) create mode 100644 apps/ui/src/lib/components/svg/services/Appwrite.svelte diff --git a/apps/api/src/lib/services.ts b/apps/api/src/lib/services.ts index 22c8081a5..c5d315ff0 100644 --- a/apps/api/src/lib/services.ts +++ b/apps/api/src/lib/services.ts @@ -13,13 +13,13 @@ export async function defaultServiceConfigurations({ id, teamId }) { let secrets = []; if (serviceSecret.length > 0) { serviceSecret.forEach((secret) => { - secrets.push([secret.name]=secret.value); + secrets.push(`${secret.name}=${secret.value}`); }); } return { ...service, network, port, workdir, image, secrets } } -export function defaultServiceComposeConfiguration(network: string) { +export function defaultServiceComposeConfiguration(network: string): any { return { networks: [network], restart: 'always', diff --git a/apps/api/src/routes/api/v1/databases/handlers.ts b/apps/api/src/routes/api/v1/databases/handlers.ts index 5d3bcac51..96c740440 100644 --- a/apps/api/src/routes/api/v1/databases/handlers.ts +++ b/apps/api/src/routes/api/v1/databases/handlers.ts @@ -3,8 +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, isARM, listSettings, makeLabelForStandaloneDatabase, prisma, startTraefikTCPProxy, stopDatabaseContainer, stopTcpHttpProxy, supportedDatabaseTypesAndVersions, uniqueName, updatePasswordInDb } from '../../../../lib/common'; -import { checkContainer } from '../../../../lib/docker'; +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 { day } from '../../../../lib/dayjs'; import { GetDatabaseLogs, OnlyId, SaveDatabase, SaveDatabaseDestination, SaveDatabaseSettings, SaveVersion } from '../../../../types'; diff --git a/apps/api/src/routes/api/v1/services/handlers.ts b/apps/api/src/routes/api/v1/services/handlers.ts index ceef05420..bfd8a9352 100644 --- a/apps/api/src/routes/api/v1/services/handlers.ts +++ b/apps/api/src/routes/api/v1/services/handlers.ts @@ -2,7 +2,7 @@ import type { FastifyReply, FastifyRequest } from 'fastify'; import fs from 'fs/promises'; import yaml from 'js-yaml'; import bcrypt from 'bcryptjs'; -import { prisma, uniqueName, asyncExecShell, getServiceImage, configureServiceType, getServiceFromDB, getContainerUsage, removeService, isDomainConfigured, saveUpdateableFields, fixType, decrypt, encrypt, getServiceMainPort, createDirectories, ComposeFile, makeLabelForServices, getFreePublicPort, getDomain, errorHandler, generatePassword, isDev, stopTcpHttpProxy, supportedServiceTypesAndVersions, executeDockerCmd, listSettings, getFreeExposedPort, checkDomainsIsValidInDNS, persistentVolumes } from '../../../../lib/common'; +import { prisma, uniqueName, asyncExecShell, getServiceImage, configureServiceType, getServiceFromDB, getContainerUsage, removeService, isDomainConfigured, saveUpdateableFields, fixType, decrypt, encrypt, getServiceMainPort, createDirectories, ComposeFile, makeLabelForServices, getFreePublicPort, getDomain, errorHandler, generatePassword, isDev, stopTcpHttpProxy, supportedServiceTypesAndVersions, executeDockerCmd, listSettings, getFreeExposedPort, checkDomainsIsValidInDNS, persistentVolumes, asyncSleep, isARM } from '../../../../lib/common'; import { day } from '../../../../lib/dayjs'; import { checkContainer, isContainerExited, removeContainer } from '../../../../lib/docker'; import cuid from 'cuid'; @@ -135,8 +135,7 @@ import { defaultServiceComposeConfiguration, defaultServiceConfigurations } from // // config.services[id].environment = environmentVariables // const composeFileDestination = `${workdir}/docker-compose.yaml`; // // await fs.writeFile(composeFileDestination, yaml.dump(config)); -// // await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} pull`); -// // await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`); +// await startServiceContainers(destinationDocker.id, composeFileDestination) // return {} // } catch ({ status, message }) { // return errorHandler({ status, message }) @@ -599,56 +598,54 @@ export async function startService(request: FastifyRequest) { } export async function stopService(request: FastifyRequest) { try { - const { type } = request.params - if (type === 'plausibleanalytics') { - return await stopPlausibleAnalyticsService(request) - } - if (type === 'nocodb') { - return await stopNocodbService(request) - } - if (type === 'minio') { - return await stopMinioService(request) - } - if (type === 'vscodeserver') { - return await stopVscodeService(request) - } - if (type === 'wordpress') { - return await stopWordpressService(request) - } - if (type === 'vaultwarden') { - return await stopVaultwardenService(request) - } - if (type === 'languagetool') { - return await stopLanguageToolService(request) - } - if (type === 'n8n') { - return await stopN8nService(request) - } - if (type === 'uptimekuma') { - return await stopUptimekumaService(request) - } - if (type === 'ghost') { - return await stopGhostService(request) - } - if (type === 'meilisearch') { - return await stopMeilisearchService(request) - } - if (type === 'umami') { - return await stopUmamiService(request) - } - if (type === 'hasura') { - return await stopHasuraService(request) - } - if (type === 'fider') { - return await stopFiderService(request) - } - if (type === 'appwrite') { - return await stopAppWriteService(request) - } - if (type === 'moodle') { - return await stopMoodleService(request) - } - throw `Service type ${type} not supported.` + return await stopServiceContainers(request) + // const { type } = request.params + // if (type === 'plausibleanalytics') { + // return await stopPlausibleAnalyticsService(request) + // } + // if (type === 'nocodb') { + // return await stopNocodbService(request) + // } + // if (type === 'minio') { + // return await stopMinioService(request) + // } + // if (type === 'vscodeserver') { + // return await stopVscodeService(request) + // } + // if (type === 'wordpress') { + // return await stopWordpressService(request) + // } + // if (type === 'vaultwarden') { + // return await stopVaultwardenService(request) + // } + // if (type === 'languagetool') { + // return await stopLanguageToolService(request) + // } + // if (type === 'n8n') { + // return await stopN8nService(request) + // } + // if (type === 'uptimekuma') { + // return await stopUptimekumaService(request) + // } + // if (type === 'ghost') { + // return await stopGhostService(request) + // } + // if (type === 'meilisearch') { + // return await stopMeilisearchService(request) + // } + // if (type === 'umami') { + // return await stopUmamiService(request) + // } + // if (type === 'hasura') { + // return await stopHasuraService(request) + // } + // if (type === 'fider') { + // return await stopFiderService(request) + // } + // if (type === 'moodle') { + // return await stopMoodleService(request) + // } + // throw `Service type ${type} not supported.` } catch (error) { throw { status: 500, message: error?.message || error } } @@ -805,52 +802,25 @@ COPY ./init-db.sh /docker-entrypoint-initdb.d/init-db.sh`; volumes, command: 'sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh db init-admin && /entrypoint.sh run"', - networks: [network], environment: config.plausibleAnalytics.environmentVariables, - restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), depends_on: [`${id}-postgresql`, `${id}-clickhouse`], labels: makeLabelForServices('plausibleAnalytics'), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '10s', - max_attempts: 5, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), }, [`${id}-postgresql`]: { container_name: `${id}-postgresql`, image: config.postgresql.image, - networks: [network], environment: config.postgresql.environmentVariables, volumes: [config.postgresql.volume], - restart: 'always', - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '10s', - max_attempts: 5, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), }, [`${id}-clickhouse`]: { build: workdir, container_name: `${id}-clickhouse`, - networks: [network], environment: config.clickhouse.environmentVariables, volumes: [config.clickhouse.volume], - restart: 'always', - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '10s', - max_attempts: 5, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -870,36 +840,7 @@ COPY ./init-db.sh /docker-entrypoint-initdb.d/init-db.sh`; }; const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} -async function stopPlausibleAnalyticsService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker, fqdn } = service; - if (destinationDockerId) { - const engine = destinationDocker.engine; - - let found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - found = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-postgresql` }); - if (found) { - await removeContainer({ id: `${id}-postgresql`, dockerId: destinationDocker.id }); - } - found = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-clickhouse` }); - if (found) { - await removeContainer({ id: `${id}-clickhouse`, dockerId: destinationDocker.id }); - } - } - + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) @@ -936,20 +877,11 @@ async function startNocodbService(request: FastifyRequest) { [id]: { container_name: id, image: config.image, - networks: [network], volumes, environment: config.environmentVariables, - restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), labels: makeLabelForServices('nocodb'), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -961,25 +893,7 @@ async function startNocodbService(request: FastifyRequest) { }; const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} -async function stopNocodbService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker, fqdn } = service; - if (destinationDockerId) { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) @@ -1036,19 +950,10 @@ async function startMinioService(request: FastifyRequest) { image: config.image, command: `server /data --console-address ":${consolePort}"`, environment: config.environmentVariables, - networks: [network], volumes, - restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), labels: makeLabelForServices('minio'), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -1060,32 +965,13 @@ async function startMinioService(request: FastifyRequest) { }; const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) await prisma.minio.update({ where: { serviceId: id }, data: { publicPort } }); return {} } catch ({ status, message }) { return errorHandler({ status, message }) } } -async function stopMinioService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - await prisma.minio.update({ where: { serviceId: id }, data: { publicPort: null } }) - if (destinationDockerId) { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} async function startVscodeService(request: FastifyRequest) { try { @@ -1130,19 +1016,10 @@ async function startVscodeService(request: FastifyRequest) { container_name: id, image: config.image, environment: config.environmentVariables, - networks: [network], volumes, - restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), labels: makeLabelForServices('vscodeServer'), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -1155,8 +1032,7 @@ async function startVscodeService(request: FastifyRequest) { const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) const changePermissionOn = persistentStorage.map((p) => p.path); if (changePermissionOn.length > 0) { @@ -1171,23 +1047,6 @@ async function startVscodeService(request: FastifyRequest) { return errorHandler({ status, message }) } } -async function stopVscodeService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} async function startWordpressService(request: FastifyRequest) { try { @@ -1195,6 +1054,7 @@ async function startWordpressService(request: FastifyRequest) const teamId = request.user.teamId; const service = await getServiceFromDB({ id, teamId }); const { + arch, type, version, destinationDockerId, @@ -1244,6 +1104,10 @@ async function startWordpressService(request: FastifyRequest) } } }; + if (isARM(arch)) { + config.mysql.image = 'mysql:5.7' + config.mysql.volume = `${id}-mysql-data:/var/lib/mysql` + } if (serviceSecret.length > 0) { serviceSecret.forEach((secret) => { config.wordpress.environmentVariables[secret.name] = secret.value; @@ -1260,18 +1124,9 @@ async function startWordpressService(request: FastifyRequest) image: config.wordpress.image, environment: config.wordpress.environmentVariables, volumes, - networks: [network], - restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), labels: makeLabelForServices('wordpress'), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -1288,16 +1143,7 @@ async function startWordpressService(request: FastifyRequest) image: config.mysql.image, volumes: [config.mysql.volume], environment: config.mysql.environmentVariables, - networks: [network], - restart: 'always', - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), }; composeFile.volumes[config.mysql.volume.split(':')[0]] = { @@ -1307,61 +1153,13 @@ async function startWordpressService(request: FastifyRequest) const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) } } -async function stopWordpressService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { - destinationDockerId, - destinationDocker, - wordpress: { ftpEnabled } - } = service; - if (destinationDockerId) { - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-mysql` }); - if (found) { - await removeContainer({ id: `${id}-mysql`, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - try { - if (ftpEnabled) { - const found = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-ftp` }); - if (found) { - await removeContainer({ id: `${id}-ftp`, dockerId: destinationDocker.id }); - } - await prisma.wordpress.update({ - where: { serviceId: id }, - data: { ftpEnabled: false } - }); - } - } catch (error) { - console.error(error); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} async function startVaultwardenService(request: FastifyRequest) { try { @@ -1395,19 +1193,10 @@ async function startVaultwardenService(request: FastifyRequest container_name: id, image: config.image, environment: config.environmentVariables, - networks: [network], volumes, - restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), labels: makeLabelForServices('vaultWarden'), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -1420,35 +1209,13 @@ async function startVaultwardenService(request: FastifyRequest const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) } } -async function stopVaultwardenService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} async function startLanguageToolService(request: FastifyRequest) { try { @@ -1481,20 +1248,11 @@ async function startLanguageToolService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} async function startN8nService(request: FastifyRequest) { try { @@ -1569,20 +1305,11 @@ async function startN8nService(request: FastifyRequest) { [id]: { container_name: id, image: config.image, - networks: [network], volumes, environment: config.environmentVariables, - restart: 'always', labels: makeLabelForServices('n8n'), ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -1595,35 +1322,13 @@ async function startN8nService(request: FastifyRequest) { const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) } } -async function stopN8nService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} async function startUptimekumaService(request: FastifyRequest) { try { @@ -1655,20 +1360,11 @@ async function startUptimekumaService(request: FastifyRequest) [id]: { container_name: id, image: config.image, - networks: [network], volumes, environment: config.environmentVariables, - restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), labels: makeLabelForServices('uptimekuma'), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -1681,35 +1377,13 @@ async function startUptimekumaService(request: FastifyRequest) const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) } } -async function stopUptimekumaService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} async function startGhostService(request: FastifyRequest) { try { @@ -1784,37 +1458,19 @@ async function startGhostService(request: FastifyRequest) { [id]: { container_name: id, image: config.ghost.image, - networks: [network], volumes, environment: config.ghost.environmentVariables, - restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), labels: makeLabelForServices('ghost'), depends_on: [`${id}-mariadb`], - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), }, [`${id}-mariadb`]: { container_name: `${id}-mariadb`, image: config.mariadb.image, - networks: [network], volumes: [config.mariadb.volume], environment: config.mariadb.environmentVariables, - restart: 'always', - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -1832,39 +1488,13 @@ async function startGhostService(request: FastifyRequest) { const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) } } -async function stopGhostService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - try { - let found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - found = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-mariadb` }); - if (found) { - await removeContainer({ id: `${id}-mariadb`, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} async function startMeilisearchService(request: FastifyRequest) { try { @@ -1902,20 +1532,11 @@ async function startMeilisearchService(request: FastifyRequest [id]: { container_name: id, image: config.image, - networks: [network], environment: config.environmentVariables, - restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), volumes, labels: makeLabelForServices('meilisearch'), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -1927,29 +1548,7 @@ async function startMeilisearchService(request: FastifyRequest }; const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} -async function stopMeilisearchService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - } + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) @@ -2099,36 +1698,18 @@ async function startUmamiService(request: FastifyRequest) { container_name: id, image: config.umami.image, environment: config.umami.environmentVariables, - networks: [network], volumes, - restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), labels: makeLabelForServices('umami'), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - }, - depends_on: [`${id}-postgresql`] + depends_on: [`${id}-postgresql`], + ...defaultServiceComposeConfiguration(network), }, [`${id}-postgresql`]: { build: workdir, container_name: `${id}-postgresql`, environment: config.postgresql.environmentVariables, - networks: [network], volumes: [config.postgresql.volume], - restart: 'always', - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -2145,37 +1726,7 @@ async function startUmamiService(request: FastifyRequest) { }; const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} -async function stopUmamiService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-postgresql` }); - if (found) { - await removeContainer({ id: `${id}-postgresql`, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - } + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) @@ -2234,36 +1785,18 @@ async function startHasuraService(request: FastifyRequest) { container_name: id, image: config.hasura.image, environment: config.hasura.environmentVariables, - networks: [network], volumes, - restart: 'always', labels: makeLabelForServices('hasura'), ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - }, - depends_on: [`${id}-postgresql`] + depends_on: [`${id}-postgresql`], + ...defaultServiceComposeConfiguration(network), }, [`${id}-postgresql`]: { image: config.postgresql.image, container_name: `${id}-postgresql`, environment: config.postgresql.environmentVariables, - networks: [network], volumes: [config.postgresql.volume], - restart: 'always', - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -2281,43 +1814,13 @@ async function startHasuraService(request: FastifyRequest) { const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) } } -async function stopHasuraService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-postgresql` }); - if (found) { - await removeContainer({ id: `${id}-postgresql`, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} async function startFiderService(request: FastifyRequest) { try { @@ -2395,36 +1898,18 @@ async function startFiderService(request: FastifyRequest) { container_name: id, image: config.fider.image, environment: config.fider.environmentVariables, - networks: [network], volumes, - restart: 'always', labels: makeLabelForServices('fider'), ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - }, - depends_on: [`${id}-postgresql`] + depends_on: [`${id}-postgresql`], + ...defaultServiceComposeConfiguration(network), }, [`${id}-postgresql`]: { image: config.postgresql.image, container_name: `${id}-postgresql`, environment: config.postgresql.environmentVariables, - networks: [network], volumes: [config.postgresql.volume], - restart: 'always', - deploy: { - restart_policy: { - condition: 'on-failure', - delay: '5s', - max_attempts: 3, - window: '120s' - } - } + ...defaultServiceComposeConfiguration(network), } }, networks: { @@ -2442,43 +1927,14 @@ async function startFiderService(request: FastifyRequest) { const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) } } -async function stopFiderService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-postgresql` }); - if (found) { - await removeContainer({ id: `${id}-postgresql`, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} + async function startAppWriteService(request: FastifyRequest) { try { const { id } = request.params; @@ -2486,7 +1942,7 @@ async function startAppWriteService(request: FastifyRequest) { const { version, fqdn, destinationDocker, secrets, exposePort, network, port, workdir, image, appwrite } = await defaultServiceConfigurations({ id, teamId }) let isStatsEnabled = false - if (secrets._APP_USAGE_STATS) { + if (secrets.find(s => s === '_APP_USAGE_STATS=enabled')) { isStatsEnabled = true } const { @@ -2503,7 +1959,6 @@ async function startAppWriteService(request: FastifyRequest) { const dockerCompose = { [id]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: id, labels: makeLabelForServices('appwrite'), @@ -2533,16 +1988,16 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_DB_USER=${mariadbUser}`, `_APP_DB_PASS=${mariadbPassword}`, `_APP_INFLUXDB_HOST=${id}-influxdb`, - "_APP_INFLUXDB_PORT=8806", + "_APP_INFLUXDB_PORT=8086", `_APP_EXECUTOR_SECRET=${executorSecret}`, `_APP_EXECUTOR_HOST=http://${id}-executor/v1`, `_APP_STATSD_HOST=${id}-telegraf`, "_APP_STATSD_PORT=8125", ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-realtime`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-realtime`, entrypoint: "realtime", @@ -2562,10 +2017,11 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_DB_USER=${mariadbUser}`, `_APP_DB_PASS=${mariadbPassword}`, ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-worker-audits`]: { - ...defaultServiceComposeConfiguration(network), + image: `${image}:${version}`, container_name: `${id}-worker-audits`, labels: makeLabelForServices('appwrite'), @@ -2585,10 +2041,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_DB_USER=${mariadbUser}`, `_APP_DB_PASS=${mariadbPassword}`, ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-worker-webhooks`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-worker-webhooks`, labels: makeLabelForServices('appwrite'), @@ -2603,10 +2059,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_REDIS_HOST=${id}-redis`, "_APP_REDIS_PORT=6379", ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-worker-deletes`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-worker-deletes`, labels: makeLabelForServices('appwrite'), @@ -2636,10 +2092,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_EXECUTOR_SECRET=${executorSecret}`, `_APP_EXECUTOR_HOST=http://${id}-executor/v1`, ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-worker-databases`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-worker-databases`, labels: makeLabelForServices('appwrite'), @@ -2659,10 +2115,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_DB_USER=${mariadbUser}`, `_APP_DB_PASS=${mariadbPassword}`, ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-worker-builds`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-worker-builds`, labels: makeLabelForServices('appwrite'), @@ -2684,10 +2140,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_DB_USER=${mariadbUser}`, `_APP_DB_PASS=${mariadbPassword}`, ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-worker-certificates`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-worker-certificates`, labels: makeLabelForServices('appwrite'), @@ -2713,10 +2169,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_DB_USER=${mariadbUser}`, `_APP_DB_PASS=${mariadbPassword}`, ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-worker-functions`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-worker-functions`, labels: makeLabelForServices('appwrite'), @@ -2739,10 +2195,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_EXECUTOR_SECRET=${executorSecret}`, `_APP_EXECUTOR_HOST=http://${id}-executor/v1`, ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-executor`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-executor`, labels: makeLabelForServices('appwrite'), @@ -2763,10 +2219,10 @@ async function startAppWriteService(request: FastifyRequest) { "_APP_ENV=production", `_APP_EXECUTOR_SECRET=${executorSecret}`, ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-worker-mails`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-worker-mails`, labels: makeLabelForServices('appwrite'), @@ -2780,10 +2236,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_REDIS_HOST=${id}-redis`, "_APP_REDIS_PORT=6379", ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-worker-messaging`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-worker-messaging`, labels: makeLabelForServices('appwrite'), @@ -2796,10 +2252,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_REDIS_HOST=${id}-redis`, "_APP_REDIS_PORT=6379", ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-maintenance`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-maintenance`, labels: makeLabelForServices('appwrite'), @@ -2820,10 +2276,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_DB_USER=${mariadbUser}`, `_APP_DB_PASS=${mariadbPassword}`, ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-schedule`]: { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-schedule`, labels: makeLabelForServices('appwrite'), @@ -2836,10 +2292,10 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_REDIS_HOST=${id}-redis`, "_APP_REDIS_PORT=6379", ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), }, [`${id}-mariadb`]: { - ...defaultServiceComposeConfiguration(network), "image": "mariadb:10.7", container_name: `${id}-mariadb`, labels: makeLabelForServices('appwrite'), @@ -2853,23 +2309,23 @@ async function startAppWriteService(request: FastifyRequest) { `MYSQL_PASSWORD=${mariadbPassword}`, `MYSQL_DATABASE=${mariadbDatabase}` ], - "command": "mysqld --innodb-flush-method=fsync" + "command": "mysqld --innodb-flush-method=fsync", + ...defaultServiceComposeConfiguration(network), }, [`${id}-redis`]: { - ...defaultServiceComposeConfiguration(network), "image": "redis:6.2-alpine", container_name: `${id}-redis`, "command": `redis-server --maxmemory 512mb --maxmemory-policy allkeys-lru --maxmemory-samples 5\n`, "volumes": [ `${id}-redis:/data:rw` - ] + ], + ...defaultServiceComposeConfiguration(network), }, }; if (isStatsEnabled) { - dockerCompose.id.depends_on.push(`${id}-influxdb`); + dockerCompose[id].depends_on.push(`${id}-influxdb`); dockerCompose[`${id}-usage`] = { - ...defaultServiceComposeConfiguration(network), image: `${image}:${version}`, container_name: `${id}-usage`, labels: makeLabelForServices('appwrite'), @@ -2887,28 +2343,29 @@ async function startAppWriteService(request: FastifyRequest) { `_APP_DB_USER=${mariadbUser}`, `_APP_DB_PASS=${mariadbPassword}`, `_APP_INFLUXDB_HOST=${id}-influxdb`, - "_APP_INFLUXDB_PORT=8806", + "_APP_INFLUXDB_PORT=8086", `_APP_REDIS_HOST=${id}-redis`, "_APP_REDIS_PORT=6379", ...secrets - ] + ], + ...defaultServiceComposeConfiguration(network), } dockerCompose[`${id}-influxdb`] = { - ...defaultServiceComposeConfiguration(network), "image": "appwrite/influxdb:1.5.0", container_name: `${id}-influxdb`, "volumes": [ `${id}-influxdb:/var/lib/influxdb:rw` - ] + ], + ...defaultServiceComposeConfiguration(network), } dockerCompose[`${id}-telegraf`] = { - ...defaultServiceComposeConfiguration(network), "image": "appwrite/telegraf:1.4.0", container_name: `${id}-telegraf`, "environment": [ `_APP_INFLUXDB_HOST=${id}-influxdb`, - "_APP_INFLUXDB_PORT=8806", - ] + "_APP_INFLUXDB_PORT=8086", + ], + ...defaultServiceComposeConfiguration(network), } } @@ -2954,32 +2411,37 @@ async function startAppWriteService(request: FastifyRequest) { const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) } } -async function stopAppWriteService(request: FastifyRequest) { +async function startServiceContainers(dockerId, composeFileDestination) { + await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} pull` }) + await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} create` }) + await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} start` }) + await asyncSleep(1000); + await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} up -d` }) +} +async function stopServiceContainers(request: FastifyRequest) { try { - // TODO: Fix async for of const { id } = request.params; const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - const containers = [`${id}-mariadb`, `${id}-redis`, `${id}-influxdb`, `${id}-telegraf`, id, `${id}-realtime`, `${id}-worker-audits`, `${id}worker-webhooks`, `${id}-worker-deletes`, `${id}-worker-databases`, `${id}-worker-builds`, `${id}-worker-certificates`, `${id}-worker-functions`, `${id}-worker-mails`, `${id}-worker-messaging`, `${id}-maintenance`, `${id}-schedule`, `${id}-executor`, `${id}-usage`] + const { destinationDockerId } = await getServiceFromDB({ id, teamId }); if (destinationDockerId) { - for (const container of containers) { - const found = await checkContainer({ dockerId: destinationDocker.id, container }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - - } + await executeDockerCmd({ + dockerId: destinationDockerId, + command: `docker ps -a --filter 'label=com.docker.compose.project=${id}' --format {{.ID}}|xargs -n 1 docker stop -t 0` + }) + await executeDockerCmd({ + dockerId: destinationDockerId, + command: `docker ps -a --filter 'label=com.docker.compose.project=${id}' --format {{.ID}}|xargs -n 1 docker rm --force` + }) + return {} } - return {} + throw { status: 500, message: 'Could not stop containers.' } } catch ({ status, message }) { return errorHandler({ status, message }) } @@ -3104,44 +2566,13 @@ async function startMoodleService(request: FastifyRequest) { const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} pull` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose -f ${composeFileDestination} up --build -d` }) + await startServiceContainers(destinationDocker.id, composeFileDestination) return {} } catch ({ status, message }) { return errorHandler({ status, message }) } } -async function stopMoodleService(request: FastifyRequest) { - try { - const { id } = request.params; - const teamId = request.user.teamId; - const service = await getServiceFromDB({ id, teamId }); - const { destinationDockerId, destinationDocker } = service; - if (destinationDockerId) { - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: id }); - if (found) { - await removeContainer({ id, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - try { - const found = await checkContainer({ dockerId: destinationDocker.id, container: `${id}-mariadb` }); - if (found) { - await removeContainer({ id: `${id}-mariadb`, dockerId: destinationDocker.id }); - } - } catch (error) { - console.error(error); - } - } - return {} - } catch ({ status, message }) { - return errorHandler({ status, message }) - } -} - export async function activatePlausibleUsers(request: FastifyRequest, reply: FastifyReply) { try { diff --git a/apps/ui/src/lib/components/svg/services/Appwrite.svelte b/apps/ui/src/lib/components/svg/services/Appwrite.svelte new file mode 100644 index 000000000..9a774d0d3 --- /dev/null +++ b/apps/ui/src/lib/components/svg/services/Appwrite.svelte @@ -0,0 +1,21 @@ + + + + + + diff --git a/apps/ui/src/lib/components/svg/services/ServiceIcons.svelte b/apps/ui/src/lib/components/svg/services/ServiceIcons.svelte index 00e1bcf6e..c5f537736 100644 --- a/apps/ui/src/lib/components/svg/services/ServiceIcons.svelte +++ b/apps/ui/src/lib/components/svg/services/ServiceIcons.svelte @@ -32,6 +32,8 @@ {:else if type === 'fider'} +{:else if type === 'appwrite'} + {:else if type === 'moodle'} {/if} diff --git a/apps/ui/src/lib/components/svg/services/index.ts b/apps/ui/src/lib/components/svg/services/index.ts index e4f5bc749..1e47a5def 100644 --- a/apps/ui/src/lib/components/svg/services/index.ts +++ b/apps/ui/src/lib/components/svg/services/index.ts @@ -1,18 +1,18 @@ //@ts-nocheck export { default as PlausibleAnalytics } from './PlausibleAnalytics.svelte'; -export { default as NocoDb } from './NocoDB.svelte'; -export { default as MinIo } from './MinIO.svelte'; -export { default as VsCodeServer } from './VSCodeServer.svelte'; -export { default as Wordpress } from './Wordpress.svelte'; -export { default as VaultWarden } from './VaultWarden.svelte'; -export { default as LanguageTool } from './LanguageTool.svelte'; -export { default as N8n } from './N8n.svelte'; -export { default as UptimeKuma } from './UptimeKuma.svelte'; -export { default as Ghost } from './Ghost.svelte'; -export { default as MeiliSearch } from './MeiliSearch.svelte'; -export { default as Umami } from './Umami.svelte'; -export { default as Hasura } from './Hasura.svelte'; -export { default as Fider } from './Fider.svelte'; -export { default as Appwrite } from './Moodle.svelte'; -export { default as Moodle } from './Moodle.svelte'; +export { default as NocoDb } from './NocoDB.svelte'; +export { default as MinIo } from './MinIO.svelte'; +export { default as VsCodeServer } from './VSCodeServer.svelte'; +export { default as Wordpress } from './Wordpress.svelte'; +export { default as VaultWarden } from './VaultWarden.svelte'; +export { default as LanguageTool } from './LanguageTool.svelte'; +export { default as N8n } from './N8n.svelte'; +export { default as UptimeKuma } from './UptimeKuma.svelte'; +export { default as Ghost } from './Ghost.svelte'; +export { default as MeiliSearch } from './MeiliSearch.svelte'; +export { default as Umami } from './Umami.svelte'; +export { default as Hasura } from './Hasura.svelte'; +export { default as Fider } from './Fider.svelte'; +export { default as Appwrite } from './Appwrite.svelte'; +export { default as Moodle } from './Moodle.svelte'; diff --git a/apps/ui/src/routes/services/[id]/_ServiceLinks.svelte b/apps/ui/src/routes/services/[id]/_ServiceLinks.svelte index cad074ee5..9303a0fb2 100644 --- a/apps/ui/src/routes/services/[id]/_ServiceLinks.svelte +++ b/apps/ui/src/routes/services/[id]/_ServiceLinks.svelte @@ -55,7 +55,7 @@ -{:else if service.type === 'appwrote'} +{:else if service.type === 'appwrite'} diff --git a/apps/ui/src/routes/services/[id]/_Services/_Wordpress.svelte b/apps/ui/src/routes/services/[id]/_Services/_Wordpress.svelte index 61368c983..4d72fafd2 100644 --- a/apps/ui/src/routes/services/[id]/_Services/_Wordpress.svelte +++ b/apps/ui/src/routes/services/[id]/_Services/_Wordpress.svelte @@ -22,7 +22,7 @@ function generateUrl(publicPort: any) { return browser ? `sftp://${ - settings.fqdn ? getDomain(settings.fqdn) : window.location.hostname + settings?.fqdn ? getDomain(settings.fqdn) : window.location.hostname }:${publicPort}` : 'Loading...'; }