diff --git a/prisma/migrations/20220510081125_custom_wordpress_db/migration.sql b/prisma/migrations/20220510081125_custom_wordpress_db/migration.sql new file mode 100644 index 000000000..5a1cd301c --- /dev/null +++ b/prisma/migrations/20220510081125_custom_wordpress_db/migration.sql @@ -0,0 +1,32 @@ +-- RedefineTables +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_Wordpress" ( + "id" TEXT NOT NULL PRIMARY KEY, + "extraConfig" TEXT, + "tablePrefix" TEXT, + "ownMysql" BOOLEAN NOT NULL DEFAULT false, + "mysqlHost" TEXT, + "mysqlPort" INTEGER, + "mysqlUser" TEXT NOT NULL, + "mysqlPassword" TEXT NOT NULL, + "mysqlRootUser" TEXT NOT NULL, + "mysqlRootUserPassword" TEXT NOT NULL, + "mysqlDatabase" TEXT, + "mysqlPublicPort" INTEGER, + "ftpEnabled" BOOLEAN NOT NULL DEFAULT false, + "ftpUser" TEXT, + "ftpPassword" TEXT, + "ftpPublicPort" INTEGER, + "ftpHostKey" TEXT, + "ftpHostKeyPrivate" TEXT, + "serviceId" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + CONSTRAINT "Wordpress_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); +INSERT INTO "new_Wordpress" ("createdAt", "extraConfig", "ftpEnabled", "ftpHostKey", "ftpHostKeyPrivate", "ftpPassword", "ftpPublicPort", "ftpUser", "id", "mysqlDatabase", "mysqlPassword", "mysqlPublicPort", "mysqlRootUser", "mysqlRootUserPassword", "mysqlUser", "serviceId", "tablePrefix", "updatedAt") SELECT "createdAt", "extraConfig", "ftpEnabled", "ftpHostKey", "ftpHostKeyPrivate", "ftpPassword", "ftpPublicPort", "ftpUser", "id", "mysqlDatabase", "mysqlPassword", "mysqlPublicPort", "mysqlRootUser", "mysqlRootUserPassword", "mysqlUser", "serviceId", "tablePrefix", "updatedAt" FROM "Wordpress"; +DROP TABLE "Wordpress"; +ALTER TABLE "new_Wordpress" RENAME TO "Wordpress"; +CREATE UNIQUE INDEX "Wordpress_serviceId_key" ON "Wordpress"("serviceId"); +PRAGMA foreign_key_check; +PRAGMA foreign_keys=ON; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 77fd59d4c..b0c2e233a 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -353,6 +353,9 @@ model Wordpress { id String @id @default(cuid()) extraConfig String? tablePrefix String? + ownMysql Boolean @default(false) + mysqlHost String? + mysqlPort Int? mysqlUser String mysqlPassword String mysqlRootUser String diff --git a/src/lib/components/svg/services/PlausibleAnalytics.svelte b/src/lib/components/svg/services/PlausibleAnalytics.svelte index 9ae5774fc..c02a9e6d9 100644 --- a/src/lib/components/svg/services/PlausibleAnalytics.svelte +++ b/src/lib/components/svg/services/PlausibleAnalytics.svelte @@ -4,6 +4,6 @@ plausible logo diff --git a/src/lib/database/common.ts b/src/lib/database/common.ts index c6293e76f..53551882b 100644 --- a/src/lib/database/common.ts +++ b/src/lib/database/common.ts @@ -28,7 +28,7 @@ if (!dev) { } export const prisma = new PrismaClient({ - errorFormat: 'pretty', + errorFormat: 'minimal', rejectOnNotFound: false }); diff --git a/src/lib/database/services.ts b/src/lib/database/services.ts index cc2ab5152..a1fb7f2de 100644 --- a/src/lib/database/services.ts +++ b/src/lib/database/services.ts @@ -419,7 +419,9 @@ export async function updateWordpress({ name, exposePort, mysqlDatabase, - extraConfig + extraConfig, + mysqlHost, + mysqlPort }: { id: string; fqdn: string; @@ -427,10 +429,24 @@ export async function updateWordpress({ exposePort?: number; mysqlDatabase: string; extraConfig: string; + mysqlHost?: string; + mysqlPort?: number; }): Promise { return await prisma.service.update({ where: { id }, - data: { fqdn, name, exposePort, wordpress: { update: { mysqlDatabase, extraConfig } } } + data: { + fqdn, + name, + exposePort, + wordpress: { + update: { + mysqlDatabase, + extraConfig, + mysqlHost, + mysqlPort + } + } + } }); } diff --git a/src/routes/applications/index.svelte b/src/routes/applications/index.svelte index 07e4564c5..a14e6fd5c 100644 --- a/src/routes/applications/index.svelte +++ b/src/routes/applications/index.svelte @@ -60,7 +60,7 @@ {/if} -
+
{#if !applications || ownApplications.length === 0}
{$t('application.no_applications_found')}
diff --git a/src/routes/databases/index.svelte b/src/routes/databases/index.svelte index ec6b86291..94520ba0d 100644 --- a/src/routes/databases/index.svelte +++ b/src/routes/databases/index.svelte @@ -47,7 +47,7 @@
-
+
{#if !databases || ownDatabases.length === 0}
{$t('database.no_databases_found')}
diff --git a/src/routes/destinations/[id]/index.svelte b/src/routes/destinations/[id]/index.svelte index 1effefdd7..dabc3c88f 100644 --- a/src/routes/destinations/[id]/index.svelte +++ b/src/routes/destinations/[id]/index.svelte @@ -39,10 +39,13 @@ import { t } from '$lib/translations'; -
-
{$t('application.destination')}
- > - {destination.name} +
+
+
+ Configuration +
+ {destination.name} +
diff --git a/src/routes/index.svelte b/src/routes/index.svelte index b3a60529a..43974835c 100644 --- a/src/routes/index.svelte +++ b/src/routes/index.svelte @@ -141,21 +141,21 @@
Server Usage
-
+
Total Memory
{(usage?.memory.totalMemMb).toFixed(0)}
-
+
Used Memory
{(usage?.memory.usedMemMb).toFixed(0)}
-
+
Free Memory
{usage?.memory.freeMemPercentage}% @@ -166,19 +166,19 @@
-
+
Total CPUs
{usage?.cpu.count}
-
+
Load Average (5/10/30mins)
{usage?.cpu.load.join('/')}
-
+
CPU Usage
{usage?.cpu.usage}% @@ -189,19 +189,19 @@
-
+
Total Disk
{usage?.disk.totalGb}GB
-
+
Used Disk
{usage?.disk.usedGb}GB
-
+ - diff --git a/src/routes/services/[id]/_Services/_Wordpress.svelte b/src/routes/services/[id]/_Services/_Wordpress.svelte index 601843534..7dd62c946 100644 --- a/src/routes/services/[id]/_Services/_Wordpress.svelte +++ b/src/routes/services/[id]/_Services/_Wordpress.svelte @@ -18,6 +18,7 @@ let ftpUser = service.wordpress.ftpUser; let ftpPassword = service.wordpress.ftpPassword; let ftpLoading = false; + let ownMysql = service.wordpress.ownMysql; function generateUrl(publicPort) { return browser @@ -40,7 +41,7 @@ publicPort, ftpUser: user, ftpPassword: password - } = await post(`/services/${id}/wordpress/settings.json`, { + } = await post(`/services/${id}/wordpress/ftp.json`, { ftpEnabled }); ftpUrl = generateUrl(publicPort); @@ -52,6 +53,18 @@ } finally { ftpLoading = false; } + } else { + try { + if (name === 'ownMysql') { + ownMysql = !ownMysql; + } + await post(`/services/${id}/wordpress/settings.json`, { + ownMysql + }); + service.wordpress.ownMysql = ownMysql; + } catch ({ error }) { + return errorNotification(error); + } } } @@ -106,51 +119,95 @@ define('SUBDOMAIN_INSTALL', false);`
MySQL
+
+ !isRunning && changeSettings('ownMysql')} + title="Use your own MySQL server" + description="Enables the use of your own MySQL server. If you don't have one, you can use the one provided by Coolify." + /> +
+{#if service.wordpress.ownMysql} +
+ + +
+
+ + +
+{/if}
-
- - -
-
- - -
+{#if !service.wordpress.ownMysql} +
+ + +
+
+ + +
+{/if}
- +
diff --git a/src/routes/services/[id]/wordpress/ftp.json.ts b/src/routes/services/[id]/wordpress/ftp.json.ts new file mode 100644 index 000000000..cee85bc41 --- /dev/null +++ b/src/routes/services/[id]/wordpress/ftp.json.ts @@ -0,0 +1,185 @@ +import { dev } from '$app/env'; +import { asyncExecShell, getEngine, getUserDetails } from '$lib/common'; +import { decrypt, encrypt } from '$lib/crypto'; +import * as db from '$lib/database'; +import { ErrorHandler, generatePassword, getFreePort } from '$lib/database'; +import { checkContainer, startTcpProxy, stopTcpHttpProxy } from '$lib/haproxy'; +import type { ComposeFile } from '$lib/types/composeFile'; +import type { RequestHandler } from '@sveltejs/kit'; +import cuid from 'cuid'; +import fs from 'fs/promises'; +import yaml from 'js-yaml'; + +export const post: RequestHandler = async (event) => { + const { status, body, teamId } = await getUserDetails(event); + if (status === 401) return { status, body }; + + const { id } = event.params; + + const { ftpEnabled } = await event.request.json(); + const publicPort = await getFreePort(); + + let ftpUser = cuid(); + let ftpPassword = generatePassword(); + + const hostkeyDir = dev ? '/tmp/hostkeys' : '/app/ssl/hostkeys'; + try { + const data = await db.prisma.wordpress.update({ + where: { serviceId: id }, + data: { ftpEnabled }, + include: { service: { include: { destinationDocker: true } } } + }); + const { + service: { destinationDockerId, destinationDocker }, + ftpPublicPort: oldPublicPort, + ftpUser: user, + ftpPassword: savedPassword, + ftpHostKey, + ftpHostKeyPrivate + } = data; + if (user) ftpUser = user; + if (savedPassword) ftpPassword = decrypt(savedPassword); + + const { stdout: password } = await asyncExecShell( + `echo ${ftpPassword} | openssl passwd -1 -stdin` + ); + if (destinationDockerId) { + try { + await fs.stat(hostkeyDir); + } catch (error) { + await asyncExecShell(`mkdir -p ${hostkeyDir}`); + } + if (!ftpHostKey) { + await asyncExecShell( + `ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N "" -q -f ${hostkeyDir}/${id}.ed25519` + ); + const { stdout: ftpHostKey } = await asyncExecShell(`cat ${hostkeyDir}/${id}.ed25519`); + await db.prisma.wordpress.update({ + where: { serviceId: id }, + data: { ftpHostKey: encrypt(ftpHostKey) } + }); + } else { + await asyncExecShell(`echo "${decrypt(ftpHostKey)}" > ${hostkeyDir}/${id}.ed25519`); + } + if (!ftpHostKeyPrivate) { + await asyncExecShell(`ssh-keygen -t rsa -b 4096 -N "" -f ${hostkeyDir}/${id}.rsa`); + const { stdout: ftpHostKeyPrivate } = await asyncExecShell(`cat ${hostkeyDir}/${id}.rsa`); + await db.prisma.wordpress.update({ + where: { serviceId: id }, + data: { ftpHostKeyPrivate: encrypt(ftpHostKeyPrivate) } + }); + } else { + await asyncExecShell(`echo "${decrypt(ftpHostKeyPrivate)}" > ${hostkeyDir}/${id}.rsa`); + } + const { network, engine } = destinationDocker; + const host = getEngine(engine); + if (ftpEnabled) { + await db.prisma.wordpress.update({ + where: { serviceId: id }, + data: { + ftpPublicPort: publicPort, + ftpUser: user ? undefined : ftpUser, + ftpPassword: savedPassword ? undefined : encrypt(ftpPassword) + } + }); + + try { + const isRunning = await checkContainer(engine, `${id}-ftp`); + if (isRunning) { + await asyncExecShell( + `DOCKER_HOST=${host} docker stop -t 0 ${id}-ftp && docker rm ${id}-ftp` + ); + } + } catch (error) { + console.log(error); + // + } + const volumes = [ + `${id}-wordpress-data:/home/${ftpUser}`, + `${ + dev ? hostkeyDir : '/var/lib/docker/volumes/coolify-ssl-certs/_data/hostkeys' + }/${id}.ed25519:/etc/ssh/ssh_host_ed25519_key`, + `${ + dev ? hostkeyDir : '/var/lib/docker/volumes/coolify-ssl-certs/_data/hostkeys' + }/${id}.rsa:/etc/ssh/ssh_host_rsa_key`, + `${ + dev ? hostkeyDir : '/var/lib/docker/volumes/coolify-ssl-certs/_data/hostkeys' + }/${id}.sh:/etc/sftp.d/chmod.sh` + ]; + + const compose: ComposeFile = { + version: '3.8', + services: { + [`${id}-ftp`]: { + image: `atmoz/sftp:alpine`, + command: `'${ftpUser}:${password.replace('\n', '').replace(/\$/g, '$$$')}:e:33'`, + extra_hosts: ['host.docker.internal:host-gateway'], + container_name: `${id}-ftp`, + volumes, + networks: [network], + depends_on: [], + restart: 'always' + } + }, + networks: { + [network]: { + external: true + } + }, + volumes: { + [`${id}-wordpress-data`]: { + external: true, + name: `${id}-wordpress-data` + } + } + }; + await fs.writeFile( + `${hostkeyDir}/${id}.sh`, + `#!/bin/bash\nchmod 600 /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key` + ); + await asyncExecShell(`chmod +x ${hostkeyDir}/${id}.sh`); + await fs.writeFile(`${hostkeyDir}/${id}-docker-compose.yml`, yaml.dump(compose)); + await asyncExecShell( + `DOCKER_HOST=${host} docker compose -f ${hostkeyDir}/${id}-docker-compose.yml up -d` + ); + + await startTcpProxy(destinationDocker, `${id}-ftp`, publicPort, 22); + } else { + await db.prisma.wordpress.update({ + where: { serviceId: id }, + data: { ftpPublicPort: null } + }); + try { + await asyncExecShell( + `DOCKER_HOST=${host} docker stop -t 0 ${id}-ftp && docker rm ${id}-ftp` + ); + } catch (error) { + // + } + await stopTcpHttpProxy(destinationDocker, oldPublicPort); + } + } + if (ftpEnabled) { + return { + status: 201, + body: { + publicPort, + ftpUser, + ftpPassword + } + }; + } else { + return { + status: 200, + body: {} + }; + } + } catch (error) { + console.log(error); + return ErrorHandler(error); + } finally { + await asyncExecShell( + `rm -f ${hostkeyDir}/${id}-docker-compose.yml ${hostkeyDir}/${id}.ed25519 ${hostkeyDir}/${id}.ed25519.pub ${hostkeyDir}/${id}.rsa ${hostkeyDir}/${id}.rsa.pub ${hostkeyDir}/${id}.sh` + ); + } +}; diff --git a/src/routes/services/[id]/wordpress/index.json.ts b/src/routes/services/[id]/wordpress/index.json.ts index c76cd1a92..a35270009 100644 --- a/src/routes/services/[id]/wordpress/index.json.ts +++ b/src/routes/services/[id]/wordpress/index.json.ts @@ -12,13 +12,24 @@ export const post: RequestHandler = async (event) => { name, fqdn, exposePort, - wordpress: { extraConfig, mysqlDatabase } + wordpress: { extraConfig, mysqlDatabase, mysqlHost, mysqlPort } } = await event.request.json(); + if (fqdn) fqdn = fqdn.toLowerCase(); if (exposePort) exposePort = Number(exposePort); + if (mysqlPort) mysqlPort = Number(mysqlPort); try { - await db.updateWordpress({ id, fqdn, name, extraConfig, mysqlDatabase, exposePort }); + await db.updateWordpress({ + id, + fqdn, + name, + extraConfig, + mysqlDatabase, + exposePort, + mysqlHost, + mysqlPort + }); return { status: 201 }; } catch (error) { return ErrorHandler(error); diff --git a/src/routes/services/[id]/wordpress/settings.json.ts b/src/routes/services/[id]/wordpress/settings.json.ts index cee85bc41..4848dd220 100644 --- a/src/routes/services/[id]/wordpress/settings.json.ts +++ b/src/routes/services/[id]/wordpress/settings.json.ts @@ -16,170 +16,17 @@ export const post: RequestHandler = async (event) => { const { id } = event.params; - const { ftpEnabled } = await event.request.json(); - const publicPort = await getFreePort(); - - let ftpUser = cuid(); - let ftpPassword = generatePassword(); - - const hostkeyDir = dev ? '/tmp/hostkeys' : '/app/ssl/hostkeys'; + const { ownMysql } = await event.request.json(); try { - const data = await db.prisma.wordpress.update({ + await db.prisma.wordpress.update({ where: { serviceId: id }, - data: { ftpEnabled }, - include: { service: { include: { destinationDocker: true } } } + data: { ownMysql } }); - const { - service: { destinationDockerId, destinationDocker }, - ftpPublicPort: oldPublicPort, - ftpUser: user, - ftpPassword: savedPassword, - ftpHostKey, - ftpHostKeyPrivate - } = data; - if (user) ftpUser = user; - if (savedPassword) ftpPassword = decrypt(savedPassword); - - const { stdout: password } = await asyncExecShell( - `echo ${ftpPassword} | openssl passwd -1 -stdin` - ); - if (destinationDockerId) { - try { - await fs.stat(hostkeyDir); - } catch (error) { - await asyncExecShell(`mkdir -p ${hostkeyDir}`); - } - if (!ftpHostKey) { - await asyncExecShell( - `ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N "" -q -f ${hostkeyDir}/${id}.ed25519` - ); - const { stdout: ftpHostKey } = await asyncExecShell(`cat ${hostkeyDir}/${id}.ed25519`); - await db.prisma.wordpress.update({ - where: { serviceId: id }, - data: { ftpHostKey: encrypt(ftpHostKey) } - }); - } else { - await asyncExecShell(`echo "${decrypt(ftpHostKey)}" > ${hostkeyDir}/${id}.ed25519`); - } - if (!ftpHostKeyPrivate) { - await asyncExecShell(`ssh-keygen -t rsa -b 4096 -N "" -f ${hostkeyDir}/${id}.rsa`); - const { stdout: ftpHostKeyPrivate } = await asyncExecShell(`cat ${hostkeyDir}/${id}.rsa`); - await db.prisma.wordpress.update({ - where: { serviceId: id }, - data: { ftpHostKeyPrivate: encrypt(ftpHostKeyPrivate) } - }); - } else { - await asyncExecShell(`echo "${decrypt(ftpHostKeyPrivate)}" > ${hostkeyDir}/${id}.rsa`); - } - const { network, engine } = destinationDocker; - const host = getEngine(engine); - if (ftpEnabled) { - await db.prisma.wordpress.update({ - where: { serviceId: id }, - data: { - ftpPublicPort: publicPort, - ftpUser: user ? undefined : ftpUser, - ftpPassword: savedPassword ? undefined : encrypt(ftpPassword) - } - }); - - try { - const isRunning = await checkContainer(engine, `${id}-ftp`); - if (isRunning) { - await asyncExecShell( - `DOCKER_HOST=${host} docker stop -t 0 ${id}-ftp && docker rm ${id}-ftp` - ); - } - } catch (error) { - console.log(error); - // - } - const volumes = [ - `${id}-wordpress-data:/home/${ftpUser}`, - `${ - dev ? hostkeyDir : '/var/lib/docker/volumes/coolify-ssl-certs/_data/hostkeys' - }/${id}.ed25519:/etc/ssh/ssh_host_ed25519_key`, - `${ - dev ? hostkeyDir : '/var/lib/docker/volumes/coolify-ssl-certs/_data/hostkeys' - }/${id}.rsa:/etc/ssh/ssh_host_rsa_key`, - `${ - dev ? hostkeyDir : '/var/lib/docker/volumes/coolify-ssl-certs/_data/hostkeys' - }/${id}.sh:/etc/sftp.d/chmod.sh` - ]; - - const compose: ComposeFile = { - version: '3.8', - services: { - [`${id}-ftp`]: { - image: `atmoz/sftp:alpine`, - command: `'${ftpUser}:${password.replace('\n', '').replace(/\$/g, '$$$')}:e:33'`, - extra_hosts: ['host.docker.internal:host-gateway'], - container_name: `${id}-ftp`, - volumes, - networks: [network], - depends_on: [], - restart: 'always' - } - }, - networks: { - [network]: { - external: true - } - }, - volumes: { - [`${id}-wordpress-data`]: { - external: true, - name: `${id}-wordpress-data` - } - } - }; - await fs.writeFile( - `${hostkeyDir}/${id}.sh`, - `#!/bin/bash\nchmod 600 /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key` - ); - await asyncExecShell(`chmod +x ${hostkeyDir}/${id}.sh`); - await fs.writeFile(`${hostkeyDir}/${id}-docker-compose.yml`, yaml.dump(compose)); - await asyncExecShell( - `DOCKER_HOST=${host} docker compose -f ${hostkeyDir}/${id}-docker-compose.yml up -d` - ); - - await startTcpProxy(destinationDocker, `${id}-ftp`, publicPort, 22); - } else { - await db.prisma.wordpress.update({ - where: { serviceId: id }, - data: { ftpPublicPort: null } - }); - try { - await asyncExecShell( - `DOCKER_HOST=${host} docker stop -t 0 ${id}-ftp && docker rm ${id}-ftp` - ); - } catch (error) { - // - } - await stopTcpHttpProxy(destinationDocker, oldPublicPort); - } - } - if (ftpEnabled) { - return { - status: 201, - body: { - publicPort, - ftpUser, - ftpPassword - } - }; - } else { - return { - status: 200, - body: {} - }; - } + return { + status: 201 + }; } catch (error) { console.log(error); return ErrorHandler(error); - } finally { - await asyncExecShell( - `rm -f ${hostkeyDir}/${id}-docker-compose.yml ${hostkeyDir}/${id}.ed25519 ${hostkeyDir}/${id}.ed25519.pub ${hostkeyDir}/${id}.rsa ${hostkeyDir}/${id}.rsa.pub ${hostkeyDir}/${id}.sh` - ); } }; diff --git a/src/routes/services/[id]/wordpress/start.json.ts b/src/routes/services/[id]/wordpress/start.json.ts index df16d16bc..8375c06d0 100644 --- a/src/routes/services/[id]/wordpress/start.json.ts +++ b/src/routes/services/[id]/wordpress/start.json.ts @@ -26,11 +26,14 @@ export const post: RequestHandler = async (event) => { exposePort, wordpress: { mysqlDatabase, + mysqlHost, + mysqlPort, mysqlUser, mysqlPassword, extraConfig, mysqlRootUser, - mysqlRootUserPassword + mysqlRootUserPassword, + ownMysql } } = service; @@ -45,7 +48,7 @@ export const post: RequestHandler = async (event) => { image: `${image}:${version}`, volume: `${id}-wordpress-data:/var/www/html`, environmentVariables: { - WORDPRESS_DB_HOST: `${id}-mysql`, + WORDPRESS_DB_HOST: ownMysql ? `${mysqlHost}:${mysqlPort}` : `${id}-mysql`, WORDPRESS_DB_USER: mysqlUser, WORDPRESS_DB_PASSWORD: mysqlPassword, WORDPRESS_DB_NAME: mysqlDatabase, @@ -69,7 +72,7 @@ export const post: RequestHandler = async (event) => { config.wordpress.environmentVariables[secret.name] = secret.value; }); } - const composeFile: ComposeFile = { + let composeFile: ComposeFile = { version: '3.8', services: { [id]: { @@ -80,7 +83,6 @@ export const post: RequestHandler = async (event) => { networks: [network], restart: 'always', ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), - depends_on: [`${id}-mysql`], labels: makeLabelForServices('wordpress'), deploy: { restart_policy: { @@ -90,22 +92,6 @@ export const post: RequestHandler = async (event) => { window: '120s' } } - }, - [`${id}-mysql`]: { - container_name: `${id}-mysql`, - 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' - } - } } }, networks: { @@ -116,12 +102,32 @@ export const post: RequestHandler = async (event) => { volumes: { [config.wordpress.volume.split(':')[0]]: { name: config.wordpress.volume.split(':')[0] - }, - [config.mysql.volume.split(':')[0]]: { - name: config.mysql.volume.split(':')[0] } } }; + if (!ownMysql) { + composeFile.services[id].depends_on = [`${id}-mysql`]; + composeFile.services[`${id}-mysql`] = { + container_name: `${id}-mysql`, + 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' + } + } + }; + + composeFile.volumes[config.mysql.volume.split(':')[0]] = { + name: config.mysql.volume.split(':')[0] + }; + } const composeFileDestination = `${workdir}/docker-compose.yaml`; await fs.writeFile(composeFileDestination, yaml.dump(composeFile)); try { diff --git a/src/routes/services/index.svelte b/src/routes/services/index.svelte index bab3a4322..06a7ce2cc 100644 --- a/src/routes/services/index.svelte +++ b/src/routes/services/index.svelte @@ -55,7 +55,7 @@
-
+
{#if !services || ownServices.length === 0}
{$t('service.no_service')}
diff --git a/src/routes/sources/[id]/index.svelte b/src/routes/sources/[id]/index.svelte index 7538dbbbd..4b12fe1c6 100644 --- a/src/routes/sources/[id]/index.svelte +++ b/src/routes/sources/[id]/index.svelte @@ -68,10 +68,48 @@ } -