diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 456faa513..91a008238 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -172,9 +172,9 @@ const host = '0.0.0.0'; }, 60000 * 15); // Cleanup stucked containers (not defined in Coolify, but still running and managed by Coolify) - // setInterval(async () => { - // await cleanupStuckedContainers(); - // }, 60000 * 5); + setInterval(async () => { + await cleanupStuckedContainers(); + }, 2000); // checkProxies, checkFluentBit & refresh templates setInterval(async () => { @@ -344,9 +344,16 @@ async function cleanupStuckedContainers() { const containersArray = containers.trim().split('\n'); if (containersArray.length > 0) { for (const container of containersArray) { - const application = await prisma.application.findFirst({ where: { id: container } }); - const service = await prisma.service.findFirst({ where: { id: container } }); - const database = await prisma.database.findFirst({ where: { id: container } }); + const containerId = container.split('-')[0]; + const application = await prisma.application.findFirst({ + where: { id: { startsWith: containerId } } + }); + const service = await prisma.service.findFirst({ + where: { id: { startsWith: containerId } } + }); + const database = await prisma.database.findFirst({ + where: { id: { startsWith: containerId } } + }); if (!application && !service && !database) { await executeCommand({ command: `docker container rm -f ${container}` }); } diff --git a/apps/backup/.dockerignore b/apps/others/backup/.dockerignore similarity index 100% rename from apps/backup/.dockerignore rename to apps/others/backup/.dockerignore diff --git a/apps/backup/Dockerfile b/apps/others/backup/Dockerfile similarity index 100% rename from apps/backup/Dockerfile rename to apps/others/backup/Dockerfile diff --git a/apps/backup/backups/.gitkeep b/apps/others/backup/backups/.gitkeep similarity index 100% rename from apps/backup/backups/.gitkeep rename to apps/others/backup/backups/.gitkeep diff --git a/apps/backup/package.json b/apps/others/backup/package.json similarity index 100% rename from apps/backup/package.json rename to apps/others/backup/package.json diff --git a/apps/backup/src/index.mjs b/apps/others/backup/src/index.mjs similarity index 100% rename from apps/backup/src/index.mjs rename to apps/others/backup/src/index.mjs diff --git a/apps/i18n/.env.example b/apps/others/i18n/.env.example similarity index 100% rename from apps/i18n/.env.example rename to apps/others/i18n/.env.example diff --git a/apps/i18n/.gitignore b/apps/others/i18n/.gitignore similarity index 100% rename from apps/i18n/.gitignore rename to apps/others/i18n/.gitignore diff --git a/apps/i18n/index.mjs b/apps/others/i18n/index.mjs similarity index 100% rename from apps/i18n/index.mjs rename to apps/others/i18n/index.mjs diff --git a/apps/i18n/package.json b/apps/others/i18n/package.json similarity index 100% rename from apps/i18n/package.json rename to apps/others/i18n/package.json diff --git a/apps/client/.eslintignore b/apps/trpc-experimental/client/.eslintignore similarity index 100% rename from apps/client/.eslintignore rename to apps/trpc-experimental/client/.eslintignore diff --git a/apps/client/.eslintrc.cjs b/apps/trpc-experimental/client/.eslintrc.cjs similarity index 100% rename from apps/client/.eslintrc.cjs rename to apps/trpc-experimental/client/.eslintrc.cjs diff --git a/apps/client/.gitignore b/apps/trpc-experimental/client/.gitignore similarity index 100% rename from apps/client/.gitignore rename to apps/trpc-experimental/client/.gitignore diff --git a/apps/client/.npmrc b/apps/trpc-experimental/client/.npmrc similarity index 100% rename from apps/client/.npmrc rename to apps/trpc-experimental/client/.npmrc diff --git a/apps/client/.prettierignore b/apps/trpc-experimental/client/.prettierignore similarity index 100% rename from apps/client/.prettierignore rename to apps/trpc-experimental/client/.prettierignore diff --git a/apps/client/.prettierrc b/apps/trpc-experimental/client/.prettierrc similarity index 100% rename from apps/client/.prettierrc rename to apps/trpc-experimental/client/.prettierrc diff --git a/apps/client/README.md b/apps/trpc-experimental/client/README.md similarity index 100% rename from apps/client/README.md rename to apps/trpc-experimental/client/README.md diff --git a/apps/client/package.json b/apps/trpc-experimental/client/package.json similarity index 100% rename from apps/client/package.json rename to apps/trpc-experimental/client/package.json diff --git a/apps/client/playwright.config.ts b/apps/trpc-experimental/client/playwright.config.ts similarity index 100% rename from apps/client/playwright.config.ts rename to apps/trpc-experimental/client/playwright.config.ts diff --git a/apps/client/pnpm-lock.yaml b/apps/trpc-experimental/client/pnpm-lock.yaml similarity index 100% rename from apps/client/pnpm-lock.yaml rename to apps/trpc-experimental/client/pnpm-lock.yaml diff --git a/apps/client/postcss.config.cjs b/apps/trpc-experimental/client/postcss.config.cjs similarity index 100% rename from apps/client/postcss.config.cjs rename to apps/trpc-experimental/client/postcss.config.cjs diff --git a/apps/client/src/app.d.ts b/apps/trpc-experimental/client/src/app.d.ts similarity index 100% rename from apps/client/src/app.d.ts rename to apps/trpc-experimental/client/src/app.d.ts diff --git a/apps/client/src/app.html b/apps/trpc-experimental/client/src/app.html similarity index 100% rename from apps/client/src/app.html rename to apps/trpc-experimental/client/src/app.html diff --git a/apps/client/src/app.postcss b/apps/trpc-experimental/client/src/app.postcss similarity index 100% rename from apps/client/src/app.postcss rename to apps/trpc-experimental/client/src/app.postcss diff --git a/apps/client/src/lib/common.ts b/apps/trpc-experimental/client/src/lib/common.ts similarity index 100% rename from apps/client/src/lib/common.ts rename to apps/trpc-experimental/client/src/lib/common.ts diff --git a/apps/client/src/lib/components/Beta.svelte b/apps/trpc-experimental/client/src/lib/components/Beta.svelte similarity index 100% rename from apps/client/src/lib/components/Beta.svelte rename to apps/trpc-experimental/client/src/lib/components/Beta.svelte diff --git a/apps/client/src/lib/components/CopyPasswordField.svelte b/apps/trpc-experimental/client/src/lib/components/CopyPasswordField.svelte similarity index 100% rename from apps/client/src/lib/components/CopyPasswordField.svelte rename to apps/trpc-experimental/client/src/lib/components/CopyPasswordField.svelte diff --git a/apps/client/src/lib/components/DocLink.svelte b/apps/trpc-experimental/client/src/lib/components/DocLink.svelte similarity index 100% rename from apps/client/src/lib/components/DocLink.svelte rename to apps/trpc-experimental/client/src/lib/components/DocLink.svelte diff --git a/apps/client/src/lib/components/Explainer.svelte b/apps/trpc-experimental/client/src/lib/components/Explainer.svelte similarity index 100% rename from apps/client/src/lib/components/Explainer.svelte rename to apps/trpc-experimental/client/src/lib/components/Explainer.svelte diff --git a/apps/client/src/lib/components/ExternalLink.svelte b/apps/trpc-experimental/client/src/lib/components/ExternalLink.svelte similarity index 100% rename from apps/client/src/lib/components/ExternalLink.svelte rename to apps/trpc-experimental/client/src/lib/components/ExternalLink.svelte diff --git a/apps/client/src/lib/components/Setting.svelte b/apps/trpc-experimental/client/src/lib/components/Setting.svelte similarity index 100% rename from apps/client/src/lib/components/Setting.svelte rename to apps/trpc-experimental/client/src/lib/components/Setting.svelte diff --git a/apps/client/src/lib/components/SimpleExplainer.svelte b/apps/trpc-experimental/client/src/lib/components/SimpleExplainer.svelte similarity index 100% rename from apps/client/src/lib/components/SimpleExplainer.svelte rename to apps/trpc-experimental/client/src/lib/components/SimpleExplainer.svelte diff --git a/apps/client/src/lib/components/Toast.svelte b/apps/trpc-experimental/client/src/lib/components/Toast.svelte similarity index 100% rename from apps/client/src/lib/components/Toast.svelte rename to apps/trpc-experimental/client/src/lib/components/Toast.svelte diff --git a/apps/client/src/lib/components/Toasts.svelte b/apps/trpc-experimental/client/src/lib/components/Toasts.svelte similarity index 100% rename from apps/client/src/lib/components/Toasts.svelte rename to apps/trpc-experimental/client/src/lib/components/Toasts.svelte diff --git a/apps/client/src/lib/components/Tooltip.svelte b/apps/trpc-experimental/client/src/lib/components/Tooltip.svelte similarity index 100% rename from apps/client/src/lib/components/Tooltip.svelte rename to apps/trpc-experimental/client/src/lib/components/Tooltip.svelte diff --git a/apps/client/src/lib/components/UpdateAvailable.svelte b/apps/trpc-experimental/client/src/lib/components/UpdateAvailable.svelte similarity index 100% rename from apps/client/src/lib/components/UpdateAvailable.svelte rename to apps/trpc-experimental/client/src/lib/components/UpdateAvailable.svelte diff --git a/apps/client/src/lib/components/icons/Delete.svelte b/apps/trpc-experimental/client/src/lib/components/icons/Delete.svelte similarity index 100% rename from apps/client/src/lib/components/icons/Delete.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/Delete.svelte diff --git a/apps/client/src/lib/components/icons/RemoteLink.svelte b/apps/trpc-experimental/client/src/lib/components/icons/RemoteLink.svelte similarity index 100% rename from apps/client/src/lib/components/icons/RemoteLink.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/RemoteLink.svelte diff --git a/apps/client/src/lib/components/icons/applications/ApplicationIcons.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/ApplicationIcons.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/ApplicationIcons.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/ApplicationIcons.svelte diff --git a/apps/client/src/lib/components/icons/applications/Astro.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Astro.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Astro.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Astro.svelte diff --git a/apps/client/src/lib/components/icons/applications/Compose.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Compose.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Compose.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Compose.svelte diff --git a/apps/client/src/lib/components/icons/applications/Deno.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Deno.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Deno.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Deno.svelte diff --git a/apps/client/src/lib/components/icons/applications/Docker.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Docker.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Docker.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Docker.svelte diff --git a/apps/client/src/lib/components/icons/applications/Eleventy.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Eleventy.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Eleventy.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Eleventy.svelte diff --git a/apps/client/src/lib/components/icons/applications/Gatsby.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Gatsby.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Gatsby.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Gatsby.svelte diff --git a/apps/client/src/lib/components/icons/applications/Heroku.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Heroku.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Heroku.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Heroku.svelte diff --git a/apps/client/src/lib/components/icons/applications/Laravel.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Laravel.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Laravel.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Laravel.svelte diff --git a/apps/client/src/lib/components/icons/applications/Nestjs.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Nestjs.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Nestjs.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Nestjs.svelte diff --git a/apps/client/src/lib/components/icons/applications/Nextjs.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Nextjs.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Nextjs.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Nextjs.svelte diff --git a/apps/client/src/lib/components/icons/applications/Nodejs.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Nodejs.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Nodejs.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Nodejs.svelte diff --git a/apps/client/src/lib/components/icons/applications/Nuxtjs.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Nuxtjs.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Nuxtjs.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Nuxtjs.svelte diff --git a/apps/client/src/lib/components/icons/applications/PHP.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/PHP.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/PHP.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/PHP.svelte diff --git a/apps/client/src/lib/components/icons/applications/Python.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Python.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Python.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Python.svelte diff --git a/apps/client/src/lib/components/icons/applications/React.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/React.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/React.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/React.svelte diff --git a/apps/client/src/lib/components/icons/applications/Rust.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Rust.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Rust.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Rust.svelte diff --git a/apps/client/src/lib/components/icons/applications/Static.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Static.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Static.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Static.svelte diff --git a/apps/client/src/lib/components/icons/applications/Svelte.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Svelte.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Svelte.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Svelte.svelte diff --git a/apps/client/src/lib/components/icons/applications/Vuejs.svelte b/apps/trpc-experimental/client/src/lib/components/icons/applications/Vuejs.svelte similarity index 100% rename from apps/client/src/lib/components/icons/applications/Vuejs.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/applications/Vuejs.svelte diff --git a/apps/client/src/lib/components/icons/applications/index.ts b/apps/trpc-experimental/client/src/lib/components/icons/applications/index.ts similarity index 100% rename from apps/client/src/lib/components/icons/applications/index.ts rename to apps/trpc-experimental/client/src/lib/components/icons/applications/index.ts diff --git a/apps/client/src/lib/components/icons/databases/Clickhouse.svelte b/apps/trpc-experimental/client/src/lib/components/icons/databases/Clickhouse.svelte similarity index 100% rename from apps/client/src/lib/components/icons/databases/Clickhouse.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/databases/Clickhouse.svelte diff --git a/apps/client/src/lib/components/icons/databases/CouchDB.svelte b/apps/trpc-experimental/client/src/lib/components/icons/databases/CouchDB.svelte similarity index 100% rename from apps/client/src/lib/components/icons/databases/CouchDB.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/databases/CouchDB.svelte diff --git a/apps/client/src/lib/components/icons/databases/DatabaseIcons.svelte b/apps/trpc-experimental/client/src/lib/components/icons/databases/DatabaseIcons.svelte similarity index 100% rename from apps/client/src/lib/components/icons/databases/DatabaseIcons.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/databases/DatabaseIcons.svelte diff --git a/apps/client/src/lib/components/icons/databases/EdgeDB.svelte b/apps/trpc-experimental/client/src/lib/components/icons/databases/EdgeDB.svelte similarity index 100% rename from apps/client/src/lib/components/icons/databases/EdgeDB.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/databases/EdgeDB.svelte diff --git a/apps/client/src/lib/components/icons/databases/MariaDB.svelte b/apps/trpc-experimental/client/src/lib/components/icons/databases/MariaDB.svelte similarity index 100% rename from apps/client/src/lib/components/icons/databases/MariaDB.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/databases/MariaDB.svelte diff --git a/apps/client/src/lib/components/icons/databases/MongoDB.svelte b/apps/trpc-experimental/client/src/lib/components/icons/databases/MongoDB.svelte similarity index 100% rename from apps/client/src/lib/components/icons/databases/MongoDB.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/databases/MongoDB.svelte diff --git a/apps/client/src/lib/components/icons/databases/MySQL.svelte b/apps/trpc-experimental/client/src/lib/components/icons/databases/MySQL.svelte similarity index 100% rename from apps/client/src/lib/components/icons/databases/MySQL.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/databases/MySQL.svelte diff --git a/apps/client/src/lib/components/icons/databases/PostgreSQL.svelte b/apps/trpc-experimental/client/src/lib/components/icons/databases/PostgreSQL.svelte similarity index 100% rename from apps/client/src/lib/components/icons/databases/PostgreSQL.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/databases/PostgreSQL.svelte diff --git a/apps/client/src/lib/components/icons/databases/Redis.svelte b/apps/trpc-experimental/client/src/lib/components/icons/databases/Redis.svelte similarity index 100% rename from apps/client/src/lib/components/icons/databases/Redis.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/databases/Redis.svelte diff --git a/apps/client/src/lib/components/icons/databases/index.ts b/apps/trpc-experimental/client/src/lib/components/icons/databases/index.ts similarity index 100% rename from apps/client/src/lib/components/icons/databases/index.ts rename to apps/trpc-experimental/client/src/lib/components/icons/databases/index.ts diff --git a/apps/client/src/lib/components/icons/destinations/LocalDocker.svelte b/apps/trpc-experimental/client/src/lib/components/icons/destinations/LocalDocker.svelte similarity index 100% rename from apps/client/src/lib/components/icons/destinations/LocalDocker.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/destinations/LocalDocker.svelte diff --git a/apps/client/src/lib/components/icons/destinations/RemoteDocker.svelte b/apps/trpc-experimental/client/src/lib/components/icons/destinations/RemoteDocker.svelte similarity index 100% rename from apps/client/src/lib/components/icons/destinations/RemoteDocker.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/destinations/RemoteDocker.svelte diff --git a/apps/client/src/lib/components/icons/destinations/index.ts b/apps/trpc-experimental/client/src/lib/components/icons/destinations/index.ts similarity index 100% rename from apps/client/src/lib/components/icons/destinations/index.ts rename to apps/trpc-experimental/client/src/lib/components/icons/destinations/index.ts diff --git a/apps/client/src/lib/components/icons/index.ts b/apps/trpc-experimental/client/src/lib/components/icons/index.ts similarity index 100% rename from apps/client/src/lib/components/icons/index.ts rename to apps/trpc-experimental/client/src/lib/components/icons/index.ts diff --git a/apps/client/src/lib/components/icons/services/ServiceIcons.svelte b/apps/trpc-experimental/client/src/lib/components/icons/services/ServiceIcons.svelte similarity index 100% rename from apps/client/src/lib/components/icons/services/ServiceIcons.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/services/ServiceIcons.svelte diff --git a/apps/client/src/lib/components/icons/sources/Github.svelte b/apps/trpc-experimental/client/src/lib/components/icons/sources/Github.svelte similarity index 100% rename from apps/client/src/lib/components/icons/sources/Github.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/sources/Github.svelte diff --git a/apps/client/src/lib/components/icons/sources/Gitlab.svelte b/apps/trpc-experimental/client/src/lib/components/icons/sources/Gitlab.svelte similarity index 100% rename from apps/client/src/lib/components/icons/sources/Gitlab.svelte rename to apps/trpc-experimental/client/src/lib/components/icons/sources/Gitlab.svelte diff --git a/apps/client/src/lib/components/icons/sources/index.ts b/apps/trpc-experimental/client/src/lib/components/icons/sources/index.ts similarity index 100% rename from apps/client/src/lib/components/icons/sources/index.ts rename to apps/trpc-experimental/client/src/lib/components/icons/sources/index.ts diff --git a/apps/client/src/lib/dayjs.ts b/apps/trpc-experimental/client/src/lib/dayjs.ts similarity index 100% rename from apps/client/src/lib/dayjs.ts rename to apps/trpc-experimental/client/src/lib/dayjs.ts diff --git a/apps/client/src/lib/store.ts b/apps/trpc-experimental/client/src/lib/store.ts similarity index 100% rename from apps/client/src/lib/store.ts rename to apps/trpc-experimental/client/src/lib/store.ts diff --git a/apps/client/src/routes/+error.svelte b/apps/trpc-experimental/client/src/routes/+error.svelte similarity index 100% rename from apps/client/src/routes/+error.svelte rename to apps/trpc-experimental/client/src/routes/+error.svelte diff --git a/apps/client/src/routes/+layout.svelte b/apps/trpc-experimental/client/src/routes/+layout.svelte similarity index 100% rename from apps/client/src/routes/+layout.svelte rename to apps/trpc-experimental/client/src/routes/+layout.svelte diff --git a/apps/client/src/routes/+layout.ts b/apps/trpc-experimental/client/src/routes/+layout.ts similarity index 100% rename from apps/client/src/routes/+layout.ts rename to apps/trpc-experimental/client/src/routes/+layout.ts diff --git a/apps/client/src/routes/+page.svelte b/apps/trpc-experimental/client/src/routes/+page.svelte similarity index 100% rename from apps/client/src/routes/+page.svelte rename to apps/trpc-experimental/client/src/routes/+page.svelte diff --git a/apps/client/src/routes/+page.ts b/apps/trpc-experimental/client/src/routes/+page.ts similarity index 100% rename from apps/client/src/routes/+page.ts rename to apps/trpc-experimental/client/src/routes/+page.ts diff --git a/apps/client/src/routes/applications/[id]/+layout.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/+layout.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/+layout.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/+layout.svelte diff --git a/apps/client/src/routes/applications/[id]/+layout.ts b/apps/trpc-experimental/client/src/routes/applications/[id]/+layout.ts similarity index 100% rename from apps/client/src/routes/applications/[id]/+layout.ts rename to apps/trpc-experimental/client/src/routes/applications/[id]/+layout.ts diff --git a/apps/client/src/routes/applications/[id]/+page.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/+page.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/+page.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/+page.svelte diff --git a/apps/client/src/routes/applications/[id]/builds/+page.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/builds/+page.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/builds/+page.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/builds/+page.svelte diff --git a/apps/client/src/routes/applications/[id]/builds/+page.ts b/apps/trpc-experimental/client/src/routes/applications/[id]/builds/+page.ts similarity index 100% rename from apps/client/src/routes/applications/[id]/builds/+page.ts rename to apps/trpc-experimental/client/src/routes/applications/[id]/builds/+page.ts diff --git a/apps/client/src/routes/applications/[id]/builds/BuildLog.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/builds/BuildLog.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/builds/BuildLog.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/builds/BuildLog.svelte diff --git a/apps/client/src/routes/applications/[id]/components/Buttons/Delete.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/Delete.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/Buttons/Delete.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/Delete.svelte diff --git a/apps/client/src/routes/applications/[id]/components/Buttons/Deploy.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/Deploy.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/Buttons/Deploy.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/Deploy.svelte diff --git a/apps/client/src/routes/applications/[id]/components/Buttons/ForceDeploy.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/ForceDeploy.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/Buttons/ForceDeploy.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/ForceDeploy.svelte diff --git a/apps/client/src/routes/applications/[id]/components/Buttons/Loading.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/Loading.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/Buttons/Loading.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/Loading.svelte diff --git a/apps/client/src/routes/applications/[id]/components/Buttons/Restart.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/Restart.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/Buttons/Restart.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/Restart.svelte diff --git a/apps/client/src/routes/applications/[id]/components/Buttons/Stop.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/Stop.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/Buttons/Stop.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/Stop.svelte diff --git a/apps/client/src/routes/applications/[id]/components/Buttons/index.ts b/apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/index.ts similarity index 100% rename from apps/client/src/routes/applications/[id]/components/Buttons/index.ts rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/Buttons/index.ts diff --git a/apps/client/src/routes/applications/[id]/components/Menu.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/Menu.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/Menu.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/Menu.svelte diff --git a/apps/client/src/routes/applications/[id]/components/States/Degraded.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/States/Degraded.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/States/Degraded.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/States/Degraded.svelte diff --git a/apps/client/src/routes/applications/[id]/components/States/Healthy.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/States/Healthy.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/States/Healthy.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/States/Healthy.svelte diff --git a/apps/client/src/routes/applications/[id]/components/States/Loading.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/States/Loading.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/States/Loading.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/States/Loading.svelte diff --git a/apps/client/src/routes/applications/[id]/components/States/Stopped.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/components/States/Stopped.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/components/States/Stopped.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/States/Stopped.svelte diff --git a/apps/client/src/routes/applications/[id]/components/States/index.ts b/apps/trpc-experimental/client/src/routes/applications/[id]/components/States/index.ts similarity index 100% rename from apps/client/src/routes/applications/[id]/components/States/index.ts rename to apps/trpc-experimental/client/src/routes/applications/[id]/components/States/index.ts diff --git a/apps/client/src/routes/applications/[id]/danger/+page.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/danger/+page.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/danger/+page.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/danger/+page.svelte diff --git a/apps/client/src/routes/applications/[id]/features/+page.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/features/+page.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/features/+page.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/features/+page.svelte diff --git a/apps/client/src/routes/applications/[id]/logs/+page.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/logs/+page.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/logs/+page.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/logs/+page.svelte diff --git a/apps/client/src/routes/applications/[id]/previews/+page.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/previews/+page.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/previews/+page.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/previews/+page.svelte diff --git a/apps/client/src/routes/applications/[id]/revert/+page.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/revert/+page.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/revert/+page.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/revert/+page.svelte diff --git a/apps/client/src/routes/applications/[id]/revert/+page.ts b/apps/trpc-experimental/client/src/routes/applications/[id]/revert/+page.ts similarity index 100% rename from apps/client/src/routes/applications/[id]/revert/+page.ts rename to apps/trpc-experimental/client/src/routes/applications/[id]/revert/+page.ts diff --git a/apps/client/src/routes/applications/[id]/secrets/+page.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/secrets/+page.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/secrets/+page.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/secrets/+page.svelte diff --git a/apps/client/src/routes/applications/[id]/secrets/+page.ts b/apps/trpc-experimental/client/src/routes/applications/[id]/secrets/+page.ts similarity index 100% rename from apps/client/src/routes/applications/[id]/secrets/+page.ts rename to apps/trpc-experimental/client/src/routes/applications/[id]/secrets/+page.ts diff --git a/apps/client/src/routes/applications/[id]/secrets/components/PreviewSecret.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/secrets/components/PreviewSecret.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/secrets/components/PreviewSecret.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/secrets/components/PreviewSecret.svelte diff --git a/apps/client/src/routes/applications/[id]/secrets/components/Secret.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/secrets/components/Secret.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/secrets/components/Secret.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/secrets/components/Secret.svelte diff --git a/apps/client/src/routes/applications/[id]/storages/+page.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/storages/+page.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/storages/+page.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/storages/+page.svelte diff --git a/apps/client/src/routes/applications/[id]/storages/+page.ts b/apps/trpc-experimental/client/src/routes/applications/[id]/storages/+page.ts similarity index 100% rename from apps/client/src/routes/applications/[id]/storages/+page.ts rename to apps/trpc-experimental/client/src/routes/applications/[id]/storages/+page.ts diff --git a/apps/client/src/routes/applications/[id]/storages/components/Storage.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/storages/components/Storage.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/storages/components/Storage.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/storages/components/Storage.svelte diff --git a/apps/client/src/routes/applications/[id]/usage/+page.svelte b/apps/trpc-experimental/client/src/routes/applications/[id]/usage/+page.svelte similarity index 100% rename from apps/client/src/routes/applications/[id]/usage/+page.svelte rename to apps/trpc-experimental/client/src/routes/applications/[id]/usage/+page.svelte diff --git a/apps/client/src/routes/applications/[id]/utils.ts b/apps/trpc-experimental/client/src/routes/applications/[id]/utils.ts similarity index 100% rename from apps/client/src/routes/applications/[id]/utils.ts rename to apps/trpc-experimental/client/src/routes/applications/[id]/utils.ts diff --git a/apps/client/src/routes/components/NewResource.svelte b/apps/trpc-experimental/client/src/routes/components/NewResource.svelte similarity index 100% rename from apps/client/src/routes/components/NewResource.svelte rename to apps/trpc-experimental/client/src/routes/components/NewResource.svelte diff --git a/apps/client/src/routes/databases/[id]/+layout.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/+layout.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/+layout.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/+layout.svelte diff --git a/apps/client/src/routes/databases/[id]/+layout.ts b/apps/trpc-experimental/client/src/routes/databases/[id]/+layout.ts similarity index 100% rename from apps/client/src/routes/databases/[id]/+layout.ts rename to apps/trpc-experimental/client/src/routes/databases/[id]/+layout.ts diff --git a/apps/client/src/routes/databases/[id]/+page.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/+page.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/+page.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/+page.svelte diff --git a/apps/client/src/routes/databases/[id]/components/DatabaseLinks.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/components/DatabaseLinks.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/components/DatabaseLinks.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/components/DatabaseLinks.svelte diff --git a/apps/client/src/routes/databases/[id]/components/Databases/CouchDb.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/CouchDb.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/components/Databases/CouchDb.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/CouchDb.svelte diff --git a/apps/client/src/routes/databases/[id]/components/Databases/Databases.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/Databases.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/components/Databases/Databases.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/Databases.svelte diff --git a/apps/client/src/routes/databases/[id]/components/Databases/EdgeDB.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/EdgeDB.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/components/Databases/EdgeDB.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/EdgeDB.svelte diff --git a/apps/client/src/routes/databases/[id]/components/Databases/MariaDB.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/MariaDB.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/components/Databases/MariaDB.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/MariaDB.svelte diff --git a/apps/client/src/routes/databases/[id]/components/Databases/MongoDB.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/MongoDB.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/components/Databases/MongoDB.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/MongoDB.svelte diff --git a/apps/client/src/routes/databases/[id]/components/Databases/MySQL.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/MySQL.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/components/Databases/MySQL.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/MySQL.svelte diff --git a/apps/client/src/routes/databases/[id]/components/Databases/PostgreSQL.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/PostgreSQL.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/components/Databases/PostgreSQL.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/PostgreSQL.svelte diff --git a/apps/client/src/routes/databases/[id]/components/Databases/Redis.svelte b/apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/Redis.svelte similarity index 100% rename from apps/client/src/routes/databases/[id]/components/Databases/Redis.svelte rename to apps/trpc-experimental/client/src/routes/databases/[id]/components/Databases/Redis.svelte diff --git a/apps/client/src/routes/databases/[id]/utils.ts b/apps/trpc-experimental/client/src/routes/databases/[id]/utils.ts similarity index 100% rename from apps/client/src/routes/databases/[id]/utils.ts rename to apps/trpc-experimental/client/src/routes/databases/[id]/utils.ts diff --git a/apps/client/src/routes/destinations/[id]/+layout.svelte b/apps/trpc-experimental/client/src/routes/destinations/[id]/+layout.svelte similarity index 100% rename from apps/client/src/routes/destinations/[id]/+layout.svelte rename to apps/trpc-experimental/client/src/routes/destinations/[id]/+layout.svelte diff --git a/apps/client/src/routes/destinations/[id]/+layout.ts b/apps/trpc-experimental/client/src/routes/destinations/[id]/+layout.ts similarity index 100% rename from apps/client/src/routes/destinations/[id]/+layout.ts rename to apps/trpc-experimental/client/src/routes/destinations/[id]/+layout.ts diff --git a/apps/client/src/routes/destinations/[id]/+page.svelte b/apps/trpc-experimental/client/src/routes/destinations/[id]/+page.svelte similarity index 100% rename from apps/client/src/routes/destinations/[id]/+page.svelte rename to apps/trpc-experimental/client/src/routes/destinations/[id]/+page.svelte diff --git a/apps/client/src/routes/destinations/[id]/components/Destination.svelte b/apps/trpc-experimental/client/src/routes/destinations/[id]/components/Destination.svelte similarity index 100% rename from apps/client/src/routes/destinations/[id]/components/Destination.svelte rename to apps/trpc-experimental/client/src/routes/destinations/[id]/components/Destination.svelte diff --git a/apps/client/src/routes/destinations/[id]/components/LocalDocker.svelte b/apps/trpc-experimental/client/src/routes/destinations/[id]/components/LocalDocker.svelte similarity index 100% rename from apps/client/src/routes/destinations/[id]/components/LocalDocker.svelte rename to apps/trpc-experimental/client/src/routes/destinations/[id]/components/LocalDocker.svelte diff --git a/apps/client/src/routes/destinations/[id]/components/New.svelte b/apps/trpc-experimental/client/src/routes/destinations/[id]/components/New.svelte similarity index 100% rename from apps/client/src/routes/destinations/[id]/components/New.svelte rename to apps/trpc-experimental/client/src/routes/destinations/[id]/components/New.svelte diff --git a/apps/client/src/routes/destinations/[id]/components/NewLocalDocker.svelte b/apps/trpc-experimental/client/src/routes/destinations/[id]/components/NewLocalDocker.svelte similarity index 100% rename from apps/client/src/routes/destinations/[id]/components/NewLocalDocker.svelte rename to apps/trpc-experimental/client/src/routes/destinations/[id]/components/NewLocalDocker.svelte diff --git a/apps/client/src/routes/destinations/[id]/components/NewRemoteDocker.svelte b/apps/trpc-experimental/client/src/routes/destinations/[id]/components/NewRemoteDocker.svelte similarity index 100% rename from apps/client/src/routes/destinations/[id]/components/NewRemoteDocker.svelte rename to apps/trpc-experimental/client/src/routes/destinations/[id]/components/NewRemoteDocker.svelte diff --git a/apps/client/src/routes/destinations/[id]/components/RemoteDocker.svelte b/apps/trpc-experimental/client/src/routes/destinations/[id]/components/RemoteDocker.svelte similarity index 100% rename from apps/client/src/routes/destinations/[id]/components/RemoteDocker.svelte rename to apps/trpc-experimental/client/src/routes/destinations/[id]/components/RemoteDocker.svelte diff --git a/apps/client/src/routes/login/+page.svelte b/apps/trpc-experimental/client/src/routes/login/+page.svelte similarity index 100% rename from apps/client/src/routes/login/+page.svelte rename to apps/trpc-experimental/client/src/routes/login/+page.svelte diff --git a/apps/client/src/routes/register/+page.svelte b/apps/trpc-experimental/client/src/routes/register/+page.svelte similarity index 100% rename from apps/client/src/routes/register/+page.svelte rename to apps/trpc-experimental/client/src/routes/register/+page.svelte diff --git a/apps/client/src/routes/services/[id]/+layout.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/+layout.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/+layout.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/+layout.svelte diff --git a/apps/client/src/routes/services/[id]/+layout.ts b/apps/trpc-experimental/client/src/routes/services/[id]/+layout.ts similarity index 100% rename from apps/client/src/routes/services/[id]/+layout.ts rename to apps/trpc-experimental/client/src/routes/services/[id]/+layout.ts diff --git a/apps/client/src/routes/services/[id]/+page.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/+page.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/+page.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/+page.svelte diff --git a/apps/client/src/routes/services/[id]/components/Menu.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/components/Menu.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/components/Menu.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/components/Menu.svelte diff --git a/apps/client/src/routes/services/[id]/components/ServiceLinks.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/components/ServiceLinks.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/components/ServiceLinks.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/components/ServiceLinks.svelte diff --git a/apps/client/src/routes/services/[id]/components/ServiceStatus.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/components/ServiceStatus.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/components/ServiceStatus.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/components/ServiceStatus.svelte diff --git a/apps/client/src/routes/services/[id]/components/Wordpress.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/components/Wordpress.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/components/Wordpress.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/components/Wordpress.svelte diff --git a/apps/client/src/routes/services/[id]/danger/+page.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/danger/+page.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/danger/+page.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/danger/+page.svelte diff --git a/apps/client/src/routes/services/[id]/logs/+page.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/logs/+page.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/logs/+page.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/logs/+page.svelte diff --git a/apps/client/src/routes/services/[id]/secrets/+page.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/secrets/+page.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/secrets/+page.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/secrets/+page.svelte diff --git a/apps/client/src/routes/services/[id]/secrets/+page.ts b/apps/trpc-experimental/client/src/routes/services/[id]/secrets/+page.ts similarity index 100% rename from apps/client/src/routes/services/[id]/secrets/+page.ts rename to apps/trpc-experimental/client/src/routes/services/[id]/secrets/+page.ts diff --git a/apps/client/src/routes/services/[id]/secrets/components/Secret.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/secrets/components/Secret.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/secrets/components/Secret.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/secrets/components/Secret.svelte diff --git a/apps/client/src/routes/services/[id]/secrets/utils.ts b/apps/trpc-experimental/client/src/routes/services/[id]/secrets/utils.ts similarity index 100% rename from apps/client/src/routes/services/[id]/secrets/utils.ts rename to apps/trpc-experimental/client/src/routes/services/[id]/secrets/utils.ts diff --git a/apps/client/src/routes/services/[id]/storages/+page.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/storages/+page.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/storages/+page.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/storages/+page.svelte diff --git a/apps/client/src/routes/services/[id]/storages/+page.ts b/apps/trpc-experimental/client/src/routes/services/[id]/storages/+page.ts similarity index 100% rename from apps/client/src/routes/services/[id]/storages/+page.ts rename to apps/trpc-experimental/client/src/routes/services/[id]/storages/+page.ts diff --git a/apps/client/src/routes/services/[id]/storages/components/Storage.svelte b/apps/trpc-experimental/client/src/routes/services/[id]/storages/components/Storage.svelte similarity index 100% rename from apps/client/src/routes/services/[id]/storages/components/Storage.svelte rename to apps/trpc-experimental/client/src/routes/services/[id]/storages/components/Storage.svelte diff --git a/apps/client/src/routes/services/[id]/utils.ts b/apps/trpc-experimental/client/src/routes/services/[id]/utils.ts similarity index 100% rename from apps/client/src/routes/services/[id]/utils.ts rename to apps/trpc-experimental/client/src/routes/services/[id]/utils.ts diff --git a/apps/client/src/routes/sources/[id]/+layout.svelte b/apps/trpc-experimental/client/src/routes/sources/[id]/+layout.svelte similarity index 100% rename from apps/client/src/routes/sources/[id]/+layout.svelte rename to apps/trpc-experimental/client/src/routes/sources/[id]/+layout.svelte diff --git a/apps/client/src/routes/sources/[id]/+layout.ts b/apps/trpc-experimental/client/src/routes/sources/[id]/+layout.ts similarity index 100% rename from apps/client/src/routes/sources/[id]/+layout.ts rename to apps/trpc-experimental/client/src/routes/sources/[id]/+layout.ts diff --git a/apps/client/src/routes/sources/[id]/+page.svelte b/apps/trpc-experimental/client/src/routes/sources/[id]/+page.svelte similarity index 100% rename from apps/client/src/routes/sources/[id]/+page.svelte rename to apps/trpc-experimental/client/src/routes/sources/[id]/+page.svelte diff --git a/apps/client/src/routes/sources/[id]/components/Github.svelte b/apps/trpc-experimental/client/src/routes/sources/[id]/components/Github.svelte similarity index 100% rename from apps/client/src/routes/sources/[id]/components/Github.svelte rename to apps/trpc-experimental/client/src/routes/sources/[id]/components/Github.svelte diff --git a/apps/client/src/routes/sources/[id]/components/Gitlab.svelte b/apps/trpc-experimental/client/src/routes/sources/[id]/components/Gitlab.svelte similarity index 100% rename from apps/client/src/routes/sources/[id]/components/Gitlab.svelte rename to apps/trpc-experimental/client/src/routes/sources/[id]/components/Gitlab.svelte diff --git a/apps/client/src/routes/sources/[id]/components/New.svelte b/apps/trpc-experimental/client/src/routes/sources/[id]/components/New.svelte similarity index 100% rename from apps/client/src/routes/sources/[id]/components/New.svelte rename to apps/trpc-experimental/client/src/routes/sources/[id]/components/New.svelte diff --git a/apps/client/src/routes/sources/[id]/components/Source.svelte b/apps/trpc-experimental/client/src/routes/sources/[id]/components/Source.svelte similarity index 100% rename from apps/client/src/routes/sources/[id]/components/Source.svelte rename to apps/trpc-experimental/client/src/routes/sources/[id]/components/Source.svelte diff --git a/apps/client/static/favicon.png b/apps/trpc-experimental/client/static/favicon.png similarity index 100% rename from apps/client/static/favicon.png rename to apps/trpc-experimental/client/static/favicon.png diff --git a/apps/client/static/icons/appsmith.png b/apps/trpc-experimental/client/static/icons/appsmith.png similarity index 100% rename from apps/client/static/icons/appsmith.png rename to apps/trpc-experimental/client/static/icons/appsmith.png diff --git a/apps/client/static/icons/appwrite.png b/apps/trpc-experimental/client/static/icons/appwrite.png similarity index 100% rename from apps/client/static/icons/appwrite.png rename to apps/trpc-experimental/client/static/icons/appwrite.png diff --git a/apps/client/static/icons/compose.png b/apps/trpc-experimental/client/static/icons/compose.png similarity index 100% rename from apps/client/static/icons/compose.png rename to apps/trpc-experimental/client/static/icons/compose.png diff --git a/apps/client/static/icons/default.png b/apps/trpc-experimental/client/static/icons/default.png similarity index 100% rename from apps/client/static/icons/default.png rename to apps/trpc-experimental/client/static/icons/default.png diff --git a/apps/client/static/icons/directus.svg b/apps/trpc-experimental/client/static/icons/directus.svg similarity index 100% rename from apps/client/static/icons/directus.svg rename to apps/trpc-experimental/client/static/icons/directus.svg diff --git a/apps/client/static/icons/fider.png b/apps/trpc-experimental/client/static/icons/fider.png similarity index 100% rename from apps/client/static/icons/fider.png rename to apps/trpc-experimental/client/static/icons/fider.png diff --git a/apps/client/static/icons/ghost.png b/apps/trpc-experimental/client/static/icons/ghost.png similarity index 100% rename from apps/client/static/icons/ghost.png rename to apps/trpc-experimental/client/static/icons/ghost.png diff --git a/apps/client/static/icons/gitea.svg b/apps/trpc-experimental/client/static/icons/gitea.svg similarity index 100% rename from apps/client/static/icons/gitea.svg rename to apps/trpc-experimental/client/static/icons/gitea.svg diff --git a/apps/client/static/icons/glitchtip.svg b/apps/trpc-experimental/client/static/icons/glitchtip.svg similarity index 100% rename from apps/client/static/icons/glitchtip.svg rename to apps/trpc-experimental/client/static/icons/glitchtip.svg diff --git a/apps/client/static/icons/grafana.png b/apps/trpc-experimental/client/static/icons/grafana.png similarity index 100% rename from apps/client/static/icons/grafana.png rename to apps/trpc-experimental/client/static/icons/grafana.png diff --git a/apps/client/static/icons/hasura.png b/apps/trpc-experimental/client/static/icons/hasura.png similarity index 100% rename from apps/client/static/icons/hasura.png rename to apps/trpc-experimental/client/static/icons/hasura.png diff --git a/apps/client/static/icons/keycloak.png b/apps/trpc-experimental/client/static/icons/keycloak.png similarity index 100% rename from apps/client/static/icons/keycloak.png rename to apps/trpc-experimental/client/static/icons/keycloak.png diff --git a/apps/client/static/icons/languagetool.svg b/apps/trpc-experimental/client/static/icons/languagetool.svg similarity index 100% rename from apps/client/static/icons/languagetool.svg rename to apps/trpc-experimental/client/static/icons/languagetool.svg diff --git a/apps/client/static/icons/lavalink.png b/apps/trpc-experimental/client/static/icons/lavalink.png similarity index 100% rename from apps/client/static/icons/lavalink.png rename to apps/trpc-experimental/client/static/icons/lavalink.png diff --git a/apps/client/static/icons/libretranslate.png b/apps/trpc-experimental/client/static/icons/libretranslate.png similarity index 100% rename from apps/client/static/icons/libretranslate.png rename to apps/trpc-experimental/client/static/icons/libretranslate.png diff --git a/apps/client/static/icons/meilisearch.svg b/apps/trpc-experimental/client/static/icons/meilisearch.svg similarity index 100% rename from apps/client/static/icons/meilisearch.svg rename to apps/trpc-experimental/client/static/icons/meilisearch.svg diff --git a/apps/client/static/icons/minio.png b/apps/trpc-experimental/client/static/icons/minio.png similarity index 100% rename from apps/client/static/icons/minio.png rename to apps/trpc-experimental/client/static/icons/minio.png diff --git a/apps/client/static/icons/moodle.png b/apps/trpc-experimental/client/static/icons/moodle.png similarity index 100% rename from apps/client/static/icons/moodle.png rename to apps/trpc-experimental/client/static/icons/moodle.png diff --git a/apps/client/static/icons/n8n.svg b/apps/trpc-experimental/client/static/icons/n8n.svg similarity index 100% rename from apps/client/static/icons/n8n.svg rename to apps/trpc-experimental/client/static/icons/n8n.svg diff --git a/apps/client/static/icons/nocodb.png b/apps/trpc-experimental/client/static/icons/nocodb.png similarity index 100% rename from apps/client/static/icons/nocodb.png rename to apps/trpc-experimental/client/static/icons/nocodb.png diff --git a/apps/client/static/icons/openblocks.png b/apps/trpc-experimental/client/static/icons/openblocks.png similarity index 100% rename from apps/client/static/icons/openblocks.png rename to apps/trpc-experimental/client/static/icons/openblocks.png diff --git a/apps/client/static/icons/plausibleanalytics.png b/apps/trpc-experimental/client/static/icons/plausibleanalytics.png similarity index 100% rename from apps/client/static/icons/plausibleanalytics.png rename to apps/trpc-experimental/client/static/icons/plausibleanalytics.png diff --git a/apps/client/static/icons/pocketbase.svg b/apps/trpc-experimental/client/static/icons/pocketbase.svg similarity index 100% rename from apps/client/static/icons/pocketbase.svg rename to apps/trpc-experimental/client/static/icons/pocketbase.svg diff --git a/apps/client/static/icons/searxng.svg b/apps/trpc-experimental/client/static/icons/searxng.svg similarity index 100% rename from apps/client/static/icons/searxng.svg rename to apps/trpc-experimental/client/static/icons/searxng.svg diff --git a/apps/client/static/icons/trilium.png b/apps/trpc-experimental/client/static/icons/trilium.png similarity index 100% rename from apps/client/static/icons/trilium.png rename to apps/trpc-experimental/client/static/icons/trilium.png diff --git a/apps/client/static/icons/umami.svg b/apps/trpc-experimental/client/static/icons/umami.svg similarity index 100% rename from apps/client/static/icons/umami.svg rename to apps/trpc-experimental/client/static/icons/umami.svg diff --git a/apps/client/static/icons/uptimekuma.svg b/apps/trpc-experimental/client/static/icons/uptimekuma.svg similarity index 100% rename from apps/client/static/icons/uptimekuma.svg rename to apps/trpc-experimental/client/static/icons/uptimekuma.svg diff --git a/apps/client/static/icons/vaultwarden.svg b/apps/trpc-experimental/client/static/icons/vaultwarden.svg similarity index 100% rename from apps/client/static/icons/vaultwarden.svg rename to apps/trpc-experimental/client/static/icons/vaultwarden.svg diff --git a/apps/client/static/icons/vscodeserver.png b/apps/trpc-experimental/client/static/icons/vscodeserver.png similarity index 100% rename from apps/client/static/icons/vscodeserver.png rename to apps/trpc-experimental/client/static/icons/vscodeserver.png diff --git a/apps/client/static/icons/weblate.svg b/apps/trpc-experimental/client/static/icons/weblate.svg similarity index 100% rename from apps/client/static/icons/weblate.svg rename to apps/trpc-experimental/client/static/icons/weblate.svg diff --git a/apps/client/static/icons/whoogle.png b/apps/trpc-experimental/client/static/icons/whoogle.png similarity index 100% rename from apps/client/static/icons/whoogle.png rename to apps/trpc-experimental/client/static/icons/whoogle.png diff --git a/apps/client/static/icons/wordpress.svg b/apps/trpc-experimental/client/static/icons/wordpress.svg similarity index 100% rename from apps/client/static/icons/wordpress.svg rename to apps/trpc-experimental/client/static/icons/wordpress.svg diff --git a/apps/client/static/poppins-v19-latin-ext_latin_devanagari-500.woff b/apps/trpc-experimental/client/static/poppins-v19-latin-ext_latin_devanagari-500.woff similarity index 100% rename from apps/client/static/poppins-v19-latin-ext_latin_devanagari-500.woff rename to apps/trpc-experimental/client/static/poppins-v19-latin-ext_latin_devanagari-500.woff diff --git a/apps/client/static/poppins-v19-latin-ext_latin_devanagari-500.woff2 b/apps/trpc-experimental/client/static/poppins-v19-latin-ext_latin_devanagari-500.woff2 similarity index 100% rename from apps/client/static/poppins-v19-latin-ext_latin_devanagari-500.woff2 rename to apps/trpc-experimental/client/static/poppins-v19-latin-ext_latin_devanagari-500.woff2 diff --git a/apps/client/static/poppins-v19-latin-ext_latin_devanagari-regular.woff b/apps/trpc-experimental/client/static/poppins-v19-latin-ext_latin_devanagari-regular.woff similarity index 100% rename from apps/client/static/poppins-v19-latin-ext_latin_devanagari-regular.woff rename to apps/trpc-experimental/client/static/poppins-v19-latin-ext_latin_devanagari-regular.woff diff --git a/apps/client/static/poppins-v19-latin-ext_latin_devanagari-regular.woff2 b/apps/trpc-experimental/client/static/poppins-v19-latin-ext_latin_devanagari-regular.woff2 similarity index 100% rename from apps/client/static/poppins-v19-latin-ext_latin_devanagari-regular.woff2 rename to apps/trpc-experimental/client/static/poppins-v19-latin-ext_latin_devanagari-regular.woff2 diff --git a/apps/client/svelte.config.js b/apps/trpc-experimental/client/svelte.config.js similarity index 100% rename from apps/client/svelte.config.js rename to apps/trpc-experimental/client/svelte.config.js diff --git a/apps/client/tailwind.config.cjs b/apps/trpc-experimental/client/tailwind.config.cjs similarity index 100% rename from apps/client/tailwind.config.cjs rename to apps/trpc-experimental/client/tailwind.config.cjs diff --git a/apps/client/tests/test.ts b/apps/trpc-experimental/client/tests/test.ts similarity index 100% rename from apps/client/tests/test.ts rename to apps/trpc-experimental/client/tests/test.ts diff --git a/apps/client/tsconfig.json b/apps/trpc-experimental/client/tsconfig.json similarity index 100% rename from apps/client/tsconfig.json rename to apps/trpc-experimental/client/tsconfig.json diff --git a/apps/client/vite.config.ts b/apps/trpc-experimental/client/vite.config.ts similarity index 100% rename from apps/client/vite.config.ts rename to apps/trpc-experimental/client/vite.config.ts diff --git a/apps/server/.env-template b/apps/trpc-experimental/server/.env-template similarity index 100% rename from apps/server/.env-template rename to apps/trpc-experimental/server/.env-template diff --git a/apps/server/.prettierrc b/apps/trpc-experimental/server/.prettierrc similarity index 100% rename from apps/server/.prettierrc rename to apps/trpc-experimental/server/.prettierrc diff --git a/apps/trpc-experimental/server/build/api/index.js b/apps/trpc-experimental/server/build/api/index.js new file mode 100644 index 000000000..2a6289ae9 --- /dev/null +++ b/apps/trpc-experimental/server/build/api/index.js @@ -0,0 +1,31 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var api_exports = {}; +__export(api_exports, { + default: () => api_default +}); +module.exports = __toCommonJS(api_exports); +const root = async (fastify) => { + fastify.get("/", async function(_request, _reply) { + return { status: "ok" }; + }); +}; +var api_default = root; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/config.js b/apps/trpc-experimental/server/build/config.js new file mode 100644 index 000000000..9186a9097 --- /dev/null +++ b/apps/trpc-experimental/server/build/config.js @@ -0,0 +1,32 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var config_exports = {}; +__export(config_exports, { + serverConfig: () => serverConfig +}); +module.exports = __toCommonJS(config_exports); +const serverConfig = { + dev: false, + port: 2022, + prefix: "/trpc" +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + serverConfig +}); diff --git a/apps/trpc-experimental/server/build/env.js b/apps/trpc-experimental/server/build/env.js new file mode 100644 index 000000000..455559525 --- /dev/null +++ b/apps/trpc-experimental/server/build/env.js @@ -0,0 +1,18 @@ +"use strict"; +const dotenv = require("dotenv"); +dotenv.config(); +const { z } = require("zod"); +const envSchema = z.object({ + CODESANDBOX_HOST: z.string().optional(), + NODE_ENV: z.enum(["development", "test", "production"]), + COOLIFY_DATABASE_URL: z.string(), + COOLIFY_SECRET_KEY: z.string().length(32), + COOLIFY_WHITE_LABELED: z.string().optional(), + COOLIFY_WHITE_LABELED_ICON: z.string().optional() +}); +const env = envSchema.safeParse(process.env); +if (!env.success) { + console.error("\u274C Invalid environment variables:", JSON.stringify(env.error.format(), null, 4)); + process.exit(1); +} +module.exports.env = env.data; diff --git a/apps/trpc-experimental/server/build/index.js b/apps/trpc-experimental/server/build/index.js new file mode 100644 index 000000000..5d36a4041 --- /dev/null +++ b/apps/trpc-experimental/server/build/index.js @@ -0,0 +1,5 @@ +"use strict"; +var import_config = require("./config"); +var import_server = require("./server"); +const server = (0, import_server.createServer)(import_config.serverConfig); +server.start(); diff --git a/apps/trpc-experimental/server/build/jobs/applicationBuildQueue.js b/apps/trpc-experimental/server/build/jobs/applicationBuildQueue.js new file mode 100644 index 000000000..0c00297a6 --- /dev/null +++ b/apps/trpc-experimental/server/build/jobs/applicationBuildQueue.js @@ -0,0 +1,813 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var import_node_worker_threads = require("node:worker_threads"); +var import_crypto = __toESM(require("crypto")); +var import_promises = __toESM(require("fs/promises")); +var import_js_yaml = __toESM(require("js-yaml")); +var import_common = require("../lib/buildPacks/common"); +var import_common2 = require("../lib/common"); +var importers = __toESM(require("../lib/importers")); +var buildpacks = __toESM(require("../lib/buildPacks")); +var import_prisma = require("../prisma"); +var import_executeCommand = require("../lib/executeCommand"); +var import_docker = require("../lib/docker"); +(async () => { + if (import_node_worker_threads.parentPort) { + import_node_worker_threads.parentPort.on("message", async (message) => { + if (message === "error") + throw new Error("oops"); + if (message === "cancel") { + import_node_worker_threads.parentPort.postMessage("cancelled"); + await import_prisma.prisma.$disconnect(); + process.exit(0); + } + }); + const pThrottle = await import("p-throttle"); + const throttle = pThrottle.default({ + limit: 1, + interval: 2e3 + }); + const th = throttle(async () => { + try { + const queuedBuilds = await import_prisma.prisma.build.findMany({ + where: { status: { in: ["queued", "running"] } }, + orderBy: { createdAt: "asc" } + }); + const { concurrentBuilds } = await import_prisma.prisma.setting.findFirst({}); + if (queuedBuilds.length > 0) { + import_node_worker_threads.parentPort.postMessage({ deploying: true }); + const concurrency = concurrentBuilds; + const pAll = await import("p-all"); + const actions = []; + for (const queueBuild of queuedBuilds) { + actions.push(async () => { + let application = await import_prisma.prisma.application.findUnique({ + where: { id: queueBuild.applicationId }, + include: { + dockerRegistry: true, + destinationDocker: true, + gitSource: { include: { githubApp: true, gitlabApp: true } }, + persistentStorage: true, + secrets: true, + settings: true, + teams: true + } + }); + let { + id: buildId, + type, + gitSourceId, + sourceBranch = null, + pullmergeRequestId = null, + previewApplicationId = null, + forceRebuild, + sourceRepository = null + } = queueBuild; + application = (0, import_common2.decryptApplication)(application); + if (!gitSourceId && application.simpleDockerfile) { + const { + id: applicationId2, + destinationDocker: destinationDocker2, + destinationDockerId: destinationDockerId2, + secrets: secrets2, + port: port2, + persistentStorage: persistentStorage2, + exposePort: exposePort2, + simpleDockerfile, + dockerRegistry: dockerRegistry2 + } = application; + const { workdir: workdir2 } = await (0, import_common2.createDirectories)({ repository: applicationId2, buildId }); + try { + if (queueBuild.status === "running") { + await (0, import_common.saveBuildLog)({ + line: "Building halted, restarting...", + buildId, + applicationId: application.id + }); + } + const volumes = persistentStorage2?.map((storage) => { + if (storage.oldPath) { + return `${applicationId2}${storage.path.replace(/\//gi, "-").replace("-app", "")}:${storage.path}`; + } + return `${applicationId2}${storage.path.replace(/\//gi, "-")}:${storage.path}`; + }) || []; + if (destinationDockerId2) { + await import_prisma.prisma.build.update({ + where: { id: buildId }, + data: { status: "running" } + }); + try { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId2, + command: `docker ps -a --filter 'label=com.docker.compose.service=${applicationId2}' --format {{.ID}}` + }); + if (containers) { + const containerArray = containers.split("\n"); + if (containerArray.length > 0) { + for (const container of containerArray) { + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId2, + command: `docker stop -t 0 ${container}` + }); + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId2, + command: `docker rm --force ${container}` + }); + } + } + } + } catch (error) { + } + let envs = []; + if (secrets2.length > 0) { + envs = [ + ...envs, + ...(0, import_common2.generateSecrets)(secrets2, pullmergeRequestId, false, port2) + ]; + } + await import_promises.default.writeFile(`${workdir2}/Dockerfile`, simpleDockerfile); + if (dockerRegistry2) { + const { url, username, password } = dockerRegistry2; + await (0, import_common.saveDockerRegistryCredentials)({ url, username, password, workdir: workdir2 }); + } + const labels = (0, import_common.makeLabelForSimpleDockerfile)({ + applicationId: applicationId2, + type, + port: exposePort2 ? `${exposePort2}:${port2}` : port2 + }); + try { + const composeVolumes = volumes.map((volume) => { + return { + [`${volume.split(":")[0]}`]: { + name: volume.split(":")[0] + } + }; + }); + const composeFile = { + version: "3.8", + services: { + [applicationId2]: { + build: { + context: workdir2 + }, + image: `${applicationId2}:${buildId}`, + container_name: applicationId2, + volumes, + labels, + environment: envs, + depends_on: [], + expose: [port2], + ...exposePort2 ? { ports: [`${exposePort2}:${port2}`] } : {}, + ...(0, import_docker.defaultComposeConfiguration)(destinationDocker2.network) + } + }, + networks: { + [destinationDocker2.network]: { + external: true + } + }, + volumes: Object.assign({}, ...composeVolumes) + }; + await import_promises.default.writeFile(`${workdir2}/docker-compose.yml`, import_js_yaml.default.dump(composeFile)); + await (0, import_executeCommand.executeCommand)({ + debug: true, + dockerId: destinationDocker2.id, + command: `docker compose --project-directory ${workdir2} up -d` + }); + await (0, import_common.saveBuildLog)({ line: "Deployed \u{1F389}", buildId, applicationId: applicationId2 }); + } catch (error) { + await (0, import_common.saveBuildLog)({ line: error, buildId, applicationId: applicationId2 }); + const foundBuild = await import_prisma.prisma.build.findUnique({ where: { id: buildId } }); + if (foundBuild) { + await import_prisma.prisma.build.update({ + where: { id: buildId }, + data: { + status: "failed" + } + }); + } + throw new Error(error); + } + } + } catch (error) { + const foundBuild = await import_prisma.prisma.build.findUnique({ where: { id: buildId } }); + if (foundBuild) { + await import_prisma.prisma.build.update({ + where: { id: buildId }, + data: { + status: "failed" + } + }); + } + if (error !== 1) { + await (0, import_common.saveBuildLog)({ line: error, buildId, applicationId: application.id }); + } + if (error instanceof Error) { + await (0, import_common.saveBuildLog)({ + line: error.message, + buildId, + applicationId: application.id + }); + } + await import_promises.default.rm(workdir2, { recursive: true, force: true }); + return; + } + try { + if (application.dockerRegistryImageName) { + const customTag2 = application.dockerRegistryImageName.split(":")[1] || buildId; + const imageName2 = application.dockerRegistryImageName.split(":")[0]; + await (0, import_common.saveBuildLog)({ + line: `Pushing ${imageName2}:${customTag2} to Docker Registry... It could take a while...`, + buildId, + applicationId: application.id + }); + await (0, import_common2.pushToRegistry)(application, workdir2, buildId, imageName2, customTag2); + await (0, import_common.saveBuildLog)({ line: "Success", buildId, applicationId: application.id }); + } + } catch (error) { + if (error.stdout) { + await (0, import_common.saveBuildLog)({ line: error.stdout, buildId, applicationId: applicationId2 }); + } + if (error.stderr) { + await (0, import_common.saveBuildLog)({ line: error.stderr, buildId, applicationId: applicationId2 }); + } + } finally { + await import_promises.default.rm(workdir2, { recursive: true, force: true }); + await import_prisma.prisma.build.update({ + where: { id: buildId }, + data: { status: "success" } + }); + } + return; + } + const originalApplicationId = application.id; + const { + id: applicationId, + name, + destinationDocker, + destinationDockerId, + gitSource, + configHash, + fqdn, + projectId, + secrets, + phpModules, + settings, + persistentStorage, + pythonWSGI, + pythonModule, + pythonVariable, + denoOptions, + exposePort, + baseImage, + baseBuildImage, + deploymentType, + gitCommitHash, + dockerRegistry + } = application; + let { + branch, + repository, + buildPack, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory, + dockerFileLocation, + dockerComposeFileLocation, + dockerComposeConfiguration, + denoMainFile + } = application; + let imageId = applicationId; + let domain = (0, import_common2.getDomain)(fqdn); + let location = null; + let tag = null; + let customTag = null; + let imageName = null; + let imageFoundLocally = false; + let imageFoundRemotely = false; + if (pullmergeRequestId) { + const previewApplications = await import_prisma.prisma.previewApplication.findMany({ + where: { applicationId: originalApplicationId, pullmergeRequestId } + }); + if (previewApplications.length > 0) { + previewApplicationId = previewApplications[0].id; + } + branch = sourceBranch; + domain = `${pullmergeRequestId}.${domain}`; + imageId = `${applicationId}-${pullmergeRequestId}`; + repository = sourceRepository || repository; + } + const { workdir, repodir } = await (0, import_common2.createDirectories)({ repository, buildId }); + try { + if (queueBuild.status === "running") { + await (0, import_common.saveBuildLog)({ + line: "Building halted, restarting...", + buildId, + applicationId: application.id + }); + } + const currentHash = import_crypto.default.createHash("sha256").update( + JSON.stringify({ + pythonWSGI, + pythonModule, + pythonVariable, + deploymentType, + denoOptions, + baseImage, + baseBuildImage, + buildPack, + port, + exposePort, + installCommand, + buildCommand, + startCommand, + secrets, + branch, + repository, + fqdn + }) + ).digest("hex"); + const { debug } = settings; + if (!debug) { + await (0, import_common.saveBuildLog)({ + line: `Debug logging is disabled. Enable it above if necessary!`, + buildId, + applicationId + }); + } + const volumes = persistentStorage?.map((storage) => { + if (storage.oldPath) { + return `${applicationId}${storage.path.replace(/\//gi, "-").replace("-app", "")}:${storage.path}`; + } + return `${applicationId}${storage.path.replace(/\//gi, "-")}:${storage.path}`; + }) || []; + try { + dockerComposeConfiguration = JSON.parse(dockerComposeConfiguration); + } catch (error) { + } + let deployNeeded = true; + let destinationType; + if (destinationDockerId) { + destinationType = "docker"; + } + if (destinationType === "docker") { + await import_prisma.prisma.build.update({ + where: { id: buildId }, + data: { status: "running" } + }); + const configuration = await (0, import_common.setDefaultConfiguration)(application); + buildPack = configuration.buildPack; + port = configuration.port; + installCommand = configuration.installCommand; + startCommand = configuration.startCommand; + buildCommand = configuration.buildCommand; + publishDirectory = configuration.publishDirectory; + baseDirectory = configuration.baseDirectory || ""; + dockerFileLocation = configuration.dockerFileLocation; + dockerComposeFileLocation = configuration.dockerComposeFileLocation; + denoMainFile = configuration.denoMainFile; + const commit = await importers[gitSource.type]({ + applicationId, + debug, + workdir, + repodir, + githubAppId: gitSource.githubApp?.id, + gitlabAppId: gitSource.gitlabApp?.id, + customPort: gitSource.customPort, + gitCommitHash, + configuration, + repository, + branch, + buildId, + apiUrl: gitSource.apiUrl, + htmlUrl: gitSource.htmlUrl, + projectId, + deployKeyId: gitSource.gitlabApp?.deployKeyId || null, + privateSshKey: (0, import_common2.decrypt)(gitSource.gitlabApp?.privateSshKey) || null, + forPublic: gitSource.forPublic + }); + if (!commit) { + throw new Error("No commit found?"); + } + tag = commit.slice(0, 7); + if (pullmergeRequestId) { + tag = `${commit.slice(0, 7)}-${pullmergeRequestId}`; + } + if (application.dockerRegistryImageName) { + imageName = application.dockerRegistryImageName.split(":")[0]; + customTag = application.dockerRegistryImageName.split(":")[1] || tag; + } else { + customTag = tag; + imageName = applicationId; + } + if (pullmergeRequestId) { + customTag = `${customTag}-${pullmergeRequestId}`; + } + try { + await import_prisma.prisma.build.update({ where: { id: buildId }, data: { commit } }); + } catch (err) { + } + if (!pullmergeRequestId) { + if (configHash !== currentHash) { + deployNeeded = true; + if (configHash) { + await (0, import_common.saveBuildLog)({ + line: "Configuration changed", + buildId, + applicationId + }); + } + } else { + deployNeeded = false; + } + } else { + deployNeeded = true; + } + try { + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDocker.id, + command: `docker image inspect ${applicationId}:${tag}` + }); + imageFoundLocally = true; + } catch (error) { + } + if (dockerRegistry) { + const { url, username, password } = dockerRegistry; + location = await (0, import_common.saveDockerRegistryCredentials)({ + url, + username, + password, + workdir + }); + } + try { + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDocker.id, + command: `docker ${location ? `--config ${location}` : ""} pull ${imageName}:${customTag}` + }); + imageFoundRemotely = true; + } catch (error) { + } + let imageFound = `${applicationId}:${tag}`; + if (imageFoundRemotely) { + imageFound = `${imageName}:${customTag}`; + } + await (0, import_common.copyBaseConfigurationFiles)( + buildPack, + workdir, + buildId, + applicationId, + baseImage + ); + const labels = (0, import_common.makeLabelForStandaloneApplication)({ + applicationId, + fqdn, + name, + type, + pullmergeRequestId, + buildPack, + repository, + branch, + projectId, + port: exposePort ? `${exposePort}:${port}` : port, + commit, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory + }); + if (forceRebuild) + deployNeeded = true; + if (!imageFoundLocally && !imageFoundRemotely || deployNeeded) { + if (buildPack === "static") { + await buildpacks.staticApp({ + dockerId: destinationDocker.id, + network: destinationDocker.network, + buildId, + applicationId, + domain, + name, + type, + volumes, + labels, + pullmergeRequestId, + buildPack, + repository, + branch, + projectId, + publishDirectory, + debug, + commit, + tag, + workdir, + port: exposePort ? `${exposePort}:${port}` : port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + phpModules, + pythonWSGI, + pythonModule, + pythonVariable, + dockerFileLocation, + dockerComposeConfiguration, + dockerComposeFileLocation, + denoMainFile, + denoOptions, + baseImage, + baseBuildImage, + deploymentType, + forceRebuild + }); + } else if (buildpacks[buildPack]) + await buildpacks[buildPack]({ + dockerId: destinationDocker.id, + network: destinationDocker.network, + buildId, + applicationId, + domain, + name, + type, + volumes, + labels, + pullmergeRequestId, + buildPack, + repository, + branch, + projectId, + publishDirectory, + debug, + commit, + tag, + workdir, + port: exposePort ? `${exposePort}:${port}` : port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + phpModules, + pythonWSGI, + pythonModule, + pythonVariable, + dockerFileLocation, + dockerComposeConfiguration, + dockerComposeFileLocation, + denoMainFile, + denoOptions, + baseImage, + baseBuildImage, + deploymentType, + forceRebuild + }); + else { + await (0, import_common.saveBuildLog)({ + line: `Build pack ${buildPack} not found`, + buildId, + applicationId + }); + throw new Error(`Build pack ${buildPack} not found.`); + } + } else { + if (imageFoundRemotely || deployNeeded) { + await (0, import_common.saveBuildLog)({ + line: `Container image ${imageFound} found in Docker Registry - reuising it`, + buildId, + applicationId + }); + } else { + if (imageFoundLocally || deployNeeded) { + await (0, import_common.saveBuildLog)({ + line: `Container image ${imageFound} found locally - reuising it`, + buildId, + applicationId + }); + } + } + } + if (buildPack === "compose") { + try { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker ps -a --filter 'label=coolify.applicationId=${applicationId}' --format {{.ID}}` + }); + if (containers) { + const containerArray = containers.split("\n"); + if (containerArray.length > 0) { + for (const container of containerArray) { + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker stop -t 0 ${container}` + }); + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker rm --force ${container}` + }); + } + } + } + } catch (error) { + } + try { + await (0, import_executeCommand.executeCommand)({ + debug, + buildId, + applicationId, + dockerId: destinationDocker.id, + command: `docker compose --project-directory ${workdir} up -d` + }); + await (0, import_common.saveBuildLog)({ line: "Deployed \u{1F389}", buildId, applicationId }); + await import_prisma.prisma.build.update({ + where: { id: buildId }, + data: { status: "success" } + }); + await import_prisma.prisma.application.update({ + where: { id: applicationId }, + data: { configHash: currentHash } + }); + } catch (error) { + await (0, import_common.saveBuildLog)({ line: error, buildId, applicationId }); + const foundBuild = await import_prisma.prisma.build.findUnique({ where: { id: buildId } }); + if (foundBuild) { + await import_prisma.prisma.build.update({ + where: { id: buildId }, + data: { + status: "failed" + } + }); + } + throw new Error(error); + } + } else { + try { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker ps -a --filter 'label=com.docker.compose.service=${pullmergeRequestId ? imageId : applicationId}' --format {{.ID}}` + }); + if (containers) { + const containerArray = containers.split("\n"); + if (containerArray.length > 0) { + for (const container of containerArray) { + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker stop -t 0 ${container}` + }); + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker rm --force ${container}` + }); + } + } + } + } catch (error) { + } + let envs = []; + if (secrets.length > 0) { + envs = [ + ...envs, + ...(0, import_common2.generateSecrets)(secrets, pullmergeRequestId, false, port) + ]; + } + if (dockerRegistry) { + const { url, username, password } = dockerRegistry; + await (0, import_common.saveDockerRegistryCredentials)({ url, username, password, workdir }); + } + try { + const composeVolumes = volumes.map((volume) => { + return { + [`${volume.split(":")[0]}`]: { + name: volume.split(":")[0] + } + }; + }); + const composeFile = { + version: "3.8", + services: { + [imageId]: { + image: imageFound, + container_name: imageId, + volumes, + environment: envs, + labels, + depends_on: [], + expose: [port], + ...exposePort ? { ports: [`${exposePort}:${port}`] } : {}, + ...(0, import_docker.defaultComposeConfiguration)(destinationDocker.network) + } + }, + networks: { + [destinationDocker.network]: { + external: true + } + }, + volumes: Object.assign({}, ...composeVolumes) + }; + await import_promises.default.writeFile(`${workdir}/docker-compose.yml`, import_js_yaml.default.dump(composeFile)); + await (0, import_executeCommand.executeCommand)({ + debug, + dockerId: destinationDocker.id, + command: `docker compose --project-directory ${workdir} up -d` + }); + await (0, import_common.saveBuildLog)({ line: "Deployed \u{1F389}", buildId, applicationId }); + } catch (error) { + await (0, import_common.saveBuildLog)({ line: error, buildId, applicationId }); + const foundBuild = await import_prisma.prisma.build.findUnique({ where: { id: buildId } }); + if (foundBuild) { + await import_prisma.prisma.build.update({ + where: { id: buildId }, + data: { + status: "failed" + } + }); + } + throw new Error(error); + } + if (!pullmergeRequestId) + await import_prisma.prisma.application.update({ + where: { id: applicationId }, + data: { configHash: currentHash } + }); + } + } + } catch (error) { + const foundBuild = await import_prisma.prisma.build.findUnique({ where: { id: buildId } }); + if (foundBuild) { + await import_prisma.prisma.build.update({ + where: { id: buildId }, + data: { + status: "failed" + } + }); + } + if (error !== 1) { + await (0, import_common.saveBuildLog)({ line: error, buildId, applicationId: application.id }); + } + if (error instanceof Error) { + await (0, import_common.saveBuildLog)({ + line: error.message, + buildId, + applicationId: application.id + }); + } + await import_promises.default.rm(workdir, { recursive: true, force: true }); + return; + } + try { + if (application.dockerRegistryImageName && (!imageFoundRemotely || forceRebuild)) { + await (0, import_common.saveBuildLog)({ + line: `Pushing ${imageName}:${customTag} to Docker Registry... It could take a while...`, + buildId, + applicationId: application.id + }); + await (0, import_common2.pushToRegistry)(application, workdir, tag, imageName, customTag); + await (0, import_common.saveBuildLog)({ line: "Success", buildId, applicationId: application.id }); + } + } catch (error) { + if (error.stdout) { + await (0, import_common.saveBuildLog)({ line: error.stdout, buildId, applicationId }); + } + if (error.stderr) { + await (0, import_common.saveBuildLog)({ line: error.stderr, buildId, applicationId }); + } + } finally { + await import_promises.default.rm(workdir, { recursive: true, force: true }); + await import_prisma.prisma.build.update({ where: { id: buildId }, data: { status: "success" } }); + } + }); + } + await pAll.default(actions, { concurrency }); + } + } catch (error) { + console.log(error); + } + }); + while (true) { + await th(); + } + } else { + console.log("hello"); + process.exit(0); + } +})(); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/common.js b/apps/trpc-experimental/server/build/lib/buildPacks/common.js new file mode 100644 index 000000000..063f4920f --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/common.js @@ -0,0 +1,842 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var common_exports = {}; +__export(common_exports, { + buildCacheImageForLaravel: () => buildCacheImageForLaravel, + buildCacheImageWithCargo: () => buildCacheImageWithCargo, + buildCacheImageWithNode: () => buildCacheImageWithNode, + buildImage: () => buildImage, + checkPnpm: () => checkPnpm, + copyBaseConfigurationFiles: () => copyBaseConfigurationFiles, + makeLabelForSimpleDockerfile: () => makeLabelForSimpleDockerfile, + makeLabelForStandaloneApplication: () => makeLabelForStandaloneApplication, + saveBuildLog: () => saveBuildLog, + saveDockerRegistryCredentials: () => saveDockerRegistryCredentials, + scanningTemplates: () => scanningTemplates, + setDefaultBaseImage: () => setDefaultBaseImage, + setDefaultConfiguration: () => setDefaultConfiguration +}); +module.exports = __toCommonJS(common_exports); +var import_common = require("../common"); +var import_fs = require("fs"); +var import_dayjs = require("../dayjs"); +var import_prisma = require("../../prisma"); +var import_executeCommand = require("../executeCommand"); +const staticApps = ["static", "react", "vuejs", "svelte", "gatsby", "astro", "eleventy"]; +const nodeBased = [ + "react", + "preact", + "vuejs", + "svelte", + "gatsby", + "astro", + "eleventy", + "node", + "nestjs", + "nuxtjs", + "nextjs" +]; +function setDefaultBaseImage(buildPack, deploymentType = null) { + const nodeVersions = [ + { + value: "node:lts", + label: "node:lts" + }, + { + value: "node:18", + label: "node:18" + }, + { + value: "node:17", + label: "node:17" + }, + { + value: "node:16", + label: "node:16" + }, + { + value: "node:14", + label: "node:14" + }, + { + value: "node:12", + label: "node:12" + } + ]; + const staticVersions = [ + { + value: "webdevops/nginx:alpine", + label: "webdevops/nginx:alpine" + }, + { + value: "webdevops/apache:alpine", + label: "webdevops/apache:alpine" + }, + { + value: "nginx:alpine", + label: "nginx:alpine" + }, + { + value: "httpd:alpine", + label: "httpd:alpine (Apache)" + } + ]; + const rustVersions = [ + { + value: "rust:latest", + label: "rust:latest" + }, + { + value: "rust:1.60", + label: "rust:1.60" + }, + { + value: "rust:1.60-buster", + label: "rust:1.60-buster" + }, + { + value: "rust:1.60-bullseye", + label: "rust:1.60-bullseye" + }, + { + value: "rust:1.60-slim-buster", + label: "rust:1.60-slim-buster" + }, + { + value: "rust:1.60-slim-bullseye", + label: "rust:1.60-slim-bullseye" + }, + { + value: "rust:1.60-alpine3.14", + label: "rust:1.60-alpine3.14" + }, + { + value: "rust:1.60-alpine3.15", + label: "rust:1.60-alpine3.15" + } + ]; + const phpVersions = [ + { + value: "webdevops/php-apache:8.2", + label: "webdevops/php-apache:8.2" + }, + { + value: "webdevops/php-nginx:8.2", + label: "webdevops/php-nginx:8.2" + }, + { + value: "webdevops/php-apache:8.1", + label: "webdevops/php-apache:8.1" + }, + { + value: "webdevops/php-nginx:8.1", + label: "webdevops/php-nginx:8.1" + }, + { + value: "webdevops/php-apache:8.0", + label: "webdevops/php-apache:8.0" + }, + { + value: "webdevops/php-nginx:8.0", + label: "webdevops/php-nginx:8.0" + }, + { + value: "webdevops/php-apache:7.4", + label: "webdevops/php-apache:7.4" + }, + { + value: "webdevops/php-nginx:7.4", + label: "webdevops/php-nginx:7.4" + }, + { + value: "webdevops/php-apache:7.3", + label: "webdevops/php-apache:7.3" + }, + { + value: "webdevops/php-nginx:7.3", + label: "webdevops/php-nginx:7.3" + }, + { + value: "webdevops/php-apache:7.2", + label: "webdevops/php-apache:7.2" + }, + { + value: "webdevops/php-nginx:7.2", + label: "webdevops/php-nginx:7.2" + }, + { + value: "webdevops/php-apache:7.1", + label: "webdevops/php-apache:7.1" + }, + { + value: "webdevops/php-nginx:7.1", + label: "webdevops/php-nginx:7.1" + }, + { + value: "webdevops/php-apache:7.0", + label: "webdevops/php-apache:7.0" + }, + { + value: "webdevops/php-nginx:7.0", + label: "webdevops/php-nginx:7.0" + }, + { + value: "webdevops/php-apache:5.6", + label: "webdevops/php-apache:5.6" + }, + { + value: "webdevops/php-nginx:5.6", + label: "webdevops/php-nginx:5.6" + }, + { + value: "webdevops/php-apache:8.2-alpine", + label: "webdevops/php-apache:8.2-alpine" + }, + { + value: "webdevops/php-nginx:8.2-alpine", + label: "webdevops/php-nginx:8.2-alpine" + }, + { + value: "webdevops/php-apache:8.1-alpine", + label: "webdevops/php-apache:8.1-alpine" + }, + { + value: "webdevops/php-nginx:8.1-alpine", + label: "webdevops/php-nginx:8.1-alpine" + }, + { + value: "webdevops/php-apache:8.0-alpine", + label: "webdevops/php-apache:8.0-alpine" + }, + { + value: "webdevops/php-nginx:8.0-alpine", + label: "webdevops/php-nginx:8.0-alpine" + }, + { + value: "webdevops/php-apache:7.4-alpine", + label: "webdevops/php-apache:7.4-alpine" + }, + { + value: "webdevops/php-nginx:7.4-alpine", + label: "webdevops/php-nginx:7.4-alpine" + }, + { + value: "webdevops/php-apache:7.3-alpine", + label: "webdevops/php-apache:7.3-alpine" + }, + { + value: "webdevops/php-nginx:7.3-alpine", + label: "webdevops/php-nginx:7.3-alpine" + }, + { + value: "webdevops/php-apache:7.2-alpine", + label: "webdevops/php-apache:7.2-alpine" + }, + { + value: "webdevops/php-nginx:7.2-alpine", + label: "webdevops/php-nginx:7.2-alpine" + }, + { + value: "webdevops/php-apache:7.1-alpine", + label: "webdevops/php-apache:7.1-alpine" + }, + { + value: "php:8.1-fpm", + label: "php:8.1-fpm" + }, + { + value: "php:8.0-fpm", + label: "php:8.0-fpm" + }, + { + value: "php:8.1-fpm-alpine", + label: "php:8.1-fpm-alpine" + }, + { + value: "php:8.0-fpm-alpine", + label: "php:8.0-fpm-alpine" + } + ]; + const pythonVersions = [ + { + value: "python:3.10-alpine", + label: "python:3.10-alpine" + }, + { + value: "python:3.10-buster", + label: "python:3.10-buster" + }, + { + value: "python:3.10-bullseye", + label: "python:3.10-bullseye" + }, + { + value: "python:3.10-slim-bullseye", + label: "python:3.10-slim-bullseye" + }, + { + value: "python:3.9-alpine", + label: "python:3.9-alpine" + }, + { + value: "python:3.9-buster", + label: "python:3.9-buster" + }, + { + value: "python:3.9-bullseye", + label: "python:3.9-bullseye" + }, + { + value: "python:3.9-slim-bullseye", + label: "python:3.9-slim-bullseye" + }, + { + value: "python:3.8-alpine", + label: "python:3.8-alpine" + }, + { + value: "python:3.8-buster", + label: "python:3.8-buster" + }, + { + value: "python:3.8-bullseye", + label: "python:3.8-bullseye" + }, + { + value: "python:3.8-slim-bullseye", + label: "python:3.8-slim-bullseye" + }, + { + value: "python:3.7-alpine", + label: "python:3.7-alpine" + }, + { + value: "python:3.7-buster", + label: "python:3.7-buster" + }, + { + value: "python:3.7-bullseye", + label: "python:3.7-bullseye" + }, + { + value: "python:3.7-slim-bullseye", + label: "python:3.7-slim-bullseye" + } + ]; + const herokuVersions = [ + { + value: "heroku/builder:22", + label: "heroku/builder:22" + }, + { + value: "heroku/buildpacks:20", + label: "heroku/buildpacks:20" + }, + { + value: "heroku/builder-classic:22", + label: "heroku/builder-classic:22" + } + ]; + let payload = { + baseImage: null, + baseBuildImage: null, + baseImages: [], + baseBuildImages: [] + }; + if (nodeBased.includes(buildPack)) { + if (deploymentType === "static") { + payload.baseImage = (0, import_common.isARM)(process.arch) ? "nginx:alpine" : "webdevops/nginx:alpine"; + payload.baseImages = (0, import_common.isARM)(process.arch) ? staticVersions.filter((version2) => !version2.value.includes("webdevops")) : staticVersions; + payload.baseBuildImage = "node:lts"; + payload.baseBuildImages = nodeVersions; + } else { + payload.baseImage = "node:lts"; + payload.baseImages = nodeVersions; + payload.baseBuildImage = "node:lts"; + payload.baseBuildImages = nodeVersions; + } + } + if (staticApps.includes(buildPack)) { + payload.baseImage = (0, import_common.isARM)(process.arch) ? "nginx:alpine" : "webdevops/nginx:alpine"; + payload.baseImages = (0, import_common.isARM)(process.arch) ? staticVersions.filter((version2) => !version2.value.includes("webdevops")) : staticVersions; + payload.baseBuildImage = "node:lts"; + payload.baseBuildImages = nodeVersions; + } + if (buildPack === "python") { + payload.baseImage = "python:3.10-alpine"; + payload.baseImages = pythonVersions; + } + if (buildPack === "rust") { + payload.baseImage = "rust:latest"; + payload.baseBuildImage = "rust:latest"; + payload.baseImages = rustVersions; + payload.baseBuildImages = rustVersions; + } + if (buildPack === "deno") { + payload.baseImage = "denoland/deno:latest"; + } + if (buildPack === "php") { + payload.baseImage = (0, import_common.isARM)(process.arch) ? "php:8.1-fpm-alpine" : "webdevops/php-apache:8.2-alpine"; + payload.baseImages = (0, import_common.isARM)(process.arch) ? phpVersions.filter((version2) => !version2.value.includes("webdevops")) : phpVersions; + } + if (buildPack === "laravel") { + payload.baseImage = (0, import_common.isARM)(process.arch) ? "php:8.1-fpm-alpine" : "webdevops/php-apache:8.2-alpine"; + payload.baseImages = (0, import_common.isARM)(process.arch) ? phpVersions.filter((version2) => !version2.value.includes("webdevops")) : phpVersions; + payload.baseBuildImage = "node:18"; + payload.baseBuildImages = nodeVersions; + } + if (buildPack === "heroku") { + payload.baseImage = "heroku/buildpacks:20"; + payload.baseImages = herokuVersions; + } + return payload; +} +const setDefaultConfiguration = async (data) => { + let { + buildPack, + port, + installCommand, + startCommand, + buildCommand, + publishDirectory, + baseDirectory, + dockerFileLocation, + dockerComposeFileLocation, + denoMainFile + } = data; + const template = scanningTemplates[buildPack]; + if (!port) { + port = template?.port || 3e3; + if (buildPack === "static") + port = 80; + else if (buildPack === "node") + port = 3e3; + else if (buildPack === "php") + port = 80; + else if (buildPack === "python") + port = 8e3; + } + if (!installCommand && buildPack !== "static" && buildPack !== "laravel") + installCommand = template?.installCommand || "yarn install"; + if (!startCommand && buildPack !== "static" && buildPack !== "laravel") + startCommand = template?.startCommand || "yarn start"; + if (!buildCommand && buildPack !== "static" && buildPack !== "laravel") + buildCommand = template?.buildCommand || null; + if (!publishDirectory) + publishDirectory = template?.publishDirectory || null; + if (baseDirectory) { + if (!baseDirectory.startsWith("/")) + baseDirectory = `/${baseDirectory}`; + if (baseDirectory.endsWith("/") && baseDirectory !== "/") + baseDirectory = baseDirectory.slice(0, -1); + } + if (dockerFileLocation) { + if (!dockerFileLocation.startsWith("/")) + dockerFileLocation = `/${dockerFileLocation}`; + if (dockerFileLocation.endsWith("/")) + dockerFileLocation = dockerFileLocation.slice(0, -1); + } else { + dockerFileLocation = "/Dockerfile"; + } + if (dockerComposeFileLocation) { + if (!dockerComposeFileLocation.startsWith("/")) + dockerComposeFileLocation = `/${dockerComposeFileLocation}`; + if (dockerComposeFileLocation.endsWith("/")) + dockerComposeFileLocation = dockerComposeFileLocation.slice(0, -1); + } else { + dockerComposeFileLocation = "/Dockerfile"; + } + if (!denoMainFile) { + denoMainFile = "main.ts"; + } + return { + buildPack, + port, + installCommand, + startCommand, + buildCommand, + publishDirectory, + baseDirectory, + dockerFileLocation, + dockerComposeFileLocation, + denoMainFile + }; +}; +const scanningTemplates = { + "@sveltejs/kit": { + buildPack: "nodejs" + }, + astro: { + buildPack: "astro" + }, + "@11ty/eleventy": { + buildPack: "eleventy" + }, + svelte: { + buildPack: "svelte" + }, + "@nestjs/core": { + buildPack: "nestjs" + }, + next: { + buildPack: "nextjs" + }, + nuxt: { + buildPack: "nuxtjs" + }, + "react-scripts": { + buildPack: "react" + }, + "parcel-bundler": { + buildPack: "static" + }, + "@vue/cli-service": { + buildPack: "vuejs" + }, + vuejs: { + buildPack: "vuejs" + }, + gatsby: { + buildPack: "gatsby" + }, + "preact-cli": { + buildPack: "react" + } +}; +const saveBuildLog = async ({ + line, + buildId, + applicationId +}) => { + if (buildId === "undefined" || buildId === "null" || !buildId) + return; + if (applicationId === "undefined" || applicationId === "null" || !applicationId) + return; + const { default: got } = await import("got"); + if (typeof line === "object" && line) { + if (line.shortMessage) { + line = line.shortMessage + "\n" + line.stderr; + } else { + line = JSON.stringify(line); + } + } + if (line && typeof line === "string" && line.includes("ghs_")) { + const regex = /ghs_.*@/g; + line = line.replace(regex, "@"); + } + const addTimestamp = `[${(0, import_common.generateTimestamp)()}] ${line}`; + const fluentBitUrl = import_common.isDev ? process.env.COOLIFY_CONTAINER_DEV === "true" ? "http://coolify-fluentbit:24224" : "http://localhost:24224" : "http://coolify-fluentbit:24224"; + if (import_common.isDev && !process.env.COOLIFY_CONTAINER_DEV) { + console.debug(`[${applicationId}] ${addTimestamp}`); + } + try { + return await got.post(`${fluentBitUrl}/${applicationId}_buildlog_${buildId}.csv`, { + json: { + line: (0, import_common.encrypt)(line) + } + }); + } catch (error) { + return await import_prisma.prisma.buildLog.create({ + data: { + line: addTimestamp, + buildId, + time: Number((0, import_dayjs.day)().valueOf()), + applicationId + } + }); + } +}; +async function copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage) { + try { + if (buildPack === "php") { + await import_fs.promises.writeFile(`${workdir}/entrypoint.sh`, `chown -R 1000 /app`); + await saveBuildLog({ + line: "Copied default configuration file for PHP.", + buildId, + applicationId + }); + } else if (baseImage?.includes("nginx")) { + await import_fs.promises.writeFile( + `${workdir}/nginx.conf`, + `user nginx; + worker_processes auto; + + error_log /docker.stdout; + pid /run/nginx.pid; + + events { + worker_connections 1024; + } + + http { + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /docker.stdout main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + server_name localhost; + + location / { + root /app; + index index.html; + try_files $uri $uri/index.html $uri/ /index.html =404; + } + + error_page 404 /50x.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /app; + } + + } + + } + ` + ); + } + } catch (error) { + throw new Error(error); + } +} +function checkPnpm(installCommand = null, buildCommand = null, startCommand = null) { + return installCommand?.includes("pnpm") || buildCommand?.includes("pnpm") || startCommand?.includes("pnpm"); +} +async function saveDockerRegistryCredentials({ url, username, password, workdir }) { + if (!username || !password) { + return null; + } + let decryptedPassword = (0, import_common.decrypt)(password); + const location = `${workdir}/.docker`; + try { + await import_fs.promises.mkdir(`${workdir}/.docker`); + } catch (error) { + } + const payload = JSON.stringify({ + auths: { + [url]: { + auth: Buffer.from(`${username}:${decryptedPassword}`).toString("base64") + } + } + }); + await import_fs.promises.writeFile(`${location}/config.json`, payload); + return location; +} +async function buildImage({ + applicationId, + tag, + workdir, + buildId, + dockerId, + isCache = false, + debug = false, + dockerFileLocation = "/Dockerfile", + commit, + forceRebuild = false +}) { + if (isCache) { + await saveBuildLog({ line: `Building cache image...`, buildId, applicationId }); + } else { + await saveBuildLog({ line: `Building production image...`, buildId, applicationId }); + } + const dockerFile = isCache ? `${dockerFileLocation}-cache` : `${dockerFileLocation}`; + const cache = `${applicationId}:${tag}${isCache ? "-cache" : ""}`; + let location = null; + const { dockerRegistry } = await import_prisma.prisma.application.findUnique({ + where: { id: applicationId }, + select: { dockerRegistry: true } + }); + if (dockerRegistry) { + const { url, username, password } = dockerRegistry; + location = await saveDockerRegistryCredentials({ url, username, password, workdir }); + } + await (0, import_executeCommand.executeCommand)({ + stream: true, + debug, + buildId, + applicationId, + dockerId, + command: `docker ${location ? `--config ${location}` : ""} build ${forceRebuild ? "--no-cache" : ""} --progress plain -f ${workdir}/${dockerFile} -t ${cache} --build-arg SOURCE_COMMIT=${commit} ${workdir}` + }); + const { status } = await import_prisma.prisma.build.findUnique({ where: { id: buildId } }); + if (status === "canceled") { + throw new Error("Canceled."); + } +} +function makeLabelForSimpleDockerfile({ applicationId, port, type }) { + return [ + "coolify.managed=true", + `coolify.version=${import_common.version}`, + `coolify.applicationId=${applicationId}`, + `coolify.type=standalone-application` + ]; +} +function makeLabelForStandaloneApplication({ + applicationId, + fqdn, + name, + type, + pullmergeRequestId = null, + buildPack, + repository, + branch, + projectId, + port, + commit, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory +}) { + if (pullmergeRequestId) { + const protocol = fqdn.startsWith("https://") ? "https" : "http"; + const domain = (0, import_common.getDomain)(fqdn); + fqdn = `${protocol}://${pullmergeRequestId}.${domain}`; + } + return [ + "coolify.managed=true", + `coolify.version=${import_common.version}`, + `coolify.applicationId=${applicationId}`, + `coolify.type=standalone-application`, + `coolify.name=${name}`, + `coolify.configuration=${(0, import_common.base64Encode)( + JSON.stringify({ + applicationId, + fqdn, + name, + type, + pullmergeRequestId, + buildPack, + repository, + branch, + projectId, + port, + commit, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory + }) + )}` + ]; +} +async function buildCacheImageWithNode(data, imageForBuild) { + const { + workdir, + buildId, + baseDirectory, + installCommand, + buildCommand, + secrets, + pullmergeRequestId + } = data; + const isPnpm = checkPnpm(installCommand, buildCommand); + const Dockerfile = []; + Dockerfile.push(`FROM ${imageForBuild}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.push(env); + }); + } + if (isPnpm) { + Dockerfile.push("RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm@7"); + } + Dockerfile.push(`COPY .${baseDirectory || ""} ./`); + if (installCommand) { + Dockerfile.push(`RUN ${installCommand}`); + } + Dockerfile.push(`RUN ${buildCommand}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile-cache`, Dockerfile.join("\n")); + await buildImage({ ...data, isCache: true }); +} +async function buildCacheImageForLaravel(data, imageForBuild) { + const { workdir, buildId, secrets, pullmergeRequestId } = data; + const Dockerfile = []; + Dockerfile.push(`FROM ${imageForBuild}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.push(env); + }); + } + Dockerfile.push(`COPY *.json *.mix.js /app/`); + Dockerfile.push(`COPY resources /app/resources`); + Dockerfile.push(`RUN yarn install && yarn production`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile-cache`, Dockerfile.join("\n")); + await buildImage({ ...data, isCache: true }); +} +async function buildCacheImageWithCargo(data, imageForBuild) { + const { applicationId, workdir, buildId } = data; + const Dockerfile = []; + Dockerfile.push(`FROM ${imageForBuild} as planner-${applicationId}`); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push("RUN cargo install cargo-chef"); + Dockerfile.push("COPY . ."); + Dockerfile.push("RUN cargo chef prepare --recipe-path recipe.json"); + Dockerfile.push(`FROM ${imageForBuild}`); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push("RUN cargo install cargo-chef"); + Dockerfile.push(`COPY --from=planner-${applicationId} /app/recipe.json recipe.json`); + Dockerfile.push("RUN cargo chef cook --release --recipe-path recipe.json"); + await import_fs.promises.writeFile(`${workdir}/Dockerfile-cache`, Dockerfile.join("\n")); + await buildImage({ ...data, isCache: true }); +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + buildCacheImageForLaravel, + buildCacheImageWithCargo, + buildCacheImageWithNode, + buildImage, + checkPnpm, + copyBaseConfigurationFiles, + makeLabelForSimpleDockerfile, + makeLabelForStandaloneApplication, + saveBuildLog, + saveDockerRegistryCredentials, + scanningTemplates, + setDefaultBaseImage, + setDefaultConfiguration +}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/compose.js b/apps/trpc-experimental/server/build/lib/buildPacks/compose.js new file mode 100644 index 000000000..073711e91 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/compose.js @@ -0,0 +1,137 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var compose_exports = {}; +__export(compose_exports, { + default: () => compose_default +}); +module.exports = __toCommonJS(compose_exports); +var import_fs = require("fs"); +var import_common = require("../common"); +var import_common2 = require("./common"); +var import_js_yaml = __toESM(require("js-yaml")); +var import_docker = require("../docker"); +var import_executeCommand = require("../executeCommand"); +async function compose_default(data) { + let { + applicationId, + debug, + buildId, + dockerId, + network, + volumes, + labels, + workdir, + baseDirectory, + secrets, + pullmergeRequestId, + dockerComposeConfiguration, + dockerComposeFileLocation + } = data; + const fileYaml = `${workdir}${baseDirectory}${dockerComposeFileLocation}`; + const dockerComposeRaw = await import_fs.promises.readFile(fileYaml, "utf8"); + const dockerComposeYaml = import_js_yaml.default.load(dockerComposeRaw); + if (!dockerComposeYaml.services) { + throw "No Services found in docker-compose file."; + } + let envs = []; + if (secrets.length > 0) { + envs = [...envs, ...(0, import_common.generateSecrets)(secrets, pullmergeRequestId, false, null)]; + } + const composeVolumes = []; + if (volumes.length > 0) { + for (const volume of volumes) { + let [v, path] = volume.split(":"); + composeVolumes[v] = { + name: v + }; + } + } + let networks = {}; + for (let [key, value] of Object.entries(dockerComposeYaml.services)) { + value["container_name"] = `${applicationId}-${key}`; + let environment = typeof value["environment"] === "undefined" ? [] : value["environment"]; + value["environment"] = [...environment, ...envs]; + value["labels"] = labels; + if (value["volumes"]?.length > 0) { + value["volumes"] = value["volumes"].map((volume) => { + let [v, path, permission] = volume.split(":"); + if (!path) { + path = v; + v = `${applicationId}${v.replace(/\//gi, "-").replace(/\./gi, "")}`; + } else { + v = `${applicationId}${v.replace(/\//gi, "-").replace(/\./gi, "")}`; + } + composeVolumes[v] = { + name: v + }; + return `${v}:${path}${permission ? ":" + permission : ""}`; + }); + } + if (volumes.length > 0) { + for (const volume of volumes) { + value["volumes"].push(volume); + } + } + if (dockerComposeConfiguration[key].port) { + value["expose"] = [dockerComposeConfiguration[key].port]; + } + if (value["networks"]?.length > 0) { + value["networks"].forEach((network2) => { + networks[network2] = { + name: network2 + }; + }); + } + value["networks"] = [...value["networks"] || "", network]; + dockerComposeYaml.services[key] = { + ...dockerComposeYaml.services[key], + restart: (0, import_docker.defaultComposeConfiguration)(network).restart, + deploy: (0, import_docker.defaultComposeConfiguration)(network).deploy + }; + } + if (Object.keys(composeVolumes).length > 0) { + dockerComposeYaml["volumes"] = { ...composeVolumes }; + } + dockerComposeYaml["networks"] = Object.assign({ ...networks }, { [network]: { external: true } }); + await import_fs.promises.writeFile(fileYaml, import_js_yaml.default.dump(dockerComposeYaml)); + await (0, import_executeCommand.executeCommand)({ + debug, + buildId, + applicationId, + dockerId, + command: `docker compose --project-directory ${workdir} pull` + }); + await (0, import_common2.saveBuildLog)({ line: "Pulling images from Compose file...", buildId, applicationId }); + await (0, import_executeCommand.executeCommand)({ + debug, + buildId, + applicationId, + dockerId, + command: `docker compose --project-directory ${workdir} build --progress plain` + }); + await (0, import_common2.saveBuildLog)({ line: "Building images from Compose file...", buildId, applicationId }); +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/deno.js b/apps/trpc-experimental/server/build/lib/buildPacks/deno.js new file mode 100644 index 000000000..2c03960c7 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/deno.js @@ -0,0 +1,74 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var deno_exports = {}; +__export(deno_exports, { + default: () => deno_default +}); +module.exports = __toCommonJS(deno_exports); +var import_fs = require("fs"); +var import_common = require("../common"); +var import_common2 = require("./common"); +const createDockerfile = async (data, image) => { + const { + workdir, + port, + baseDirectory, + secrets, + pullmergeRequestId, + denoMainFile, + denoOptions, + buildId + } = data; + const Dockerfile = []; + let depsFound = false; + try { + await import_fs.promises.readFile(`${workdir}${baseDirectory || ""}/deps.ts`); + depsFound = true; + } catch (error) { + } + Dockerfile.push(`FROM ${image}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.push(env); + }); + } + if (depsFound) { + Dockerfile.push(`COPY .${baseDirectory || ""}/deps.ts /app`); + Dockerfile.push(`RUN deno cache deps.ts`); + } + Dockerfile.push(`COPY .${baseDirectory || ""} ./`); + Dockerfile.push(`RUN deno cache ${denoMainFile}`); + Dockerfile.push(`ENV NO_COLOR true`); + Dockerfile.push(`EXPOSE ${port}`); + Dockerfile.push(`CMD deno run ${denoOptions || ""} ${denoMainFile}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function deno_default(data) { + try { + const { baseImage, baseBuildImage } = data; + await createDockerfile(data, baseImage); + await (0, import_common2.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/docker.js b/apps/trpc-experimental/server/build/lib/buildPacks/docker.js new file mode 100644 index 000000000..02cde82c2 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/docker.js @@ -0,0 +1,51 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var docker_exports = {}; +__export(docker_exports, { + default: () => docker_default +}); +module.exports = __toCommonJS(docker_exports); +var import_fs = require("fs"); +var import_common = require("../common"); +var import_common2 = require("./common"); +async function docker_default(data) { + let { workdir, buildId, baseDirectory, secrets, pullmergeRequestId, dockerFileLocation } = data; + const file = `${workdir}${baseDirectory}${dockerFileLocation}`; + data.workdir = `${workdir}${baseDirectory}`; + const DockerfileRaw = await import_fs.promises.readFile(`${file}`, "utf8"); + const Dockerfile = DockerfileRaw.toString().trim().split("\n"); + Dockerfile.forEach((line, index) => { + if (line.startsWith("FROM")) { + Dockerfile.splice(index + 1, 0, `LABEL coolify.buildId=${buildId}`); + } + }); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.forEach((line, index) => { + if (line.startsWith("FROM")) { + Dockerfile.splice(index + 1, 0, env); + } + }); + }); + } + await import_fs.promises.writeFile(`${data.workdir}${dockerFileLocation}`, Dockerfile.join("\n")); + await (0, import_common2.buildImage)(data); +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/gatsby.js b/apps/trpc-experimental/server/build/lib/buildPacks/gatsby.js new file mode 100644 index 000000000..b71e587ab --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/gatsby.js @@ -0,0 +1,50 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var gatsby_exports = {}; +__export(gatsby_exports, { + default: () => gatsby_default +}); +module.exports = __toCommonJS(gatsby_exports); +var import_fs = require("fs"); +var import_common = require("./common"); +const createDockerfile = async (data, imageforBuild) => { + const { applicationId, tag, workdir, publishDirectory, baseImage, buildId, port } = data; + const Dockerfile = []; + Dockerfile.push(`FROM ${imageforBuild}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); + if (baseImage?.includes("nginx")) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } + Dockerfile.push(`EXPOSE ${port}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function gatsby_default(data) { + try { + const { baseImage, baseBuildImage } = data; + await (0, import_common.buildCacheImageWithNode)(data, baseBuildImage); + await createDockerfile(data, baseImage); + await (0, import_common.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/heroku.js b/apps/trpc-experimental/server/build/lib/buildPacks/heroku.js new file mode 100644 index 000000000..6b5627a51 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/heroku.js @@ -0,0 +1,41 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var heroku_exports = {}; +__export(heroku_exports, { + default: () => heroku_default +}); +module.exports = __toCommonJS(heroku_exports); +var import_executeCommand = require("../executeCommand"); +var import_common = require("./common"); +async function heroku_default(data) { + const { buildId, applicationId, tag, dockerId, debug, workdir, baseDirectory, baseImage } = data; + try { + await (0, import_common.saveBuildLog)({ line: `Building production image...`, buildId, applicationId }); + await (0, import_executeCommand.executeCommand)({ + buildId, + debug, + dockerId, + command: `pack build -p ${workdir}${baseDirectory} ${applicationId}:${tag} --builder ${baseImage}` + }); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/index.js b/apps/trpc-experimental/server/build/lib/buildPacks/index.js new file mode 100644 index 000000000..5f4590110 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/index.js @@ -0,0 +1,88 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var buildPacks_exports = {}; +__export(buildPacks_exports, { + astro: () => import_static2.default, + compose: () => import_compose.default, + deno: () => import_deno.default, + docker: () => import_docker.default, + eleventy: () => import_static3.default, + gatsby: () => import_gatsby.default, + heroku: () => import_heroku.default, + laravel: () => import_laravel.default, + nestjs: () => import_nestjs.default, + nextjs: () => import_nextjs.default, + node: () => import_node.default, + nuxtjs: () => import_nuxtjs.default, + php: () => import_php.default, + python: () => import_python.default, + react: () => import_react.default, + rust: () => import_rust.default, + staticApp: () => import_static.default, + svelte: () => import_svelte.default, + vuejs: () => import_vuejs.default +}); +module.exports = __toCommonJS(buildPacks_exports); +var import_node = __toESM(require("./node")); +var import_static = __toESM(require("./static")); +var import_docker = __toESM(require("./docker")); +var import_gatsby = __toESM(require("./gatsby")); +var import_svelte = __toESM(require("./svelte")); +var import_react = __toESM(require("./react")); +var import_nestjs = __toESM(require("./nestjs")); +var import_nextjs = __toESM(require("./nextjs")); +var import_nuxtjs = __toESM(require("./nuxtjs")); +var import_vuejs = __toESM(require("./vuejs")); +var import_php = __toESM(require("./php")); +var import_rust = __toESM(require("./rust")); +var import_static2 = __toESM(require("./static")); +var import_static3 = __toESM(require("./static")); +var import_python = __toESM(require("./python")); +var import_deno = __toESM(require("./deno")); +var import_laravel = __toESM(require("./laravel")); +var import_heroku = __toESM(require("./heroku")); +var import_compose = __toESM(require("./compose")); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + astro, + compose, + deno, + docker, + eleventy, + gatsby, + heroku, + laravel, + nestjs, + nextjs, + node, + nuxtjs, + php, + python, + react, + rust, + staticApp, + svelte, + vuejs +}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/laravel.js b/apps/trpc-experimental/server/build/lib/buildPacks/laravel.js new file mode 100644 index 000000000..6bd5237a1 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/laravel.js @@ -0,0 +1,68 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var laravel_exports = {}; +__export(laravel_exports, { + default: () => laravel_default +}); +module.exports = __toCommonJS(laravel_exports); +var import_fs = require("fs"); +var import_common = require("../common"); +var import_common2 = require("./common"); +const createDockerfile = async (data, image) => { + const { workdir, applicationId, tag, buildId, port, secrets, pullmergeRequestId } = data; + const Dockerfile = []; + Dockerfile.push(`FROM ${image}`); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.push(env); + }); + } + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`ENV WEB_DOCUMENT_ROOT /app/public`); + Dockerfile.push(`COPY --chown=application:application composer.* ./`); + Dockerfile.push(`COPY --chown=application:application database/ database/`); + Dockerfile.push( + `RUN composer install --ignore-platform-reqs --no-interaction --no-plugins --no-scripts --prefer-dist` + ); + Dockerfile.push( + `COPY --chown=application:application --from=${applicationId}:${tag}-cache /app/public/js/ /app/public/js/` + ); + Dockerfile.push( + `COPY --chown=application:application --from=${applicationId}:${tag}-cache /app/public/css/ /app/public/css/` + ); + Dockerfile.push( + `COPY --chown=application:application --from=${applicationId}:${tag}-cache /app/mix-manifest.json /app/public/mix-manifest.json` + ); + Dockerfile.push(`COPY --chown=application:application . ./`); + Dockerfile.push(`EXPOSE ${port}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function laravel_default(data) { + const { baseImage, baseBuildImage } = data; + try { + await (0, import_common2.buildCacheImageForLaravel)(data, baseBuildImage); + await createDockerfile(data, baseImage); + await (0, import_common2.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/nestjs.js b/apps/trpc-experimental/server/build/lib/buildPacks/nestjs.js new file mode 100644 index 000000000..945a0f960 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/nestjs.js @@ -0,0 +1,52 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var nestjs_exports = {}; +__export(nestjs_exports, { + default: () => nestjs_default +}); +module.exports = __toCommonJS(nestjs_exports); +var import_fs = require("fs"); +var import_common = require("./common"); +const createDockerfile = async (data, image) => { + const { buildId, applicationId, tag, port, startCommand, workdir, baseDirectory } = data; + const Dockerfile = []; + const isPnpm = startCommand.includes("pnpm"); + Dockerfile.push(`FROM ${image}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (isPnpm) { + Dockerfile.push("RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm@7"); + } + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${baseDirectory || ""} ./`); + Dockerfile.push(`EXPOSE ${port}`); + Dockerfile.push(`CMD ${startCommand}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function nestjs_default(data) { + try { + const { baseImage, baseBuildImage } = data; + await (0, import_common.buildCacheImageWithNode)(data, baseBuildImage); + await createDockerfile(data, baseImage); + await (0, import_common.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/nextjs.js b/apps/trpc-experimental/server/build/lib/buildPacks/nextjs.js new file mode 100644 index 000000000..57a9aced1 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/nextjs.js @@ -0,0 +1,89 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var nextjs_exports = {}; +__export(nextjs_exports, { + default: () => nextjs_default +}); +module.exports = __toCommonJS(nextjs_exports); +var import_fs = require("fs"); +var import_common = require("../common"); +var import_common2 = require("./common"); +const createDockerfile = async (data, image) => { + const { + applicationId, + buildId, + tag, + workdir, + publishDirectory, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + pullmergeRequestId, + deploymentType, + baseImage + } = data; + const Dockerfile = []; + const isPnpm = (0, import_common2.checkPnpm)(installCommand, buildCommand, startCommand); + Dockerfile.push(`FROM ${image}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.push(env); + }); + } + if (isPnpm) { + Dockerfile.push("RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm@7"); + } + if (deploymentType === "node") { + Dockerfile.push(`COPY .${baseDirectory || ""} ./`); + Dockerfile.push(`RUN ${installCommand}`); + Dockerfile.push(`RUN ${buildCommand}`); + Dockerfile.push(`EXPOSE ${port}`); + Dockerfile.push(`CMD ${startCommand}`); + } else if (deploymentType === "static") { + if (baseImage?.includes("nginx")) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); + Dockerfile.push(`EXPOSE 80`); + } + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function nextjs_default(data) { + try { + const { baseImage, baseBuildImage, deploymentType, buildCommand } = data; + if (deploymentType === "node") { + await createDockerfile(data, baseImage); + await (0, import_common2.buildImage)(data); + } else if (deploymentType === "static") { + if (buildCommand) + await (0, import_common2.buildCacheImageWithNode)(data, baseBuildImage); + await createDockerfile(data, baseImage); + await (0, import_common2.buildImage)(data); + } + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/node.js b/apps/trpc-experimental/server/build/lib/buildPacks/node.js new file mode 100644 index 000000000..e1d246e22 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/node.js @@ -0,0 +1,71 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var node_exports = {}; +__export(node_exports, { + default: () => node_default +}); +module.exports = __toCommonJS(node_exports); +var import_fs = require("fs"); +var import_common = require("../common"); +var import_common2 = require("./common"); +const createDockerfile = async (data, image) => { + const { + workdir, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + pullmergeRequestId, + buildId + } = data; + const Dockerfile = []; + const isPnpm = (0, import_common2.checkPnpm)(installCommand, buildCommand, startCommand); + Dockerfile.push(`FROM ${image}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.push(env); + }); + } + if (isPnpm) { + Dockerfile.push("RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm@7"); + } + Dockerfile.push(`COPY .${baseDirectory || ""} ./`); + Dockerfile.push(`RUN ${installCommand}`); + if (buildCommand) { + Dockerfile.push(`RUN ${buildCommand}`); + } + Dockerfile.push(`EXPOSE ${port}`); + Dockerfile.push(`CMD ${startCommand}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function node_default(data) { + try { + const { baseImage } = data; + await createDockerfile(data, baseImage); + await (0, import_common2.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/nuxtjs.js b/apps/trpc-experimental/server/build/lib/buildPacks/nuxtjs.js new file mode 100644 index 000000000..edc953bf2 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/nuxtjs.js @@ -0,0 +1,89 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var nuxtjs_exports = {}; +__export(nuxtjs_exports, { + default: () => nuxtjs_default +}); +module.exports = __toCommonJS(nuxtjs_exports); +var import_fs = require("fs"); +var import_common = require("../common"); +var import_common2 = require("./common"); +const createDockerfile = async (data, image) => { + const { + applicationId, + buildId, + tag, + workdir, + publishDirectory, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + pullmergeRequestId, + deploymentType, + baseImage + } = data; + const Dockerfile = []; + const isPnpm = (0, import_common2.checkPnpm)(installCommand, buildCommand, startCommand); + Dockerfile.push(`FROM ${image}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.push(env); + }); + } + if (isPnpm) { + Dockerfile.push("RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm@7"); + } + if (deploymentType === "node") { + Dockerfile.push(`COPY .${baseDirectory || ""} ./`); + Dockerfile.push(`RUN ${installCommand}`); + Dockerfile.push(`RUN ${buildCommand}`); + Dockerfile.push(`EXPOSE ${port}`); + Dockerfile.push(`CMD ${startCommand}`); + } else if (deploymentType === "static") { + if (baseImage?.includes("nginx")) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); + Dockerfile.push(`EXPOSE 80`); + } + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function nuxtjs_default(data) { + try { + const { baseImage, baseBuildImage, deploymentType, buildCommand } = data; + if (deploymentType === "node") { + await createDockerfile(data, baseImage); + await (0, import_common2.buildImage)(data); + } else if (deploymentType === "static") { + if (buildCommand) + await (0, import_common2.buildCacheImageWithNode)(data, baseBuildImage); + await createDockerfile(data, baseImage); + await (0, import_common2.buildImage)(data); + } + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/php.js b/apps/trpc-experimental/server/build/lib/buildPacks/php.js new file mode 100644 index 000000000..e68b46cd0 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/php.js @@ -0,0 +1,71 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var php_exports = {}; +__export(php_exports, { + default: () => php_default +}); +module.exports = __toCommonJS(php_exports); +var import_fs = require("fs"); +var import_common = require("../common"); +var import_common2 = require("./common"); +const createDockerfile = async (data, image, htaccessFound) => { + const { workdir, baseDirectory, buildId, port, secrets, pullmergeRequestId } = data; + const Dockerfile = []; + let composerFound = false; + try { + await import_fs.promises.readFile(`${workdir}${baseDirectory || ""}/composer.json`); + composerFound = true; + } catch (error) { + } + Dockerfile.push(`FROM ${image}`); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.push(env); + }); + } + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`COPY .${baseDirectory || ""} /app`); + if (htaccessFound) { + Dockerfile.push(`COPY .${baseDirectory || ""}/.htaccess ./`); + } + if (composerFound) { + Dockerfile.push(`RUN composer install`); + } + Dockerfile.push(`COPY /entrypoint.sh /opt/docker/provision/entrypoint.d/30-entrypoint.sh`); + Dockerfile.push(`EXPOSE ${port}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function php_default(data) { + const { workdir, baseDirectory, baseImage } = data; + try { + let htaccessFound = false; + try { + await import_fs.promises.readFile(`${workdir}${baseDirectory || ""}/.htaccess`); + htaccessFound = true; + } catch (e) { + } + await createDockerfile(data, baseImage, htaccessFound); + await (0, import_common2.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/python.js b/apps/trpc-experimental/server/build/lib/buildPacks/python.js new file mode 100644 index 000000000..9221d5d66 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/python.js @@ -0,0 +1,86 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var python_exports = {}; +__export(python_exports, { + default: () => python_default +}); +module.exports = __toCommonJS(python_exports); +var import_fs = require("fs"); +var import_common = require("../common"); +var import_common2 = require("./common"); +const createDockerfile = async (data, image) => { + const { + workdir, + port, + baseDirectory, + secrets, + pullmergeRequestId, + pythonWSGI, + pythonModule, + pythonVariable, + buildId + } = data; + const Dockerfile = []; + Dockerfile.push(`FROM ${image}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.push(env); + }); + } + if (pythonWSGI?.toLowerCase() === "gunicorn") { + Dockerfile.push(`RUN pip install gunicorn`); + } else if (pythonWSGI?.toLowerCase() === "uvicorn") { + Dockerfile.push(`RUN pip install uvicorn`); + } else if (pythonWSGI?.toLowerCase() === "uwsgi") { + Dockerfile.push(`RUN apk add --no-cache uwsgi-python3`); + } + try { + await import_fs.promises.stat(`${workdir}${baseDirectory || ""}/requirements.txt`); + Dockerfile.push(`COPY .${baseDirectory || ""}/requirements.txt ./`); + Dockerfile.push(`RUN pip install --no-cache-dir -r .${baseDirectory || ""}/requirements.txt`); + } catch (e) { + } + Dockerfile.push(`COPY .${baseDirectory || ""} ./`); + Dockerfile.push(`EXPOSE ${port}`); + if (pythonWSGI?.toLowerCase() === "gunicorn") { + Dockerfile.push(`CMD gunicorn -w=4 -b=0.0.0.0:8000 ${pythonModule}:${pythonVariable}`); + } else if (pythonWSGI?.toLowerCase() === "uvicorn") { + Dockerfile.push(`CMD uvicorn ${pythonModule}:${pythonVariable} --port ${port} --host 0.0.0.0`); + } else if (pythonWSGI?.toLowerCase() === "uwsgi") { + Dockerfile.push( + `CMD uwsgi --master -p 4 --http-socket 0.0.0.0:8000 --uid uwsgi --plugins python3 --protocol uwsgi --wsgi ${pythonModule}:${pythonVariable}` + ); + } else { + Dockerfile.push(`CMD python ${pythonModule}`); + } + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function python_default(data) { + try { + const { baseImage, baseBuildImage } = data; + await createDockerfile(data, baseImage); + await (0, import_common2.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/react.js b/apps/trpc-experimental/server/build/lib/buildPacks/react.js new file mode 100644 index 000000000..dc97fc657 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/react.js @@ -0,0 +1,50 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var react_exports = {}; +__export(react_exports, { + default: () => react_default +}); +module.exports = __toCommonJS(react_exports); +var import_fs = require("fs"); +var import_common = require("./common"); +const createDockerfile = async (data, image) => { + const { applicationId, tag, workdir, publishDirectory, baseImage, buildId, port } = data; + const Dockerfile = []; + Dockerfile.push(`FROM ${image}`); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); + if (baseImage?.includes("nginx")) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } + Dockerfile.push(`EXPOSE ${port}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function react_default(data) { + try { + const { baseImage, baseBuildImage } = data; + await (0, import_common.buildCacheImageWithNode)(data, baseBuildImage); + await createDockerfile(data, baseImage); + await (0, import_common.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/rust.js b/apps/trpc-experimental/server/build/lib/buildPacks/rust.js new file mode 100644 index 000000000..5fbb0af0d --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/rust.js @@ -0,0 +1,69 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var rust_exports = {}; +__export(rust_exports, { + default: () => rust_default +}); +module.exports = __toCommonJS(rust_exports); +var import_fs = require("fs"); +var import_toml = __toESM(require("@iarna/toml")); +var import_common = require("./common"); +var import_executeCommand = require("../executeCommand"); +const createDockerfile = async (data, image, name) => { + const { workdir, port, applicationId, tag, buildId } = data; + const Dockerfile = []; + Dockerfile.push(`FROM ${image}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/target target`); + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /usr/local/cargo /usr/local/cargo`); + Dockerfile.push(`COPY . .`); + Dockerfile.push(`RUN cargo build --release --bin ${name}`); + Dockerfile.push("FROM debian:buster-slim"); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push( + `RUN apt-get update -y && apt-get install -y --no-install-recommends openssl libcurl4 ca-certificates && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*` + ); + Dockerfile.push(`RUN update-ca-certificates`); + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/target/release/${name} ${name}`); + Dockerfile.push(`EXPOSE ${port}`); + Dockerfile.push(`CMD ["/app/${name}"]`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function rust_default(data) { + try { + const { workdir, baseImage, baseBuildImage } = data; + const { stdout: cargoToml } = await (0, import_executeCommand.executeCommand)({ command: `cat ${workdir}/Cargo.toml` }); + const parsedToml = import_toml.default.parse(cargoToml); + const name = parsedToml.package.name; + await (0, import_common.buildCacheImageWithCargo)(data, baseBuildImage); + await createDockerfile(data, baseImage, name); + await (0, import_common.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/static.js b/apps/trpc-experimental/server/build/lib/buildPacks/static.js new file mode 100644 index 000000000..38e193cef --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/static.js @@ -0,0 +1,77 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var static_exports = {}; +__export(static_exports, { + default: () => static_default +}); +module.exports = __toCommonJS(static_exports); +var import_fs = require("fs"); +var import_common = require("../common"); +var import_common2 = require("./common"); +const createDockerfile = async (data, image) => { + const { + applicationId, + tag, + workdir, + buildCommand, + baseDirectory, + publishDirectory, + secrets, + pullmergeRequestId, + baseImage, + buildId, + port + } = data; + const Dockerfile = []; + Dockerfile.push(`FROM ${image}`); + if (baseImage?.includes("httpd")) { + Dockerfile.push("WORKDIR /usr/local/apache2/htdocs/"); + } else { + Dockerfile.push("WORKDIR /app"); + } + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + if (secrets.length > 0) { + (0, import_common.generateSecrets)(secrets, pullmergeRequestId, true).forEach((env) => { + Dockerfile.push(env); + }); + } + if (buildCommand) { + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); + } else { + Dockerfile.push(`COPY .${baseDirectory || ""} ./`); + } + if (baseImage?.includes("nginx")) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } + Dockerfile.push(`EXPOSE ${port}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function static_default(data) { + try { + const { baseImage, baseBuildImage } = data; + if (data.buildCommand) + await (0, import_common2.buildCacheImageWithNode)(data, baseBuildImage); + await createDockerfile(data, baseImage); + await (0, import_common2.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/svelte.js b/apps/trpc-experimental/server/build/lib/buildPacks/svelte.js new file mode 100644 index 000000000..e1af2492b --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/svelte.js @@ -0,0 +1,50 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var svelte_exports = {}; +__export(svelte_exports, { + default: () => svelte_default +}); +module.exports = __toCommonJS(svelte_exports); +var import_fs = require("fs"); +var import_common = require("./common"); +const createDockerfile = async (data, image) => { + const { applicationId, tag, workdir, publishDirectory, baseImage, buildId, port } = data; + const Dockerfile = []; + Dockerfile.push(`FROM ${image}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); + if (baseImage?.includes("nginx")) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } + Dockerfile.push(`EXPOSE ${port}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function svelte_default(data) { + try { + const { baseImage, baseBuildImage } = data; + await (0, import_common.buildCacheImageWithNode)(data, baseBuildImage); + await createDockerfile(data, baseImage); + await (0, import_common.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/buildPacks/vuejs.js b/apps/trpc-experimental/server/build/lib/buildPacks/vuejs.js new file mode 100644 index 000000000..bc787e644 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/buildPacks/vuejs.js @@ -0,0 +1,50 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var vuejs_exports = {}; +__export(vuejs_exports, { + default: () => vuejs_default +}); +module.exports = __toCommonJS(vuejs_exports); +var import_fs = require("fs"); +var import_common = require("./common"); +const createDockerfile = async (data, image) => { + const { applicationId, tag, workdir, publishDirectory, baseImage, buildId, port } = data; + const Dockerfile = []; + Dockerfile.push(`FROM ${image}`); + Dockerfile.push("WORKDIR /app"); + Dockerfile.push(`LABEL coolify.buildId=${buildId}`); + Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); + if (baseImage?.includes("nginx")) { + Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); + } + Dockerfile.push(`EXPOSE ${port}`); + await import_fs.promises.writeFile(`${workdir}/Dockerfile`, Dockerfile.join("\n")); +}; +async function vuejs_default(data) { + try { + const { baseImage, baseBuildImage } = data; + await (0, import_common.buildCacheImageWithNode)(data, baseBuildImage); + await createDockerfile(data, baseImage); + await (0, import_common.buildImage)(data); + } catch (error) { + throw error; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/common.js b/apps/trpc-experimental/server/build/lib/common.js new file mode 100644 index 000000000..a501790b7 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/common.js @@ -0,0 +1,952 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var common_exports = {}; +__export(common_exports, { + asyncSleep: () => asyncSleep, + base64Decode: () => base64Decode, + base64Encode: () => base64Encode, + checkDomainsIsValidInDNS: () => checkDomainsIsValidInDNS, + checkExposedPort: () => checkExposedPort, + cleanupDB: () => cleanupDB, + comparePassword: () => comparePassword, + configureNetworkTraefikProxy: () => configureNetworkTraefikProxy, + createDirectories: () => createDirectories, + decrypt: () => decrypt, + decryptApplication: () => decryptApplication, + defaultTraefikImage: () => defaultTraefikImage, + encrypt: () => encrypt, + fixType: () => fixType, + generateRangeArray: () => generateRangeArray, + generateSecrets: () => generateSecrets, + generateTimestamp: () => generateTimestamp, + getAPIUrl: () => getAPIUrl, + getContainerUsage: () => getContainerUsage, + getCurrentUser: () => getCurrentUser, + getDomain: () => getDomain, + getFreeExposedPort: () => getFreeExposedPort, + getTags: () => getTags, + getTeamInvitation: () => getTeamInvitation, + getTemplates: () => getTemplates, + getUIUrl: () => getUIUrl, + hashPassword: () => hashPassword, + isARM: () => isARM, + isDev: () => isDev, + isDomainConfigured: () => isDomainConfigured, + listSettings: () => listSettings, + makeLabelForServices: () => makeLabelForServices, + pushToRegistry: () => pushToRegistry, + removeService: () => removeService, + saveDockerRegistryCredentials: () => saveDockerRegistryCredentials, + scanningTemplates: () => scanningTemplates, + sentryDSN: () => sentryDSN, + setDefaultConfiguration: () => setDefaultConfiguration, + startTraefikProxy: () => startTraefikProxy, + startTraefikTCPProxy: () => startTraefikTCPProxy, + stopTraefikProxy: () => stopTraefikProxy, + uniqueName: () => uniqueName, + version: () => version +}); +module.exports = __toCommonJS(common_exports); +var import_prisma = require("../prisma"); +var import_bcryptjs = __toESM(require("bcryptjs")); +var import_crypto = __toESM(require("crypto")); +var import_dns = require("dns"); +var import_promises = __toESM(require("fs/promises")); +var import_unique_names_generator = require("unique-names-generator"); +var import_env = require("../env"); +var import_dayjs = require("./dayjs"); +var import_executeCommand = require("./executeCommand"); +var import_logging = require("./logging"); +var import_docker = require("./docker"); +var import_js_yaml = __toESM(require("js-yaml")); +const customConfig = { + dictionaries: [import_unique_names_generator.adjectives, import_unique_names_generator.colors, import_unique_names_generator.animals], + style: "capital", + separator: " ", + length: 3 +}; +const algorithm = "aes-256-ctr"; +const isDev = import_env.env.NODE_ENV === "development"; +const version = "3.13.0"; +const sentryDSN = "https://409f09bcb7af47928d3e0f46b78987f3@o1082494.ingest.sentry.io/4504236622217216"; +const defaultTraefikImage = `traefik:v2.8`; +function getAPIUrl() { + if (process.env.GITPOD_WORKSPACE_URL) { + const { href } = new URL(process.env.GITPOD_WORKSPACE_URL); + const newURL = href.replace("https://", "https://3001-").replace(/\/$/, ""); + return newURL; + } + if (process.env.CODESANDBOX_HOST) { + return `https://${process.env.CODESANDBOX_HOST.replace(/\$PORT/, "3001")}`; + } + return isDev ? "http://host.docker.internal:3001" : "http://localhost:3000"; +} +function getUIUrl() { + if (process.env.GITPOD_WORKSPACE_URL) { + const { href } = new URL(process.env.GITPOD_WORKSPACE_URL); + const newURL = href.replace("https://", "https://3000-").replace(/\/$/, ""); + return newURL; + } + if (process.env.CODESANDBOX_HOST) { + return `https://${process.env.CODESANDBOX_HOST.replace(/\$PORT/, "3000")}`; + } + return "http://localhost:3000"; +} +const mainTraefikEndpoint = isDev ? `${getAPIUrl()}/webhooks/traefik/main.json` : "http://coolify:3000/webhooks/traefik/main.json"; +const otherTraefikEndpoint = isDev ? `${getAPIUrl()}/webhooks/traefik/other.json` : "http://coolify:3000/webhooks/traefik/other.json"; +async function listSettings() { + return await import_prisma.prisma.setting.findUnique({ where: { id: "0" } }); +} +async function getCurrentUser(userId) { + return await import_prisma.prisma.user.findUnique({ + where: { id: userId }, + include: { teams: true, permission: true } + }); +} +async function getTeamInvitation(userId) { + return await import_prisma.prisma.teamInvitation.findMany({ where: { uid: userId } }); +} +async function hashPassword(password) { + const saltRounds = 15; + return import_bcryptjs.default.hash(password, saltRounds); +} +async function comparePassword(password, hashedPassword) { + return import_bcryptjs.default.compare(password, hashedPassword); +} +const uniqueName = () => (0, import_unique_names_generator.uniqueNamesGenerator)(customConfig); +const decrypt = (hashString) => { + if (hashString) { + try { + const hash = JSON.parse(hashString); + const decipher = import_crypto.default.createDecipheriv( + algorithm, + import_env.env.COOLIFY_SECRET_KEY, + Buffer.from(hash.iv, "hex") + ); + const decrpyted = Buffer.concat([ + decipher.update(Buffer.from(hash.content, "hex")), + decipher.final() + ]); + return decrpyted.toString(); + } catch (error) { + if (error instanceof Error) { + console.log({ decryptionError: error.message }); + } + return hashString; + } + } + return false; +}; +function generateRangeArray(start, end) { + return Array.from({ length: end - start }, (_v, k) => k + start); +} +function generateTimestamp() { + return `${(0, import_dayjs.day)().format("HH:mm:ss.SSS")}`; +} +const encrypt = (text) => { + if (text) { + const iv = import_crypto.default.randomBytes(16); + const cipher = import_crypto.default.createCipheriv(algorithm, import_env.env.COOLIFY_SECRET_KEY, iv); + const encrypted = Buffer.concat([cipher.update(text.trim()), cipher.final()]); + return JSON.stringify({ + iv: iv.toString("hex"), + content: encrypted.toString("hex") + }); + } + return false; +}; +async function getTemplates() { + const templatePath = isDev ? "./templates.json" : "/app/templates.json"; + const open = await import_promises.default.open(templatePath, "r"); + try { + let data = await open.readFile({ encoding: "utf-8" }); + let jsonData = JSON.parse(data); + if (isARM(process.arch)) { + jsonData = jsonData.filter((d) => d.arch !== "amd64"); + } + return jsonData; + } catch (error) { + return []; + } finally { + await open?.close(); + } +} +function isARM(arch) { + if (arch === "arm" || arch === "arm64" || arch === "aarch" || arch === "aarch64") { + return true; + } + return false; +} +async function removeService({ id }) { + await import_prisma.prisma.serviceSecret.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.serviceSetting.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.servicePersistentStorage.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.meiliSearch.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.fider.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.ghost.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.umami.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.hasura.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.plausibleAnalytics.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.minio.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.vscodeserver.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.wordpress.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.glitchTip.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.moodle.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.appwrite.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.searxng.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.weblate.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.taiga.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.service.delete({ where: { id } }); +} +const createDirectories = async ({ + repository, + buildId +}) => { + if (repository) + repository = repository.replaceAll(" ", ""); + const repodir = `/tmp/build-sources/${repository}/`; + const workdir = `/tmp/build-sources/${repository}/${buildId}`; + let workdirFound = false; + try { + workdirFound = !!await import_promises.default.stat(workdir); + } catch (error) { + } + if (workdirFound) { + await (0, import_executeCommand.executeCommand)({ command: `rm -fr ${workdir}` }); + } + await (0, import_executeCommand.executeCommand)({ command: `mkdir -p ${workdir}` }); + return { + workdir, + repodir + }; +}; +async function saveDockerRegistryCredentials({ url, username, password, workdir }) { + if (!username || !password) { + return null; + } + let decryptedPassword = decrypt(password); + const location = `${workdir}/.docker`; + try { + await import_promises.default.mkdir(`${workdir}/.docker`); + } catch (error) { + console.log(error); + } + const payload = JSON.stringify({ + auths: { + [url]: { + auth: Buffer.from(`${username}:${decryptedPassword}`).toString("base64") + } + } + }); + await import_promises.default.writeFile(`${location}/config.json`, payload); + return location; +} +function getDomain(domain) { + if (domain) { + return domain?.replace("https://", "").replace("http://", ""); + } else { + return ""; + } +} +async function isDomainConfigured({ + id, + fqdn, + checkOwn = false, + remoteIpAddress = void 0 +}) { + const domain = getDomain(fqdn); + const nakedDomain = domain.replace("www.", ""); + const foundApp = await import_prisma.prisma.application.findFirst({ + where: { + OR: [ + { fqdn: { endsWith: `//${nakedDomain}` } }, + { fqdn: { endsWith: `//www.${nakedDomain}` } }, + { dockerComposeConfiguration: { contains: `//${nakedDomain}` } }, + { dockerComposeConfiguration: { contains: `//www.${nakedDomain}` } } + ], + id: { not: id }, + destinationDocker: { + remoteIpAddress + } + }, + select: { fqdn: true } + }); + const foundService = await import_prisma.prisma.service.findFirst({ + where: { + OR: [ + { fqdn: { endsWith: `//${nakedDomain}` } }, + { fqdn: { endsWith: `//www.${nakedDomain}` } } + ], + id: { not: checkOwn ? void 0 : id }, + destinationDocker: { + remoteIpAddress + } + }, + select: { fqdn: true } + }); + const coolifyFqdn = await import_prisma.prisma.setting.findFirst({ + where: { + OR: [ + { fqdn: { endsWith: `//${nakedDomain}` } }, + { fqdn: { endsWith: `//www.${nakedDomain}` } } + ], + id: { not: id } + }, + select: { fqdn: true } + }); + return !!(foundApp || foundService || coolifyFqdn); +} +async function checkExposedPort({ + id, + configuredPort, + exposePort, + engine, + remoteEngine, + remoteIpAddress +}) { + if (exposePort < 1024 || exposePort > 65535) { + throw { status: 500, message: `Exposed Port needs to be between 1024 and 65535.` }; + } + if (configuredPort) { + if (configuredPort !== exposePort) { + const availablePort = await getFreeExposedPort( + id, + exposePort, + engine, + remoteEngine, + remoteIpAddress + ); + if (availablePort.toString() !== exposePort.toString()) { + throw { status: 500, message: `Port ${exposePort} is already in use.` }; + } + } + } else { + const availablePort = await getFreeExposedPort( + id, + exposePort, + engine, + remoteEngine, + remoteIpAddress + ); + if (availablePort.toString() !== exposePort.toString()) { + throw { status: 500, message: `Port ${exposePort} is already in use.` }; + } + } +} +async function getFreeExposedPort(id, exposePort, engine, remoteEngine, remoteIpAddress) { + const { default: checkPort } = await import("is-port-reachable"); + if (remoteEngine) { + const applicationUsed = await (await import_prisma.prisma.application.findMany({ + where: { + exposePort: { not: null }, + id: { not: id }, + destinationDocker: { remoteIpAddress } + }, + select: { exposePort: true } + })).map((a) => a.exposePort); + const serviceUsed = await (await import_prisma.prisma.service.findMany({ + where: { + exposePort: { not: null }, + id: { not: id }, + destinationDocker: { remoteIpAddress } + }, + select: { exposePort: true } + })).map((a) => a.exposePort); + const usedPorts = [...applicationUsed, ...serviceUsed]; + if (usedPorts.includes(exposePort)) { + return false; + } + const found = await checkPort(exposePort, { host: remoteIpAddress }); + if (!found) { + return exposePort; + } + return false; + } else { + const applicationUsed = await (await import_prisma.prisma.application.findMany({ + where: { exposePort: { not: null }, id: { not: id }, destinationDocker: { engine } }, + select: { exposePort: true } + })).map((a) => a.exposePort); + const serviceUsed = await (await import_prisma.prisma.service.findMany({ + where: { exposePort: { not: null }, id: { not: id }, destinationDocker: { engine } }, + select: { exposePort: true } + })).map((a) => a.exposePort); + const usedPorts = [...applicationUsed, ...serviceUsed]; + if (usedPorts.includes(exposePort)) { + return false; + } + const found = await checkPort(exposePort, { host: "localhost" }); + if (!found) { + return exposePort; + } + return false; + } +} +async function checkDomainsIsValidInDNS({ hostname, fqdn, dualCerts }) { + const { isIP } = await import("is-ip"); + const domain = getDomain(fqdn); + const domainDualCert = domain.includes("www.") ? domain.replace("www.", "") : `www.${domain}`; + const { DNSServers } = await listSettings(); + if (DNSServers) { + import_dns.promises.setServers([...DNSServers.split(",")]); + } + let resolves = []; + try { + if (isIP(hostname)) { + resolves = [hostname]; + } else { + resolves = await import_dns.promises.resolve4(hostname); + } + } catch (error) { + throw { status: 500, message: `Could not determine IP address for ${hostname}.` }; + } + if (dualCerts) { + try { + const ipDomain = await import_dns.promises.resolve4(domain); + const ipDomainDualCert = await import_dns.promises.resolve4(domainDualCert); + let ipDomainFound = false; + let ipDomainDualCertFound = false; + for (const ip of ipDomain) { + if (resolves.includes(ip)) { + ipDomainFound = true; + } + } + for (const ip of ipDomainDualCert) { + if (resolves.includes(ip)) { + ipDomainDualCertFound = true; + } + } + if (ipDomainFound && ipDomainDualCertFound) + return { status: 200 }; + throw { + status: 500, + message: `DNS not set correctly or propogated.
Please check your DNS settings.` + }; + } catch (error) { + throw { + status: 500, + message: `DNS not set correctly or propogated.
Please check your DNS settings.` + }; + } + } else { + try { + const ipDomain = await import_dns.promises.resolve4(domain); + let ipDomainFound = false; + for (const ip of ipDomain) { + if (resolves.includes(ip)) { + ipDomainFound = true; + } + } + if (ipDomainFound) + return { status: 200 }; + throw { + status: 500, + message: `DNS not set correctly or propogated.
Please check your DNS settings.` + }; + } catch (error) { + throw { + status: 500, + message: `DNS not set correctly or propogated.
Please check your DNS settings.` + }; + } + } +} +const setDefaultConfiguration = async (data) => { + let { + buildPack, + port, + installCommand, + startCommand, + buildCommand, + publishDirectory, + baseDirectory, + dockerFileLocation, + dockerComposeFileLocation, + denoMainFile + } = data; + const template = scanningTemplates[buildPack]; + if (!port) { + port = template?.port || 3e3; + if (buildPack === "static") + port = 80; + else if (buildPack === "node") + port = 3e3; + else if (buildPack === "php") + port = 80; + else if (buildPack === "python") + port = 8e3; + } + if (!installCommand && buildPack !== "static" && buildPack !== "laravel") + installCommand = template?.installCommand || "yarn install"; + if (!startCommand && buildPack !== "static" && buildPack !== "laravel") + startCommand = template?.startCommand || "yarn start"; + if (!buildCommand && buildPack !== "static" && buildPack !== "laravel") + buildCommand = template?.buildCommand || null; + if (!publishDirectory) + publishDirectory = template?.publishDirectory || null; + if (baseDirectory) { + if (!baseDirectory.startsWith("/")) + baseDirectory = `/${baseDirectory}`; + if (baseDirectory.endsWith("/") && baseDirectory !== "/") + baseDirectory = baseDirectory.slice(0, -1); + } + if (dockerFileLocation) { + if (!dockerFileLocation.startsWith("/")) + dockerFileLocation = `/${dockerFileLocation}`; + if (dockerFileLocation.endsWith("/")) + dockerFileLocation = dockerFileLocation.slice(0, -1); + } else { + dockerFileLocation = "/Dockerfile"; + } + if (dockerComposeFileLocation) { + if (!dockerComposeFileLocation.startsWith("/")) + dockerComposeFileLocation = `/${dockerComposeFileLocation}`; + if (dockerComposeFileLocation.endsWith("/")) + dockerComposeFileLocation = dockerComposeFileLocation.slice(0, -1); + } else { + dockerComposeFileLocation = "/Dockerfile"; + } + if (!denoMainFile) { + denoMainFile = "main.ts"; + } + return { + buildPack, + port, + installCommand, + startCommand, + buildCommand, + publishDirectory, + baseDirectory, + dockerFileLocation, + dockerComposeFileLocation, + denoMainFile + }; +}; +const scanningTemplates = { + "@sveltejs/kit": { + buildPack: "nodejs" + }, + astro: { + buildPack: "astro" + }, + "@11ty/eleventy": { + buildPack: "eleventy" + }, + svelte: { + buildPack: "svelte" + }, + "@nestjs/core": { + buildPack: "nestjs" + }, + next: { + buildPack: "nextjs" + }, + nuxt: { + buildPack: "nuxtjs" + }, + "react-scripts": { + buildPack: "react" + }, + "parcel-bundler": { + buildPack: "static" + }, + "@vue/cli-service": { + buildPack: "vuejs" + }, + vuejs: { + buildPack: "vuejs" + }, + gatsby: { + buildPack: "gatsby" + }, + "preact-cli": { + buildPack: "react" + } +}; +async function cleanupDB(buildId, applicationId) { + const data = await import_prisma.prisma.build.findUnique({ where: { id: buildId } }); + if (data?.status === "queued" || data?.status === "running") { + await import_prisma.prisma.build.update({ where: { id: buildId }, data: { status: "canceled" } }); + } + await (0, import_logging.saveBuildLog)({ line: "Canceled.", buildId, applicationId }); +} +const base64Encode = (text) => { + return Buffer.from(text).toString("base64"); +}; +const base64Decode = (text) => { + return Buffer.from(text, "base64").toString("ascii"); +}; +function parseSecret(secret, isBuild) { + if (secret.value.includes("$")) { + secret.value = secret.value.replaceAll("$", "$$$$"); + } + if (secret.value.includes("\\n")) { + if (isBuild) { + return `ARG ${secret.name}=${secret.value}`; + } else { + return `${secret.name}=${secret.value}`; + } + } else if (secret.value.includes(" ")) { + if (isBuild) { + return `ARG ${secret.name}='${secret.value}'`; + } else { + return `${secret.name}='${secret.value}'`; + } + } else { + if (isBuild) { + return `ARG ${secret.name}=${secret.value}`; + } else { + return `${secret.name}=${secret.value}`; + } + } +} +function generateSecrets(secrets, pullmergeRequestId, isBuild = false, port = null) { + const envs = []; + const isPRMRSecret = secrets.filter((s) => s.isPRMRSecret); + const normalSecrets = secrets.filter((s) => !s.isPRMRSecret); + if (pullmergeRequestId && isPRMRSecret.length > 0) { + isPRMRSecret.forEach((secret) => { + if (isBuild && !secret.isBuildSecret) { + return; + } + const build = isBuild && secret.isBuildSecret; + envs.push(parseSecret(secret, build)); + }); + } + if (!pullmergeRequestId && normalSecrets.length > 0) { + normalSecrets.forEach((secret) => { + if (isBuild && !secret.isBuildSecret) { + return; + } + const build = isBuild && secret.isBuildSecret; + envs.push(parseSecret(secret, build)); + }); + } + const portFound = envs.filter((env2) => env2.startsWith("PORT")); + if (portFound.length === 0 && port && !isBuild) { + envs.push(`PORT=${port}`); + } + const nodeEnv = envs.filter((env2) => env2.startsWith("NODE_ENV")); + if (nodeEnv.length === 0 && !isBuild) { + envs.push(`NODE_ENV=production`); + } + return envs; +} +function decryptApplication(application) { + if (application) { + if (application?.gitSource?.githubApp?.clientSecret) { + application.gitSource.githubApp.clientSecret = decrypt(application.gitSource.githubApp.clientSecret) || null; + } + if (application?.gitSource?.githubApp?.webhookSecret) { + application.gitSource.githubApp.webhookSecret = decrypt(application.gitSource.githubApp.webhookSecret) || null; + } + if (application?.gitSource?.githubApp?.privateKey) { + application.gitSource.githubApp.privateKey = decrypt(application.gitSource.githubApp.privateKey) || null; + } + if (application?.gitSource?.gitlabApp?.appSecret) { + application.gitSource.gitlabApp.appSecret = decrypt(application.gitSource.gitlabApp.appSecret) || null; + } + if (application?.secrets.length > 0) { + application.secrets = application.secrets.map((s) => { + s.value = decrypt(s.value) || null; + return s; + }); + } + return application; + } +} +async function pushToRegistry(application, workdir, tag, imageName, customTag) { + const location = `${workdir}/.docker`; + const tagCommand = `docker tag ${application.id}:${tag} ${imageName}:${customTag}`; + const pushCommand = `docker --config ${location} push ${imageName}:${customTag}`; + await (0, import_executeCommand.executeCommand)({ + dockerId: application.destinationDockerId, + command: tagCommand + }); + await (0, import_executeCommand.executeCommand)({ + dockerId: application.destinationDockerId, + command: pushCommand + }); +} +async function getContainerUsage(dockerId, container) { + try { + const { stdout } = await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker container stats ${container} --no-stream --no-trunc --format "{{json .}}"` + }); + return JSON.parse(stdout); + } catch (err) { + return { + MemUsage: 0, + CPUPerc: 0, + NetIO: 0 + }; + } +} +function fixType(type) { + return type?.replaceAll(" ", "").toLowerCase() || null; +} +const compareSemanticVersions = (a, b) => { + const a1 = a.split("."); + const b1 = b.split("."); + const len = Math.min(a1.length, b1.length); + for (let i = 0; i < len; i++) { + const a2 = +a1[i] || 0; + const b2 = +b1[i] || 0; + if (a2 !== b2) { + return a2 > b2 ? 1 : -1; + } + } + return b1.length - a1.length; +}; +async function getTags(type) { + try { + if (type) { + const tagsPath = isDev ? "./tags.json" : "/app/tags.json"; + const data = await import_promises.default.readFile(tagsPath, "utf8"); + let tags = JSON.parse(data); + if (tags) { + tags = tags.find((tag) => tag.name.includes(type)); + tags.tags = tags.tags.sort(compareSemanticVersions).reverse(); + return tags; + } + } + } catch (error) { + return []; + } +} +function makeLabelForServices(type) { + return [ + "coolify.managed=true", + `coolify.version=${version}`, + `coolify.type=service`, + `coolify.service.type=${type}` + ]; +} +const asyncSleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay)); +async function startTraefikTCPProxy(destinationDocker, id, publicPort, privatePort, type) { + const { network, id: dockerId, remoteEngine } = destinationDocker; + const container = `${id}-${publicPort}`; + const { found } = await (0, import_docker.checkContainer)({ dockerId, container, remove: true }); + const { ipv4, ipv6 } = await listSettings(); + let dependentId = id; + if (type === "wordpressftp") + dependentId = `${id}-ftp`; + const { found: foundDependentContainer } = await (0, import_docker.checkContainer)({ + dockerId, + container: dependentId, + remove: true + }); + if (foundDependentContainer && !found) { + const { stdout: Config } = await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker network inspect ${network} --format '{{json .IPAM.Config }}'` + }); + const ip = JSON.parse(Config)[0].Gateway; + let traefikUrl = otherTraefikEndpoint; + if (remoteEngine) { + let ip2 = null; + if (isDev) { + ip2 = getAPIUrl(); + } else { + ip2 = `http://${ipv4 || ipv6}:3000`; + } + traefikUrl = `${ip2}/webhooks/traefik/other.json`; + } + const tcpProxy = { + version: "3.8", + services: { + [`${id}-${publicPort}`]: { + container_name: container, + image: defaultTraefikImage, + command: [ + `--entrypoints.tcp.address=:${publicPort}`, + `--entryPoints.tcp.forwardedHeaders.insecure=true`, + `--providers.http.endpoint=${traefikUrl}?id=${id}&privatePort=${privatePort}&publicPort=${publicPort}&type=tcp&address=${dependentId}`, + "--providers.http.pollTimeout=10s", + "--log.level=error" + ], + ports: [`${publicPort}:${publicPort}`], + extra_hosts: ["host.docker.internal:host-gateway", `host.docker.internal: ${ip}`], + volumes: ["/var/run/docker.sock:/var/run/docker.sock"], + networks: ["coolify-infra", network] + } + }, + networks: { + [network]: { + external: false, + name: network + }, + "coolify-infra": { + external: false, + name: "coolify-infra" + } + } + }; + await import_promises.default.writeFile(`/tmp/docker-compose-${id}.yaml`, import_js_yaml.default.dump(tcpProxy)); + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker compose -f /tmp/docker-compose-${id}.yaml up -d` + }); + await import_promises.default.rm(`/tmp/docker-compose-${id}.yaml`); + } + if (!foundDependentContainer && found) { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker stop -t 0 ${container} && docker rm ${container}`, + shell: true + }); + } +} +async function startTraefikProxy(id) { + const { engine, network, remoteEngine, remoteIpAddress } = await import_prisma.prisma.destinationDocker.findUnique({ where: { id } }); + const { found } = await (0, import_docker.checkContainer)({ + dockerId: id, + container: "coolify-proxy", + remove: true + }); + const { id: settingsId, ipv4, ipv6 } = await listSettings(); + if (!found) { + const { stdout: coolifyNetwork } = await (0, import_executeCommand.executeCommand)({ + dockerId: id, + command: `docker network ls --filter 'name=coolify-infra' --no-trunc --format "{{json .}}"` + }); + if (!coolifyNetwork) { + await (0, import_executeCommand.executeCommand)({ + dockerId: id, + command: `docker network create --attachable coolify-infra` + }); + } + const { stdout: Config } = await (0, import_executeCommand.executeCommand)({ + dockerId: id, + command: `docker network inspect ${network} --format '{{json .IPAM.Config }}'` + }); + const ip = JSON.parse(Config)[0].Gateway; + let traefikUrl = mainTraefikEndpoint; + if (remoteEngine) { + let ip2 = null; + if (isDev) { + ip2 = getAPIUrl(); + } else { + ip2 = `http://${ipv4 || ipv6}:3000`; + } + traefikUrl = `${ip2}/webhooks/traefik/remote/${id}`; + } + await (0, import_executeCommand.executeCommand)({ + dockerId: id, + command: `docker run --restart always --add-host 'host.docker.internal:host-gateway' ${ip ? `--add-host 'host.docker.internal:${ip}'` : ""} -v coolify-traefik-letsencrypt:/etc/traefik/acme -v /var/run/docker.sock:/var/run/docker.sock --network coolify-infra -p "80:80" -p "443:443" --name coolify-proxy -d ${defaultTraefikImage} --entrypoints.web.address=:80 --entrypoints.web.forwardedHeaders.insecure=true --entrypoints.websecure.address=:443 --entrypoints.websecure.forwardedHeaders.insecure=true --providers.docker=true --providers.docker.exposedbydefault=false --providers.http.endpoint=${traefikUrl} --providers.http.pollTimeout=5s --certificatesresolvers.letsencrypt.acme.httpchallenge=true --certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme/acme.json --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web --log.level=error` + }); + await import_prisma.prisma.destinationDocker.update({ + where: { id }, + data: { isCoolifyProxyUsed: true } + }); + } + if (engine) { + const destinations = await import_prisma.prisma.destinationDocker.findMany({ where: { engine } }); + for (const destination of destinations) { + await configureNetworkTraefikProxy(destination); + } + } + if (remoteEngine) { + const destinations = await import_prisma.prisma.destinationDocker.findMany({ where: { remoteIpAddress } }); + for (const destination of destinations) { + await configureNetworkTraefikProxy(destination); + } + } +} +async function configureNetworkTraefikProxy(destination) { + const { id } = destination; + const { stdout: networks } = await (0, import_executeCommand.executeCommand)({ + dockerId: id, + command: `docker ps -a --filter name=coolify-proxy --format '{{json .Networks}}'` + }); + const configuredNetworks = networks.replace(/"/g, "").replace("\n", "").split(","); + if (!configuredNetworks.includes(destination.network)) { + await (0, import_executeCommand.executeCommand)({ + dockerId: destination.id, + command: `docker network connect ${destination.network} coolify-proxy` + }); + } +} +async function stopTraefikProxy(id) { + const { found } = await (0, import_docker.checkContainer)({ dockerId: id, container: "coolify-proxy" }); + await import_prisma.prisma.destinationDocker.update({ + where: { id }, + data: { isCoolifyProxyUsed: false } + }); + if (found) { + return await (0, import_executeCommand.executeCommand)({ + dockerId: id, + command: `docker stop -t 0 coolify-proxy && docker rm coolify-proxy`, + shell: true + }); + } + return { stdout: "", stderr: "" }; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + asyncSleep, + base64Decode, + base64Encode, + checkDomainsIsValidInDNS, + checkExposedPort, + cleanupDB, + comparePassword, + configureNetworkTraefikProxy, + createDirectories, + decrypt, + decryptApplication, + defaultTraefikImage, + encrypt, + fixType, + generateRangeArray, + generateSecrets, + generateTimestamp, + getAPIUrl, + getContainerUsage, + getCurrentUser, + getDomain, + getFreeExposedPort, + getTags, + getTeamInvitation, + getTemplates, + getUIUrl, + hashPassword, + isARM, + isDev, + isDomainConfigured, + listSettings, + makeLabelForServices, + pushToRegistry, + removeService, + saveDockerRegistryCredentials, + scanningTemplates, + sentryDSN, + setDefaultConfiguration, + startTraefikProxy, + startTraefikTCPProxy, + stopTraefikProxy, + uniqueName, + version +}); diff --git a/apps/trpc-experimental/server/build/lib/dayjs.js b/apps/trpc-experimental/server/build/lib/dayjs.js new file mode 100644 index 000000000..bc709ce17 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/dayjs.js @@ -0,0 +1,38 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var dayjs_exports = {}; +__export(dayjs_exports, { + day: () => import_dayjs.default +}); +module.exports = __toCommonJS(dayjs_exports); +var import_dayjs = __toESM(require("dayjs")); +var import_utc = __toESM(require("dayjs/plugin/utc.js")); +var import_relativeTime = __toESM(require("dayjs/plugin/relativeTime.js")); +import_dayjs.default.extend(import_utc.default); +import_dayjs.default.extend(import_relativeTime.default); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + day +}); diff --git a/apps/trpc-experimental/server/build/lib/docker.js b/apps/trpc-experimental/server/build/lib/docker.js new file mode 100644 index 000000000..58fd81f5d --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/docker.js @@ -0,0 +1,168 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var docker_exports = {}; +__export(docker_exports, { + checkContainer: () => checkContainer, + defaultComposeConfiguration: () => defaultComposeConfiguration, + formatLabelsOnDocker: () => formatLabelsOnDocker, + removeContainer: () => removeContainer, + stopDatabaseContainer: () => stopDatabaseContainer, + stopTcpHttpProxy: () => stopTcpHttpProxy +}); +module.exports = __toCommonJS(docker_exports); +var import_executeCommand = require("./executeCommand"); +async function checkContainer({ + dockerId, + container, + remove = false +}) { + let containerFound = false; + try { + const { stdout } = await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker inspect --format '{{json .State}}' ${container}` + }); + containerFound = true; + const parsedStdout = JSON.parse(stdout); + const status = parsedStdout.Status; + const isRunning = status === "running"; + const isRestarting = status === "restarting"; + const isExited = status === "exited"; + if (status === "created") { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker rm ${container}` + }); + } + if (remove && status === "exited") { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker rm ${container}` + }); + } + return { + found: containerFound, + status: { + isRunning, + isRestarting, + isExited + } + }; + } catch (err) { + } + return { + found: false + }; +} +async function removeContainer({ + id, + dockerId +}) { + try { + const { stdout } = await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker inspect --format '{{json .State}}' ${id}` + }); + if (JSON.parse(stdout).Running) { + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker stop -t 0 ${id}` }); + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker rm ${id}` }); + } + if (JSON.parse(stdout).Status === "exited") { + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker rm ${id}` }); + } + } catch (error) { + throw error; + } +} +async function stopDatabaseContainer(database) { + let everStarted = false; + const { + id, + destinationDockerId, + destinationDocker: { engine, id: dockerId } + } = database; + if (destinationDockerId) { + try { + const { stdout } = await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker inspect --format '{{json .State}}' ${id}` + }); + if (stdout) { + everStarted = true; + await removeContainer({ id, dockerId }); + } + } catch (error) { + } + } + return everStarted; +} +async function stopTcpHttpProxy(id, destinationDocker, publicPort, forceName = null) { + const { id: dockerId } = destinationDocker; + let container = `${id}-${publicPort}`; + if (forceName) + container = forceName; + const { found } = await checkContainer({ dockerId, container }); + try { + if (!found) + return true; + return await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker stop -t 0 ${container} && docker rm ${container}`, + shell: true + }); + } catch (error) { + return error; + } +} +function formatLabelsOnDocker(data) { + return data.trim().split("\n").map((a) => JSON.parse(a)).map((container) => { + const labels = container.Labels.split(","); + let jsonLabels = {}; + labels.forEach((l) => { + const name = l.split("=")[0]; + const value = l.split("=")[1]; + jsonLabels = { ...jsonLabels, ...{ [name]: value } }; + }); + container.Labels = jsonLabels; + return container; + }); +} +function defaultComposeConfiguration(network) { + return { + networks: [network], + restart: "on-failure", + deploy: { + restart_policy: { + condition: "on-failure", + delay: "5s", + max_attempts: 10, + window: "120s" + } + } + }; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + checkContainer, + defaultComposeConfiguration, + formatLabelsOnDocker, + removeContainer, + stopDatabaseContainer, + stopTcpHttpProxy +}); diff --git a/apps/trpc-experimental/server/build/lib/executeCommand.js b/apps/trpc-experimental/server/build/lib/executeCommand.js new file mode 100644 index 000000000..b1a12607b --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/executeCommand.js @@ -0,0 +1,207 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var executeCommand_exports = {}; +__export(executeCommand_exports, { + createRemoteEngineConfiguration: () => createRemoteEngineConfiguration, + executeCommand: () => executeCommand +}); +module.exports = __toCommonJS(executeCommand_exports); +var import_prisma = require("../prisma"); +var import_os = __toESM(require("os")); +var import_promises = __toESM(require("fs/promises")); +var import_ssh_config = __toESM(require("ssh-config")); +var import_ssh = require("./ssh"); +var import_env = require("../env"); +var import_logging = require("./logging"); +var import_common = require("./common"); +async function executeCommand({ + command, + dockerId = null, + sshCommand = false, + shell = false, + stream = false, + buildId, + applicationId, + debug +}) { + const { execa, execaCommand } = await import("execa"); + const { parse } = await import("shell-quote"); + const parsedCommand = parse(command); + const dockerCommand = parsedCommand[0]; + const dockerArgs = parsedCommand.slice(1); + if (dockerId && dockerCommand && dockerArgs) { + const destinationDocker = await import_prisma.prisma.destinationDocker.findUnique({ + where: { id: dockerId } + }); + if (!destinationDocker) { + throw new Error("Destination docker not found"); + } + let { remoteEngine, remoteIpAddress, engine } = destinationDocker; + if (remoteEngine) { + await createRemoteEngineConfiguration(dockerId); + engine = `ssh://${remoteIpAddress}-remote`; + } else { + engine = "unix:///var/run/docker.sock"; + } + if (import_env.env.CODESANDBOX_HOST) { + if (command.startsWith("docker compose")) { + command = command.replace(/docker compose/gi, "docker-compose"); + } + } + if (sshCommand) { + if (shell) { + return execaCommand(`ssh ${remoteIpAddress}-remote ${command}`); + } + return await execa("ssh", [`${remoteIpAddress}-remote`, dockerCommand, ...dockerArgs]); + } + if (stream) { + return await new Promise(async (resolve, reject) => { + let subprocess = null; + if (shell) { + subprocess = execaCommand(command, { + env: { DOCKER_BUILDKIT: "1", DOCKER_HOST: engine } + }); + } else { + subprocess = execa(dockerCommand, dockerArgs, { + env: { DOCKER_BUILDKIT: "1", DOCKER_HOST: engine } + }); + } + const logs = []; + if (subprocess && subprocess.stdout && subprocess.stderr) { + subprocess.stdout.on("data", async (data) => { + const stdout = data.toString(); + const array = stdout.split("\n"); + for (const line of array) { + if (line !== "\n" && line !== "") { + const log = { + line: `${line.replace("\n", "")}`, + buildId, + applicationId + }; + logs.push(log); + if (debug) { + await (0, import_logging.saveBuildLog)(log); + } + } + } + }); + subprocess.stderr.on("data", async (data) => { + const stderr = data.toString(); + const array = stderr.split("\n"); + for (const line of array) { + if (line !== "\n" && line !== "") { + const log = { + line: `${line.replace("\n", "")}`, + buildId, + applicationId + }; + logs.push(log); + if (debug) { + await (0, import_logging.saveBuildLog)(log); + } + } + } + }); + subprocess.on("exit", async (code) => { + if (code === 0) { + resolve(code); + } else { + if (!debug) { + for (const log of logs) { + await (0, import_logging.saveBuildLog)(log); + } + } + reject(code); + } + }); + } + }); + } else { + if (shell) { + return await execaCommand(command, { + env: { DOCKER_BUILDKIT: "1", DOCKER_HOST: engine } + }); + } else { + return await execa(dockerCommand, dockerArgs, { + env: { DOCKER_BUILDKIT: "1", DOCKER_HOST: engine } + }); + } + } + } else { + if (shell) { + return execaCommand(command, { shell: true }); + } + return await execa(dockerCommand, dockerArgs); + } +} +async function createRemoteEngineConfiguration(id) { + const homedir = import_os.default.homedir(); + const sshKeyFile = `/tmp/id_rsa-${id}`; + const localPort = await (0, import_ssh.getFreeSSHLocalPort)(id); + const { + sshKey: { privateKey }, + network, + remoteIpAddress, + remotePort, + remoteUser + } = await import_prisma.prisma.destinationDocker.findFirst({ where: { id }, include: { sshKey: true } }); + await import_promises.default.writeFile(sshKeyFile, (0, import_common.decrypt)(privateKey) + "\n", { encoding: "utf8", mode: 400 }); + const config = import_ssh_config.default.parse(""); + const Host = `${remoteIpAddress}-remote`; + try { + await executeCommand({ command: `ssh-keygen -R ${Host}` }); + await executeCommand({ command: `ssh-keygen -R ${remoteIpAddress}` }); + await executeCommand({ command: `ssh-keygen -R localhost:${localPort}` }); + } catch (error) { + } + const found = config.find({ Host }); + const foundIp = config.find({ Host: remoteIpAddress }); + if (found) + config.remove({ Host }); + if (foundIp) + config.remove({ Host: remoteIpAddress }); + config.append({ + Host, + Hostname: remoteIpAddress, + Port: remotePort.toString(), + User: remoteUser, + StrictHostKeyChecking: "no", + IdentityFile: sshKeyFile, + ControlMaster: "auto", + ControlPath: `${homedir}/.ssh/coolify-${remoteIpAddress}-%r@%h:%p`, + ControlPersist: "10m" + }); + try { + await import_promises.default.stat(`${homedir}/.ssh/`); + } catch (error) { + await import_promises.default.mkdir(`${homedir}/.ssh/`); + } + return await import_promises.default.writeFile(`${homedir}/.ssh/config`, import_ssh_config.default.stringify(config)); +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + createRemoteEngineConfiguration, + executeCommand +}); diff --git a/apps/trpc-experimental/server/build/lib/importers/github.js b/apps/trpc-experimental/server/build/lib/importers/github.js new file mode 100644 index 000000000..c03410e05 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/importers/github.js @@ -0,0 +1,108 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var github_exports = {}; +__export(github_exports, { + default: () => github_default +}); +module.exports = __toCommonJS(github_exports); +var import_jsonwebtoken = __toESM(require("jsonwebtoken")); +var import_prisma = require("../../prisma"); +var import_common = require("../buildPacks/common"); +var import_common2 = require("../common"); +var import_executeCommand = require("../executeCommand"); +async function github_default({ + applicationId, + workdir, + githubAppId, + repository, + apiUrl, + gitCommitHash, + htmlUrl, + branch, + buildId, + customPort, + forPublic +}) { + const { default: got } = await import("got"); + const url = htmlUrl.replace("https://", "").replace("http://", ""); + if (forPublic) { + await (0, import_common.saveBuildLog)({ + line: `Cloning ${repository}:${branch}...`, + buildId, + applicationId + }); + if (gitCommitHash) { + await (0, import_common.saveBuildLog)({ + line: `Checking out ${gitCommitHash} commit...`, + buildId, + applicationId + }); + } + await (0, import_executeCommand.executeCommand)({ + command: `git clone -q -b ${branch} https://${url}/${repository}.git ${workdir}/ && cd ${workdir} && git checkout ${gitCommitHash || ""} && git submodule update --init --recursive && git lfs pull && cd .. `, + shell: true + }); + } else { + const body = await import_prisma.prisma.githubApp.findUnique({ where: { id: githubAppId } }); + if (body.privateKey) + body.privateKey = (0, import_common2.decrypt)(body.privateKey); + const { privateKey, appId, installationId } = body; + const githubPrivateKey = privateKey.replace(/\\n/g, "\n").replace(/"/g, ""); + const payload = { + iat: Math.round(new Date().getTime() / 1e3), + exp: Math.round(new Date().getTime() / 1e3 + 60), + iss: appId + }; + const jwtToken = import_jsonwebtoken.default.sign(payload, githubPrivateKey, { + algorithm: "RS256" + }); + const { token } = await got.post(`${apiUrl}/app/installations/${installationId}/access_tokens`, { + headers: { + Authorization: `Bearer ${jwtToken}`, + Accept: "application/vnd.github.machine-man-preview+json" + } + }).json(); + await (0, import_common.saveBuildLog)({ + line: `Cloning ${repository}:${branch}...`, + buildId, + applicationId + }); + if (gitCommitHash) { + await (0, import_common.saveBuildLog)({ + line: `Checking out ${gitCommitHash} commit...`, + buildId, + applicationId + }); + } + await (0, import_executeCommand.executeCommand)({ + command: `git clone -q -b ${branch} https://x-access-token:${token}@${url}/${repository}.git --config core.sshCommand="ssh -p ${customPort}" ${workdir}/ && cd ${workdir} && git checkout ${gitCommitHash || ""} && git submodule update --init --recursive && git lfs pull && cd .. `, + shell: true + }); + } + const { stdout: commit } = await (0, import_executeCommand.executeCommand)({ command: `cd ${workdir}/ && git rev-parse HEAD`, shell: true }); + return commit.replace("\n", ""); +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/importers/gitlab.js b/apps/trpc-experimental/server/build/lib/importers/gitlab.js new file mode 100644 index 000000000..d34c5bb7b --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/importers/gitlab.js @@ -0,0 +1,76 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var gitlab_exports = {}; +__export(gitlab_exports, { + default: () => gitlab_default +}); +module.exports = __toCommonJS(gitlab_exports); +var import_common = require("../buildPacks/common"); +var import_executeCommand = require("../executeCommand"); +async function gitlab_default({ + applicationId, + workdir, + repodir, + htmlUrl, + gitCommitHash, + repository, + branch, + buildId, + privateSshKey, + customPort, + forPublic, + customUser +}) { + const url = htmlUrl.replace("https://", "").replace("http://", "").replace(/\/$/, ""); + if (!forPublic) { + await (0, import_executeCommand.executeCommand)({ command: `echo '${privateSshKey}' > ${repodir}/id.rsa`, shell: true }); + await (0, import_executeCommand.executeCommand)({ command: `chmod 600 ${repodir}/id.rsa` }); + } + await (0, import_common.saveBuildLog)({ + line: `Cloning ${repository}:${branch}...`, + buildId, + applicationId + }); + if (gitCommitHash) { + await (0, import_common.saveBuildLog)({ + line: `Checking out ${gitCommitHash} commit...`, + buildId, + applicationId + }); + } + if (forPublic) { + await (0, import_executeCommand.executeCommand)( + { + command: `git clone -q -b ${branch} https://${url}/${repository}.git ${workdir}/ && cd ${workdir}/ && git checkout ${gitCommitHash || ""} && git submodule update --init --recursive && git lfs pull && cd .. `, + shell: true + } + ); + } else { + await (0, import_executeCommand.executeCommand)( + { + command: `git clone -q -b ${branch} ${customUser}@${url}:${repository}.git --config core.sshCommand="ssh -p ${customPort} -q -i ${repodir}id.rsa -o StrictHostKeyChecking=no" ${workdir}/ && cd ${workdir}/ && git checkout ${gitCommitHash || ""} && git submodule update --init --recursive && git lfs pull && cd .. `, + shell: true + } + ); + } + const { stdout: commit } = await (0, import_executeCommand.executeCommand)({ command: `cd ${workdir}/ && git rev-parse HEAD`, shell: true }); + return commit.replace("\n", ""); +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/apps/trpc-experimental/server/build/lib/importers/index.js b/apps/trpc-experimental/server/build/lib/importers/index.js new file mode 100644 index 000000000..c6d1a4b55 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/importers/index.js @@ -0,0 +1,37 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var importers_exports = {}; +__export(importers_exports, { + github: () => import_github.default, + gitlab: () => import_gitlab.default +}); +module.exports = __toCommonJS(importers_exports); +var import_github = __toESM(require("./github")); +var import_gitlab = __toESM(require("./gitlab")); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + github, + gitlab +}); diff --git a/apps/trpc-experimental/server/build/lib/logging.js b/apps/trpc-experimental/server/build/lib/logging.js new file mode 100644 index 000000000..e820a7925 --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/logging.js @@ -0,0 +1,75 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var logging_exports = {}; +__export(logging_exports, { + saveBuildLog: () => saveBuildLog +}); +module.exports = __toCommonJS(logging_exports); +var import_prisma = require("../prisma"); +var import_common = require("./common"); +var import_dayjs = require("./dayjs"); +const saveBuildLog = async ({ line, buildId, applicationId }) => { + if (buildId === "undefined" || buildId === "null" || !buildId) + return; + if (applicationId === "undefined" || applicationId === "null" || !applicationId) + return; + const { default: got } = await import("got"); + if (typeof line === "object" && line) { + if (line.shortMessage) { + line = line.shortMessage + "\n" + line.stderr; + } else { + line = JSON.stringify(line); + } + } + if (line && typeof line === "string" && line.includes("ghs_")) { + const regex = /ghs_.*@/g; + line = line.replace(regex, "@"); + } + const addTimestamp = `[${(0, import_common.generateTimestamp)()}] ${line}`; + const fluentBitUrl = import_common.isDev ? "http://localhost:24224" : "http://coolify-fluentbit:24224"; + if (import_common.isDev) { + console.debug(`[${applicationId}] ${addTimestamp}`); + } + try { + return await got.post(`${fluentBitUrl}/${applicationId}_buildlog_${buildId}.csv`, { + json: { + line: (0, import_common.encrypt)(line) + } + }); + } catch (error) { + return await import_prisma.prisma.buildLog.create({ + data: { + line: addTimestamp, + buildId, + time: Number((0, import_dayjs.day)().valueOf()), + applicationId + } + }); + } +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + saveBuildLog +}); diff --git a/apps/trpc-experimental/server/build/lib/ssh.js b/apps/trpc-experimental/server/build/lib/ssh.js new file mode 100644 index 000000000..508741eeb --- /dev/null +++ b/apps/trpc-experimental/server/build/lib/ssh.js @@ -0,0 +1,76 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var ssh_exports = {}; +__export(ssh_exports, { + getFreeSSHLocalPort: () => getFreeSSHLocalPort +}); +module.exports = __toCommonJS(ssh_exports); +var import_prisma = require("../prisma"); +var import_common = require("./common"); +async function getFreeSSHLocalPort(id) { + const { default: isReachable } = await import("is-port-reachable"); + const { remoteIpAddress, sshLocalPort } = await import_prisma.prisma.destinationDocker.findUnique({ + where: { id } + }); + if (sshLocalPort) { + return Number(sshLocalPort); + } + const data = await import_prisma.prisma.setting.findFirst(); + const { minPort, maxPort } = data; + const ports = await import_prisma.prisma.destinationDocker.findMany({ + where: { sshLocalPort: { not: null }, remoteIpAddress: { not: remoteIpAddress } } + }); + const alreadyConfigured = await import_prisma.prisma.destinationDocker.findFirst({ + where: { + remoteIpAddress, + id: { not: id }, + sshLocalPort: { not: null } + } + }); + if (alreadyConfigured?.sshLocalPort) { + await import_prisma.prisma.destinationDocker.update({ + where: { id }, + data: { sshLocalPort: alreadyConfigured.sshLocalPort } + }); + return Number(alreadyConfigured.sshLocalPort); + } + const range = (0, import_common.generateRangeArray)(minPort, maxPort); + const availablePorts = range.filter((port) => !ports.map((p) => p.sshLocalPort).includes(port)); + for (const port of availablePorts) { + const found = await isReachable(port, { host: "localhost" }); + if (!found) { + await import_prisma.prisma.destinationDocker.update({ + where: { id }, + data: { sshLocalPort: Number(port) } + }); + return Number(port); + } + } + return false; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + getFreeSSHLocalPort +}); diff --git a/apps/trpc-experimental/server/build/prisma.js b/apps/trpc-experimental/server/build/prisma.js new file mode 100644 index 000000000..ec44b3000 --- /dev/null +++ b/apps/trpc-experimental/server/build/prisma.js @@ -0,0 +1,36 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var prisma_exports = {}; +__export(prisma_exports, { + prisma: () => prisma +}); +module.exports = __toCommonJS(prisma_exports); +var import_env = require("./env"); +var import_client = require("@prisma/client"); +const prismaGlobal = global; +const prisma = prismaGlobal.prisma || new import_client.PrismaClient({ + log: import_env.env.NODE_ENV !== "development" ? ["query", "error", "warn"] : ["error"] +}); +if (import_env.env.NODE_ENV !== "production") { + prismaGlobal.prisma = prisma; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + prisma +}); diff --git a/apps/trpc-experimental/server/build/scheduler.js b/apps/trpc-experimental/server/build/scheduler.js new file mode 100644 index 000000000..2a9b35e73 --- /dev/null +++ b/apps/trpc-experimental/server/build/scheduler.js @@ -0,0 +1,48 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var scheduler_exports = {}; +__export(scheduler_exports, { + isDev: () => isDev, + scheduler: () => scheduler +}); +module.exports = __toCommonJS(scheduler_exports); +var import_bree = __toESM(require("bree")); +var import_path = __toESM(require("path")); +var import_ts_worker = __toESM(require("@breejs/ts-worker")); +const isDev = process.env["NODE_ENV"] === "development"; +import_bree.default.extend(import_ts_worker.default); +const options = { + defaultExtension: "js", + logger: false, + jobs: [{ name: "applicationBuildQueue" }] +}; +if (isDev) + options.root = import_path.default.join(__dirname, "./jobs"); +const scheduler = new import_bree.default(options); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + isDev, + scheduler +}); diff --git a/apps/trpc-experimental/server/build/server.js b/apps/trpc-experimental/server/build/server.js new file mode 100644 index 000000000..f821124ac --- /dev/null +++ b/apps/trpc-experimental/server/build/server.js @@ -0,0 +1,99 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var server_exports = {}; +__export(server_exports, { + createServer: () => createServer +}); +module.exports = __toCommonJS(server_exports); +var import_fastify = require("@trpc/server/adapters/fastify"); +var import_fastify2 = __toESM(require("fastify")); +var import_trpc = require("./trpc"); +var import_context = require("./trpc/context"); +var import_cors = __toESM(require("@fastify/cors")); +var path = __toESM(require("node:path")); +var import_static = __toESM(require("@fastify/static")); +var import_autoload = __toESM(require("@fastify/autoload")); +var import_graceful = __toESM(require("@ladjs/graceful")); +var import_scheduler = require("./scheduler"); +const isDev = process.env["NODE_ENV"] === "development"; +function createServer(opts) { + const dev = opts.dev ?? true; + const port = opts.port ?? 3e3; + const prefix = opts.prefix ?? "/trpc"; + const server = (0, import_fastify2.default)({ logger: dev, trustProxy: true }); + server.register(import_cors.default); + server.register(import_fastify.fastifyTRPCPlugin, { + prefix, + trpcOptions: { + router: import_trpc.appRouter, + createContext: import_context.createContext, + onError({ error, type, path: path2, input, ctx, req }) { + console.error("Error:", error); + if (error.code === "INTERNAL_SERVER_ERROR") { + } + } + } + }); + if (!isDev) { + server.register(import_static.default, { + root: path.join(__dirname, "./public"), + preCompressed: true + }); + server.setNotFoundHandler(async function(request, reply) { + if (request.raw.url && request.raw.url.startsWith("/api")) { + return reply.status(404).send({ + success: false + }); + } + return reply.status(200).sendFile("index.html"); + }); + } + server.register(import_autoload.default, { + dir: path.join(__dirname, "api"), + options: { prefix: "/api" } + }); + const stop = () => server.close(); + const start = async () => { + try { + await server.listen({ host: "0.0.0.0", port }); + console.log("Coolify server is listening on port", port, "at 0.0.0.0 \u{1F680}"); + const graceful = new import_graceful.default({ brees: [import_scheduler.scheduler] }); + graceful.listen(); + setInterval(async () => { + if (!import_scheduler.scheduler.workers.has("applicationBuildQueue")) { + import_scheduler.scheduler.run("applicationBuildQueue"); + } + }, 2e3); + } catch (err) { + server.log.error(err); + process.exit(1); + } + }; + return { server, start, stop }; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + createServer +}); diff --git a/apps/trpc-experimental/server/build/trpc/context.js b/apps/trpc-experimental/server/build/trpc/context.js new file mode 100644 index 000000000..953bece68 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/context.js @@ -0,0 +1,43 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var context_exports = {}; +__export(context_exports, { + createContext: () => createContext +}); +module.exports = __toCommonJS(context_exports); +var import_jsonwebtoken = __toESM(require("jsonwebtoken")); +var import_env = require("../env"); +function createContext({ req }) { + const token = req.headers.authorization; + let user = null; + if (token) { + user = import_jsonwebtoken.default.verify(token, import_env.env.COOLIFY_SECRET_KEY); + } + return { user, hostname: req.hostname }; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + createContext +}); diff --git a/apps/trpc-experimental/server/build/trpc/index.js b/apps/trpc-experimental/server/build/trpc/index.js new file mode 100644 index 000000000..a325a5955 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/index.js @@ -0,0 +1,39 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var trpc_exports = {}; +__export(trpc_exports, { + appRouter: () => appRouter +}); +module.exports = __toCommonJS(trpc_exports); +var import_trpc = require("./trpc"); +var import_routers = require("./routers"); +const appRouter = (0, import_trpc.router)({ + settings: import_routers.settingsRouter, + auth: import_routers.authRouter, + dashboard: import_routers.dashboardRouter, + applications: import_routers.applicationsRouter, + services: import_routers.servicesRouter, + databases: import_routers.databasesRouter, + sources: import_routers.sourcesRouter, + destinations: import_routers.destinationsRouter +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + appRouter +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/applications/index.js b/apps/trpc-experimental/server/build/trpc/routers/applications/index.js new file mode 100644 index 000000000..b34785834 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/applications/index.js @@ -0,0 +1,1277 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var applications_exports = {}; +__export(applications_exports, { + applicationsRouter: () => applicationsRouter +}); +module.exports = __toCommonJS(applications_exports); +var import_zod = require("zod"); +var import_promises = __toESM(require("fs/promises")); +var import_js_yaml = __toESM(require("js-yaml")); +var import_trpc = require("../../trpc"); +var import_prisma = require("../../../prisma"); +var import_executeCommand = require("../../../lib/executeCommand"); +var import_docker = require("../../../lib/docker"); +var import_lib = require("./lib"); +var import_cuid = __toESM(require("cuid")); +var import_common = require("../../../lib/common"); +var import_dayjs = require("../../../lib/dayjs"); +var import_csvtojson = __toESM(require("csvtojson")); +const applicationsRouter = (0, import_trpc.router)({ + deleteApplication: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + force: import_zod.z.boolean().default(false) + }) + ).mutation(async ({ input, ctx }) => { + const { id, force } = input; + const teamId = ctx.user.teamId; + const application = await import_prisma.prisma.application.findUnique({ + where: { id }, + include: { destinationDocker: true } + }); + if (!force && application?.destinationDockerId && application.destinationDocker?.network) { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: application.destinationDocker.id, + command: `docker ps -a --filter network=${application.destinationDocker.network} --filter name=${id} --format '{{json .}}'` + }); + if (containers) { + const containersArray = containers.trim().split("\n"); + for (const container of containersArray) { + const containerObj = JSON.parse(container); + const id2 = containerObj.ID; + await (0, import_docker.removeContainer)({ id: id2, dockerId: application.destinationDocker.id }); + } + } + } + await import_prisma.prisma.applicationSettings.deleteMany({ where: { application: { id } } }); + await import_prisma.prisma.buildLog.deleteMany({ where: { applicationId: id } }); + await import_prisma.prisma.build.deleteMany({ where: { applicationId: id } }); + await import_prisma.prisma.secret.deleteMany({ where: { applicationId: id } }); + await import_prisma.prisma.applicationPersistentStorage.deleteMany({ where: { applicationId: id } }); + await import_prisma.prisma.applicationConnectedDatabase.deleteMany({ where: { applicationId: id } }); + if (teamId === "0") { + await import_prisma.prisma.application.deleteMany({ where: { id } }); + } else { + await import_prisma.prisma.application.deleteMany({ where: { id, teams: { some: { id: teamId } } } }); + } + return {}; + }), + restartPreview: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + pullmergeRequestId: import_zod.z.string() + }) + ).mutation(async ({ input, ctx }) => { + const { id, pullmergeRequestId } = input; + const teamId = ctx.user.teamId; + let application = await (0, import_lib.getApplicationFromDB)(id, teamId); + if (application?.destinationDockerId) { + const buildId = (0, import_cuid.default)(); + const { id: dockerId, network } = application.destinationDocker; + const { + secrets, + port, + repository, + persistentStorage, + id: applicationId, + buildPack, + exposePort + } = application; + let envs = []; + if (secrets.length > 0) { + envs = [...envs, ...(0, import_common.generateSecrets)(secrets, pullmergeRequestId, false, port)]; + } + const { workdir } = await (0, import_common.createDirectories)({ repository, buildId }); + const labels = []; + let image = null; + const { stdout: container } = await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker container ls --filter 'label=com.docker.compose.service=${id}-${pullmergeRequestId}' --format '{{json .}}'` + }); + const containersArray = container.trim().split("\n"); + for (const container2 of containersArray) { + const containerObj = (0, import_docker.formatLabelsOnDocker)(container2); + image = containerObj[0].Image; + Object.keys(containerObj[0].Labels).forEach(function(key) { + if (key.startsWith("coolify")) { + labels.push(`${key}=${containerObj[0].Labels[key]}`); + } + }); + } + let imageFound = false; + try { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker image inspect ${image}` + }); + imageFound = true; + } catch (error) { + } + if (!imageFound) { + throw { status: 500, message: "Image not found, cannot restart application." }; + } + const volumes = persistentStorage?.map((storage) => { + return `${applicationId}${storage.path.replace(/\//gi, "-")}:${buildPack !== "docker" ? "/app" : ""}${storage.path}`; + }) || []; + const composeVolumes = volumes.map((volume) => { + return { + [`${volume.split(":")[0]}`]: { + name: volume.split(":")[0] + } + }; + }); + const composeFile = { + version: "3.8", + services: { + [`${applicationId}-${pullmergeRequestId}`]: { + image, + container_name: `${applicationId}-${pullmergeRequestId}`, + volumes, + environment: envs, + labels, + depends_on: [], + expose: [port], + ...exposePort ? { ports: [`${exposePort}:${port}`] } : {}, + ...(0, import_docker.defaultComposeConfiguration)(network) + } + }, + networks: { + [network]: { + external: true + } + }, + volumes: Object.assign({}, ...composeVolumes) + }; + await import_promises.default.writeFile(`${workdir}/docker-compose.yml`, import_js_yaml.default.dump(composeFile)); + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker stop -t 0 ${id}-${pullmergeRequestId}` }); + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker rm ${id}-${pullmergeRequestId}` }); + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker compose --project-directory ${workdir} up -d` + }); + } + }), + getPreviewStatus: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + pullmergeRequestId: import_zod.z.string() + }) + ).query(async ({ input, ctx }) => { + const { id, pullmergeRequestId } = input; + const teamId = ctx.user.teamId; + let isRunning = false; + let isExited = false; + let isRestarting = false; + let isBuilding = false; + const application = await (0, import_lib.getApplicationFromDB)(id, teamId); + if (application?.destinationDockerId) { + const status = await (0, import_docker.checkContainer)({ + dockerId: application.destinationDocker.id, + container: `${id}-${pullmergeRequestId}` + }); + if (status?.found) { + isRunning = status.status.isRunning; + isExited = status.status.isExited; + isRestarting = status.status.isRestarting; + } + const building = await import_prisma.prisma.build.findMany({ + where: { applicationId: id, pullmergeRequestId, status: { in: ["queued", "running"] } } + }); + isBuilding = building.length > 0; + } + return { + success: true, + data: { + isBuilding, + isRunning, + isRestarting, + isExited + } + }; + }), + loadPreviews: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).mutation(async ({ input, ctx }) => { + const { id } = input; + const application = await import_prisma.prisma.application.findUnique({ + where: { id }, + include: { destinationDocker: true } + }); + const { stdout } = await (0, import_executeCommand.executeCommand)({ + dockerId: application.destinationDocker.id, + command: `docker container ls --filter 'name=${id}-' --format "{{json .}}"` + }); + if (stdout === "") { + throw { status: 500, message: "No previews found." }; + } + const containers = (0, import_docker.formatLabelsOnDocker)(stdout).filter( + (container) => container.Labels["coolify.configuration"] && container.Labels["coolify.type"] === "standalone-application" + ); + const jsonContainers = containers.map( + (container) => JSON.parse(Buffer.from(container.Labels["coolify.configuration"], "base64").toString()) + ).filter((container) => { + return container.pullmergeRequestId && container.applicationId === id; + }); + for (const container of jsonContainers) { + const found = await import_prisma.prisma.previewApplication.findMany({ + where: { + applicationId: container.applicationId, + pullmergeRequestId: container.pullmergeRequestId + } + }); + if (found.length === 0) { + await import_prisma.prisma.previewApplication.create({ + data: { + pullmergeRequestId: container.pullmergeRequestId, + sourceBranch: container.branch, + customDomain: container.fqdn, + application: { connect: { id: container.applicationId } } + } + }); + } + } + return { + success: true, + data: { + previews: await import_prisma.prisma.previewApplication.findMany({ where: { applicationId: id } }) + } + }; + }), + stopPreview: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + pullmergeRequestId: import_zod.z.string() + }) + ).mutation(async ({ input, ctx }) => { + const { id, pullmergeRequestId } = input; + const teamId = ctx.user.teamId; + const application = await (0, import_lib.getApplicationFromDB)(id, teamId); + if (application?.destinationDockerId) { + const container = `${id}-${pullmergeRequestId}`; + const { id: dockerId } = application.destinationDocker; + const { found } = await (0, import_docker.checkContainer)({ dockerId, container }); + if (found) { + await (0, import_docker.removeContainer)({ id: container, dockerId: application.destinationDocker.id }); + } + await import_prisma.prisma.previewApplication.deleteMany({ + where: { applicationId: application.id, pullmergeRequestId } + }); + } + return {}; + }), + getUsage: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + containerId: import_zod.z.string() + }) + ).query(async ({ input, ctx }) => { + const { id, containerId } = input; + const teamId = ctx.user.teamId; + let usage = {}; + const application = await (0, import_lib.getApplicationFromDB)(id, teamId); + if (application.destinationDockerId) { + [usage] = await Promise.all([ + (0, import_common.getContainerUsage)(application.destinationDocker.id, containerId) + ]); + } + return { + success: true, + data: { + usage + } + }; + }), + getLocalImages: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).query(async ({ input, ctx }) => { + const { id } = input; + const teamId = ctx.user.teamId; + const application = await (0, import_lib.getApplicationFromDB)(id, teamId); + let imagesAvailables = []; + const { stdout } = await (0, import_executeCommand.executeCommand)({ + dockerId: application.destinationDocker.id, + command: `docker images --format '{{.Repository}}#{{.Tag}}#{{.CreatedAt}}'` + }); + const { stdout: runningImage } = await (0, import_executeCommand.executeCommand)({ + dockerId: application.destinationDocker.id, + command: `docker ps -a --filter 'label=com.docker.compose.service=${id}' --format {{.Image}}` + }); + const images = stdout.trim().split("\n").filter((image) => image.includes(id) && !image.includes("-cache")); + for (const image of images) { + const [repository, tag, createdAt] = image.split("#"); + if (tag.includes("-")) { + continue; + } + const [year, time] = createdAt.split(" "); + imagesAvailables.push({ + repository, + tag, + createdAt: (0, import_dayjs.day)(year + time).unix() + }); + } + imagesAvailables = imagesAvailables.sort((a, b) => b.tag - a.tag); + return { + success: true, + data: { + imagesAvailables, + runningImage + } + }; + }), + resetQueue: import_trpc.privateProcedure.mutation(async ({ ctx }) => { + const teamId = ctx.user.teamId; + if (teamId === "0") { + await import_prisma.prisma.build.updateMany({ + where: { status: { in: ["queued", "running"] } }, + data: { status: "canceled" } + }); + } + }), + cancelBuild: import_trpc.privateProcedure.input( + import_zod.z.object({ + buildId: import_zod.z.string(), + applicationId: import_zod.z.string() + }) + ).mutation(async ({ input }) => { + const { buildId, applicationId } = input; + let count = 0; + await new Promise(async (resolve, reject) => { + const { destinationDockerId, status } = await import_prisma.prisma.build.findFirst({ + where: { id: buildId } + }); + const { id: dockerId } = await import_prisma.prisma.destinationDocker.findFirst({ + where: { id: destinationDockerId } + }); + const interval = setInterval(async () => { + try { + if (status === "failed" || status === "canceled") { + clearInterval(interval); + return resolve(); + } + if (count > 15) { + clearInterval(interval); + await (0, import_common.cleanupDB)(buildId, applicationId); + return reject(new Error("Canceled.")); + } + const { stdout: buildContainers } = await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker container ls --filter "label=coolify.buildId=${buildId}" --format '{{json .}}'` + }); + if (buildContainers) { + const containersArray = buildContainers.trim().split("\n"); + for (const container of containersArray) { + const containerObj = JSON.parse(container); + const id = containerObj.ID; + if (!containerObj.Names.startsWith(`${applicationId} `)) { + await (0, import_docker.removeContainer)({ id, dockerId }); + clearInterval(interval); + await (0, import_common.cleanupDB)(buildId, applicationId); + return resolve(); + } + } + } + count++; + } catch (error) { + } + }, 100); + }); + }), + getBuildLogs: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + buildId: import_zod.z.string(), + sequence: import_zod.z.number() + }) + ).query(async ({ input }) => { + let { id, buildId, sequence } = input; + let file = `/app/logs/${id}_buildlog_${buildId}.csv`; + if (import_common.isDev) { + file = `${process.cwd()}/../../logs/${id}_buildlog_${buildId}.csv`; + } + const data = await import_prisma.prisma.build.findFirst({ where: { id: buildId } }); + const createdAt = (0, import_dayjs.day)(data.createdAt).utc(); + try { + await import_promises.default.stat(file); + } catch (error) { + let logs2 = await import_prisma.prisma.buildLog.findMany({ + where: { buildId, time: { gt: sequence } }, + orderBy: { time: "asc" } + }); + const data2 = await import_prisma.prisma.build.findFirst({ where: { id: buildId } }); + const createdAt2 = (0, import_dayjs.day)(data2.createdAt).utc(); + return { + logs: logs2.map((log) => { + log.time = Number(log.time); + return log; + }), + fromDb: true, + took: (0, import_dayjs.day)().diff(createdAt2) / 1e3, + status: data2?.status || "queued" + }; + } + let fileLogs = (await import_promises.default.readFile(file)).toString(); + let decryptedLogs = await (0, import_csvtojson.default)({ noheader: true }).fromString(fileLogs); + let logs = decryptedLogs.map((log) => { + const parsed = { + time: log["field1"], + line: (0, import_common.decrypt)(log["field2"] + '","' + log["field3"]) + }; + return parsed; + }).filter((log) => log.time > sequence); + return { + logs, + fromDb: false, + took: (0, import_dayjs.day)().diff(createdAt) / 1e3, + status: data?.status || "queued" + }; + }), + getBuilds: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + buildId: import_zod.z.string().optional(), + skip: import_zod.z.number() + }) + ).query(async ({ input }) => { + let { id, buildId, skip } = input; + let builds = []; + const buildCount = await import_prisma.prisma.build.count({ where: { applicationId: id } }); + if (buildId) { + builds = await import_prisma.prisma.build.findMany({ where: { applicationId: id, id: buildId } }); + } else { + builds = await import_prisma.prisma.build.findMany({ + where: { applicationId: id }, + orderBy: { createdAt: "desc" }, + take: 5 + skip + }); + } + builds = builds.map((build) => { + if (build.status === "running") { + build.elapsed = ((0, import_dayjs.day)().utc().diff((0, import_dayjs.day)(build.createdAt)) / 1e3).toFixed(0); + } + return build; + }); + return { + builds, + buildCount + }; + }), + loadLogs: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + containerId: import_zod.z.string(), + since: import_zod.z.number() + }) + ).query(async ({ input }) => { + let { id, containerId, since } = input; + if (since !== 0) { + since = (0, import_dayjs.day)(since).unix(); + } + const { + destinationDockerId, + destinationDocker: { id: dockerId } + } = await import_prisma.prisma.application.findUnique({ + where: { id }, + include: { destinationDocker: true } + }); + if (destinationDockerId) { + try { + const { default: ansi } = await import("strip-ansi"); + const { stdout, stderr } = await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker logs --since ${since} --tail 5000 --timestamps ${containerId}` + }); + const stripLogsStdout = stdout.toString().split("\n").map((l) => ansi(l)).filter((a) => a); + const stripLogsStderr = stderr.toString().split("\n").map((l) => ansi(l)).filter((a) => a); + const logs = stripLogsStderr.concat(stripLogsStdout); + const sortedLogs = logs.sort( + (a, b) => (0, import_dayjs.day)(a.split(" ")[0]).isAfter((0, import_dayjs.day)(b.split(" ")[0])) ? 1 : -1 + ); + return { logs: sortedLogs }; + } catch (error) { + const { statusCode, stderr } = error; + if (stderr.startsWith("Error: No such container")) { + return { logs: [], noContainer: true }; + } + if (statusCode === 404) { + return { + logs: [] + }; + } + } + } + return { + message: "No logs found." + }; + }), + getStorages: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).query(async ({ input }) => { + const { id } = input; + const persistentStorages = await import_prisma.prisma.applicationPersistentStorage.findMany({ + where: { applicationId: id } + }); + return { + success: true, + data: { + persistentStorages + } + }; + }), + deleteStorage: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + path: import_zod.z.string() + }) + ).mutation(async ({ input }) => { + const { id, path } = input; + await import_prisma.prisma.applicationPersistentStorage.deleteMany({ where: { applicationId: id, path } }); + }), + updateStorage: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + path: import_zod.z.string(), + storageId: import_zod.z.string(), + newStorage: import_zod.z.boolean().optional().default(false) + }) + ).mutation(async ({ input }) => { + const { id, path, newStorage, storageId } = input; + if (newStorage) { + await import_prisma.prisma.applicationPersistentStorage.create({ + data: { path, application: { connect: { id } } } + }); + } else { + await import_prisma.prisma.applicationPersistentStorage.update({ + where: { id: storageId }, + data: { path } + }); + } + }), + deleteSecret: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + name: import_zod.z.string() + }) + ).mutation(async ({ input }) => { + const { id, name } = input; + await import_prisma.prisma.secret.deleteMany({ where: { applicationId: id, name } }); + }), + updateSecret: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + name: import_zod.z.string(), + value: import_zod.z.string(), + isBuildSecret: import_zod.z.boolean().optional().default(false), + isPreview: import_zod.z.boolean().optional().default(false) + }) + ).mutation(async ({ input }) => { + const { id, name, value, isBuildSecret, isPreview } = input; + console.log({ isBuildSecret }); + await import_prisma.prisma.secret.updateMany({ + where: { applicationId: id, name, isPRMRSecret: isPreview }, + data: { value: (0, import_common.encrypt)(value.trim()), isBuildSecret } + }); + }), + newSecret: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + name: import_zod.z.string(), + value: import_zod.z.string(), + isBuildSecret: import_zod.z.boolean().optional().default(false) + }) + ).mutation(async ({ input }) => { + const { id, name, value, isBuildSecret } = input; + const found = await import_prisma.prisma.secret.findMany({ where: { applicationId: id, name } }); + if (found.length > 0) { + throw { message: "Secret already exists." }; + } + await import_prisma.prisma.secret.create({ + data: { + name, + value: (0, import_common.encrypt)(value.trim()), + isBuildSecret, + isPRMRSecret: false, + application: { connect: { id } } + } + }); + await import_prisma.prisma.secret.create({ + data: { + name, + value: (0, import_common.encrypt)(value.trim()), + isBuildSecret, + isPRMRSecret: true, + application: { connect: { id } } + } + }); + }), + getSecrets: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).query(async ({ input }) => { + const { id } = input; + let secrets = await import_prisma.prisma.secret.findMany({ + where: { applicationId: id, isPRMRSecret: false }, + orderBy: { createdAt: "asc" } + }); + let previewSecrets = await import_prisma.prisma.secret.findMany({ + where: { applicationId: id, isPRMRSecret: true }, + orderBy: { createdAt: "asc" } + }); + secrets = secrets.map((secret) => { + secret.value = (0, import_common.decrypt)(secret.value); + return secret; + }); + previewSecrets = previewSecrets.map((secret) => { + secret.value = (0, import_common.decrypt)(secret.value); + return secret; + }); + return { + success: true, + data: { + previewSecrets: previewSecrets.sort((a, b) => { + return ("" + a.name).localeCompare(b.name); + }), + secrets: secrets.sort((a, b) => { + return ("" + a.name).localeCompare(b.name); + }) + } + }; + }), + checkDomain: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + domain: import_zod.z.string() + }) + ).query(async ({ input, ctx }) => { + const { id, domain } = input; + const { + fqdn, + settings: { dualCerts } + } = await import_prisma.prisma.application.findUnique({ where: { id }, include: { settings: true } }); + return await (0, import_common.checkDomainsIsValidInDNS)({ hostname: domain, fqdn, dualCerts }); + }), + checkDNS: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + fqdn: import_zod.z.string(), + forceSave: import_zod.z.boolean(), + dualCerts: import_zod.z.boolean(), + exposePort: import_zod.z.number().nullable().optional() + }) + ).mutation(async ({ input, ctx }) => { + let { id, exposePort, fqdn, forceSave, dualCerts } = input; + if (!fqdn) { + return {}; + } else { + fqdn = fqdn.toLowerCase(); + } + if (exposePort) + exposePort = Number(exposePort); + const { + destinationDocker: { engine, remoteIpAddress, remoteEngine }, + exposePort: configuredPort + } = await import_prisma.prisma.application.findUnique({ + where: { id }, + include: { destinationDocker: true } + }); + const { isDNSCheckEnabled } = await import_prisma.prisma.setting.findFirst({}); + const found = await (0, import_common.isDomainConfigured)({ id, fqdn, remoteIpAddress }); + if (found) { + throw { + status: 500, + message: `Domain ${(0, import_common.getDomain)(fqdn).replace("www.", "")} is already in use!` + }; + } + if (exposePort) + await (0, import_common.checkExposedPort)({ + id, + configuredPort, + exposePort, + engine, + remoteEngine, + remoteIpAddress + }); + if (isDNSCheckEnabled && !import_common.isDev && !forceSave) { + let hostname = ctx.hostname.split(":")[0]; + if (remoteEngine) + hostname = remoteIpAddress; + return await (0, import_common.checkDomainsIsValidInDNS)({ hostname, fqdn, dualCerts }); + } + }), + saveSettings: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + previews: import_zod.z.boolean().optional(), + debug: import_zod.z.boolean().optional(), + dualCerts: import_zod.z.boolean().optional(), + isBot: import_zod.z.boolean().optional(), + autodeploy: import_zod.z.boolean().optional(), + isDBBranching: import_zod.z.boolean().optional(), + isCustomSSL: import_zod.z.boolean().optional() + }) + ).mutation(async ({ ctx, input }) => { + const { id, debug, previews, dualCerts, autodeploy, isBot, isDBBranching, isCustomSSL } = input; + await import_prisma.prisma.application.update({ + where: { id }, + data: { + fqdn: isBot ? null : void 0, + settings: { + update: { debug, previews, dualCerts, autodeploy, isBot, isDBBranching, isCustomSSL } + } + }, + include: { destinationDocker: true } + }); + }), + getImages: import_trpc.privateProcedure.input(import_zod.z.object({ buildPack: import_zod.z.string(), deploymentType: import_zod.z.string().nullable() })).query(async ({ ctx, input }) => { + const { buildPack, deploymentType } = input; + let publishDirectory = void 0; + let port = void 0; + const { baseImage, baseBuildImage, baseBuildImages, baseImages } = (0, import_lib.setDefaultBaseImage)( + buildPack, + deploymentType + ); + if (buildPack === "nextjs") { + if (deploymentType === "static") { + publishDirectory = "out"; + port = "80"; + } else { + publishDirectory = ""; + port = "3000"; + } + } + if (buildPack === "nuxtjs") { + if (deploymentType === "static") { + publishDirectory = "dist"; + port = "80"; + } else { + publishDirectory = ""; + port = "3000"; + } + } + return { + success: true, + data: { baseImage, baseImages, baseBuildImage, baseBuildImages, publishDirectory, port } + }; + }), + getApplicationById: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).query(async ({ ctx, input }) => { + const id = input.id; + const teamId = ctx.user?.teamId; + if (!teamId) { + throw { status: 400, message: "Team not found." }; + } + const application = await (0, import_lib.getApplicationFromDB)(id, teamId); + return { + success: true, + data: { ...application } + }; + }), + save: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + name: import_zod.z.string(), + buildPack: import_zod.z.string(), + fqdn: import_zod.z.string().nullable().optional(), + port: import_zod.z.number(), + exposePort: import_zod.z.number().nullable().optional(), + installCommand: import_zod.z.string(), + buildCommand: import_zod.z.string(), + startCommand: import_zod.z.string(), + baseDirectory: import_zod.z.string().nullable().optional(), + publishDirectory: import_zod.z.string().nullable().optional(), + pythonWSGI: import_zod.z.string().nullable().optional(), + pythonModule: import_zod.z.string().nullable().optional(), + pythonVariable: import_zod.z.string().nullable().optional(), + dockerFileLocation: import_zod.z.string(), + denoMainFile: import_zod.z.string().nullable().optional(), + denoOptions: import_zod.z.string().nullable().optional(), + gitCommitHash: import_zod.z.string(), + baseImage: import_zod.z.string(), + baseBuildImage: import_zod.z.string(), + deploymentType: import_zod.z.string().nullable().optional(), + baseDatabaseBranch: import_zod.z.string().nullable().optional(), + dockerComposeFile: import_zod.z.string().nullable().optional(), + dockerComposeFileLocation: import_zod.z.string().nullable().optional(), + dockerComposeConfiguration: import_zod.z.string().nullable().optional(), + simpleDockerfile: import_zod.z.string().nullable().optional(), + dockerRegistryImageName: import_zod.z.string().nullable().optional() + }) + ).mutation(async ({ input }) => { + let { + id, + name, + buildPack, + fqdn, + port, + exposePort, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory, + pythonWSGI, + pythonModule, + pythonVariable, + dockerFileLocation, + denoMainFile, + denoOptions, + gitCommitHash, + baseImage, + baseBuildImage, + deploymentType, + baseDatabaseBranch, + dockerComposeFile, + dockerComposeFileLocation, + dockerComposeConfiguration, + simpleDockerfile, + dockerRegistryImageName + } = input; + const { + destinationDocker: { engine, remoteEngine, remoteIpAddress }, + exposePort: configuredPort + } = await import_prisma.prisma.application.findUnique({ + where: { id }, + include: { destinationDocker: true } + }); + if (exposePort) + await (0, import_common.checkExposedPort)({ + id, + configuredPort, + exposePort, + engine, + remoteEngine, + remoteIpAddress + }); + if (denoOptions) + denoOptions = denoOptions.trim(); + const defaultConfiguration = await (0, import_common.setDefaultConfiguration)({ + buildPack, + port, + installCommand, + startCommand, + buildCommand, + publishDirectory, + baseDirectory, + dockerFileLocation, + dockerComposeFileLocation, + denoMainFile + }); + if (baseDatabaseBranch) { + await import_prisma.prisma.application.update({ + where: { id }, + data: { + name, + fqdn, + exposePort, + pythonWSGI, + pythonModule, + pythonVariable, + denoOptions, + baseImage, + gitCommitHash, + baseBuildImage, + deploymentType, + dockerComposeFile, + dockerComposeConfiguration, + simpleDockerfile, + dockerRegistryImageName, + ...defaultConfiguration, + connectedDatabase: { update: { hostedDatabaseDBName: baseDatabaseBranch } } + } + }); + } else { + await import_prisma.prisma.application.update({ + where: { id }, + data: { + name, + fqdn, + exposePort, + pythonWSGI, + pythonModule, + gitCommitHash, + pythonVariable, + denoOptions, + baseImage, + baseBuildImage, + deploymentType, + dockerComposeFile, + dockerComposeConfiguration, + simpleDockerfile, + dockerRegistryImageName, + ...defaultConfiguration + } + }); + } + }), + status: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).query(async ({ ctx, input }) => { + const id = input.id; + const teamId = ctx.user?.teamId; + if (!teamId) { + throw { status: 400, message: "Team not found." }; + } + let payload = []; + const application = await (0, import_lib.getApplicationFromDB)(id, teamId); + if (application?.destinationDockerId) { + if (application.buildPack === "compose") { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: application.destinationDocker.id, + command: `docker ps -a --filter "label=coolify.applicationId=${id}" --format '{{json .}}'` + }); + const containersArray = containers.trim().split("\n"); + if (containersArray.length > 0 && containersArray[0] !== "") { + for (const container of containersArray) { + let isRunning = false; + let isExited = false; + let isRestarting = false; + const containerObj = JSON.parse(container); + const status = containerObj.State; + if (status === "running") { + isRunning = true; + } + if (status === "exited") { + isExited = true; + } + if (status === "restarting") { + isRestarting = true; + } + payload.push({ + name: containerObj.Names, + status: { + isRunning, + isExited, + isRestarting + } + }); + } + } + } else { + let isRunning = false; + let isExited = false; + let isRestarting = false; + const status = await (0, import_docker.checkContainer)({ + dockerId: application.destinationDocker.id, + container: id + }); + if (status?.found) { + isRunning = status.status.isRunning; + isExited = status.status.isExited; + isRestarting = status.status.isRestarting; + payload.push({ + name: id, + status: { + isRunning, + isExited, + isRestarting + } + }); + } + } + } + return payload; + }), + cleanup: import_trpc.privateProcedure.query(async ({ ctx }) => { + const teamId = ctx.user?.teamId; + let applications = await import_prisma.prisma.application.findMany({ + where: { teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { settings: true, destinationDocker: true, teams: true } + }); + for (const application of applications) { + if (!application.buildPack || !application.destinationDockerId || !application.branch || !application.settings?.isBot && !application?.fqdn) { + if (application?.destinationDockerId && application.destinationDocker?.network) { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: application.destinationDocker.id, + command: `docker ps -a --filter network=${application.destinationDocker.network} --filter name=${application.id} --format '{{json .}}'` + }); + if (containers) { + const containersArray = containers.trim().split("\n"); + for (const container of containersArray) { + const containerObj = JSON.parse(container); + const id = containerObj.ID; + await (0, import_docker.removeContainer)({ id, dockerId: application.destinationDocker.id }); + } + } + } + await import_prisma.prisma.applicationSettings.deleteMany({ where: { applicationId: application.id } }); + await import_prisma.prisma.buildLog.deleteMany({ where: { applicationId: application.id } }); + await import_prisma.prisma.build.deleteMany({ where: { applicationId: application.id } }); + await import_prisma.prisma.secret.deleteMany({ where: { applicationId: application.id } }); + await import_prisma.prisma.applicationPersistentStorage.deleteMany({ + where: { applicationId: application.id } + }); + await import_prisma.prisma.applicationConnectedDatabase.deleteMany({ + where: { applicationId: application.id } + }); + await import_prisma.prisma.application.deleteMany({ where: { id: application.id } }); + } + } + return {}; + }), + stop: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).mutation(async ({ ctx, input }) => { + const { id } = input; + const teamId = ctx.user?.teamId; + const application = await (0, import_lib.getApplicationFromDB)(id, teamId); + if (application?.destinationDockerId) { + const { id: dockerId } = application.destinationDocker; + if (application.buildPack === "compose") { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: application.destinationDocker.id, + command: `docker ps -a --filter "label=coolify.applicationId=${id}" --format '{{json .}}'` + }); + const containersArray = containers.trim().split("\n"); + if (containersArray.length > 0 && containersArray[0] !== "") { + for (const container of containersArray) { + const containerObj = JSON.parse(container); + await (0, import_docker.removeContainer)({ + id: containerObj.ID, + dockerId: application.destinationDocker.id + }); + } + } + return; + } + const { found } = await (0, import_docker.checkContainer)({ dockerId, container: id }); + if (found) { + await (0, import_docker.removeContainer)({ id, dockerId: application.destinationDocker.id }); + } + } + return {}; + }), + restart: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string(), imageId: import_zod.z.string().nullable() })).mutation(async ({ ctx, input }) => { + const { id, imageId } = input; + const teamId = ctx.user?.teamId; + let application = await (0, import_lib.getApplicationFromDB)(id, teamId); + if (application?.destinationDockerId) { + const buildId = (0, import_cuid.default)(); + const { id: dockerId, network } = application.destinationDocker; + const { + dockerRegistry, + secrets, + pullmergeRequestId, + port, + repository, + persistentStorage, + id: applicationId, + buildPack, + exposePort + } = application; + let location = null; + const labels = []; + let image = null; + const envs = [`PORT=${port}`, "NODE_ENV=production"]; + if (secrets.length > 0) { + secrets.forEach((secret) => { + if (pullmergeRequestId) { + const isSecretFound = secrets.filter((s) => s.name === secret.name && s.isPRMRSecret); + if (isSecretFound.length > 0) { + if (isSecretFound[0].value.includes("\\n") || isSecretFound[0].value.includes("'")) { + envs.push(`${secret.name}=${isSecretFound[0].value}`); + } else { + envs.push(`${secret.name}='${isSecretFound[0].value}'`); + } + } else { + if (secret.value.includes("\\n") || secret.value.includes("'")) { + envs.push(`${secret.name}=${secret.value}`); + } else { + envs.push(`${secret.name}='${secret.value}'`); + } + } + } else { + if (!secret.isPRMRSecret) { + if (secret.value.includes("\\n") || secret.value.includes("'")) { + envs.push(`${secret.name}=${secret.value}`); + } else { + envs.push(`${secret.name}='${secret.value}'`); + } + } + } + }); + } + const { workdir } = await (0, import_common.createDirectories)({ repository, buildId }); + if (imageId) { + image = imageId; + } else { + const { stdout: container } = await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker container ls --filter 'label=com.docker.compose.service=${id}' --format '{{json .}}'` + }); + const containersArray = container.trim().split("\n"); + for (const container2 of containersArray) { + const containerObj = (0, import_docker.formatLabelsOnDocker)(container2); + image = containerObj[0].Image; + Object.keys(containerObj[0].Labels).forEach(function(key) { + if (key.startsWith("coolify")) { + labels.push(`${key}=${containerObj[0].Labels[key]}`); + } + }); + } + } + if (dockerRegistry) { + const { url, username, password } = dockerRegistry; + location = await (0, import_common.saveDockerRegistryCredentials)({ url, username, password, workdir }); + } + let imageFoundLocally = false; + try { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker image inspect ${image}` + }); + imageFoundLocally = true; + } catch (error) { + } + let imageFoundRemotely = false; + try { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker ${location ? `--config ${location}` : ""} pull ${image}` + }); + imageFoundRemotely = true; + } catch (error) { + } + if (!imageFoundLocally && !imageFoundRemotely) { + throw { status: 500, message: "Image not found, cannot restart application." }; + } + await import_promises.default.writeFile(`${workdir}/.env`, envs.join("\n")); + let envFound = false; + try { + envFound = !!await import_promises.default.stat(`${workdir}/.env`); + } catch (error) { + } + const volumes = persistentStorage?.map((storage) => { + return `${applicationId}${storage.path.replace(/\//gi, "-")}:${buildPack !== "docker" ? "/app" : ""}${storage.path}`; + }) || []; + const composeVolumes = volumes.map((volume) => { + return { + [`${volume.split(":")[0]}`]: { + name: volume.split(":")[0] + } + }; + }); + const composeFile = { + version: "3.8", + services: { + [applicationId]: { + image, + container_name: applicationId, + volumes, + env_file: envFound ? [`${workdir}/.env`] : [], + labels, + depends_on: [], + expose: [port], + ...exposePort ? { ports: [`${exposePort}:${port}`] } : {}, + ...(0, import_docker.defaultComposeConfiguration)(network) + } + }, + networks: { + [network]: { + external: true + } + }, + volumes: Object.assign({}, ...composeVolumes) + }; + await import_promises.default.writeFile(`${workdir}/docker-compose.yml`, import_js_yaml.default.dump(composeFile)); + try { + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker stop -t 0 ${id}` }); + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker rm ${id}` }); + } catch (error) { + } + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker compose --project-directory ${workdir} up -d` + }); + } + return {}; + }), + deploy: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + forceRebuild: import_zod.z.boolean().default(false), + pullmergeRequestId: import_zod.z.string().nullable().optional(), + branch: import_zod.z.string().nullable().optional() + }) + ).mutation(async ({ ctx, input }) => { + const { id, pullmergeRequestId, branch, forceRebuild } = input; + const teamId = ctx.user?.teamId; + const buildId = await (0, import_lib.deployApplication)(id, teamId, forceRebuild, pullmergeRequestId, branch); + return { + buildId + }; + }), + forceRedeploy: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).mutation(async ({ ctx, input }) => { + const { id } = input; + const teamId = ctx.user?.teamId; + const buildId = await (0, import_lib.deployApplication)(id, teamId, true); + return { + buildId + }; + }), + delete: import_trpc.privateProcedure.input(import_zod.z.object({ force: import_zod.z.boolean(), id: import_zod.z.string() })).mutation(async ({ ctx, input }) => { + const { id, force } = input; + const teamId = ctx.user?.teamId; + const application = await import_prisma.prisma.application.findUnique({ + where: { id }, + include: { destinationDocker: true } + }); + if (!force && application?.destinationDockerId && application.destinationDocker?.network) { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: application.destinationDocker.id, + command: `docker ps -a --filter network=${application.destinationDocker.network} --filter name=${id} --format '{{json .}}'` + }); + if (containers) { + const containersArray = containers.trim().split("\n"); + for (const container of containersArray) { + const containerObj = JSON.parse(container); + const id2 = containerObj.ID; + await (0, import_docker.removeContainer)({ id: id2, dockerId: application.destinationDocker.id }); + } + } + } + await import_prisma.prisma.applicationSettings.deleteMany({ where: { application: { id } } }); + await import_prisma.prisma.buildLog.deleteMany({ where: { applicationId: id } }); + await import_prisma.prisma.build.deleteMany({ where: { applicationId: id } }); + await import_prisma.prisma.secret.deleteMany({ where: { applicationId: id } }); + await import_prisma.prisma.applicationPersistentStorage.deleteMany({ where: { applicationId: id } }); + await import_prisma.prisma.applicationConnectedDatabase.deleteMany({ where: { applicationId: id } }); + if (teamId === "0") { + await import_prisma.prisma.application.deleteMany({ where: { id } }); + } else { + await import_prisma.prisma.application.deleteMany({ where: { id, teams: { some: { id: teamId } } } }); + } + return {}; + }) +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + applicationsRouter +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/applications/lib.js b/apps/trpc-experimental/server/build/trpc/routers/applications/lib.js new file mode 100644 index 000000000..95a6d7b1d --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/applications/lib.js @@ -0,0 +1,526 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var lib_exports = {}; +__export(lib_exports, { + deployApplication: () => deployApplication, + generateConfigHash: () => generateConfigHash, + getApplicationFromDB: () => getApplicationFromDB, + setDefaultBaseImage: () => setDefaultBaseImage +}); +module.exports = __toCommonJS(lib_exports); +var import_cuid = __toESM(require("cuid")); +var import_node_crypto = __toESM(require("node:crypto")); +var import_common = require("../../../lib/common"); +var import_prisma = require("../../../prisma"); +async function deployApplication(id, teamId, forceRebuild, pullmergeRequestId = null, branch = null) { + const buildId = (0, import_cuid.default)(); + const application = await getApplicationFromDB(id, teamId); + if (application) { + if (!application?.configHash) { + await generateConfigHash( + id, + application.buildPack, + application.port, + application.exposePort, + application.installCommand, + application.buildCommand, + application.startCommand + ); + } + await import_prisma.prisma.application.update({ where: { id }, data: { updatedAt: new Date() } }); + if (application.gitSourceId) { + await import_prisma.prisma.build.create({ + data: { + id: buildId, + applicationId: id, + sourceBranch: branch, + branch: application.branch, + pullmergeRequestId: pullmergeRequestId?.toString(), + forceRebuild, + destinationDockerId: application.destinationDocker?.id, + gitSourceId: application.gitSource?.id, + githubAppId: application.gitSource?.githubApp?.id, + gitlabAppId: application.gitSource?.gitlabApp?.id, + status: "queued", + type: pullmergeRequestId ? application.gitSource?.githubApp?.id ? "manual_pr" : "manual_mr" : "manual" + } + }); + } else { + await import_prisma.prisma.build.create({ + data: { + id: buildId, + applicationId: id, + branch: "latest", + forceRebuild, + destinationDockerId: application.destinationDocker?.id, + status: "queued", + type: "manual" + } + }); + } + return buildId; + } + throw { status: 500, message: "Application cannot be deployed." }; +} +async function generateConfigHash(id, buildPack, port, exposePort, installCommand, buildCommand, startCommand) { + const configHash = import_node_crypto.default.createHash("sha256").update( + JSON.stringify({ + buildPack, + port, + exposePort, + installCommand, + buildCommand, + startCommand + }) + ).digest("hex"); + return await import_prisma.prisma.application.update({ where: { id }, data: { configHash } }); +} +async function getApplicationFromDB(id, teamId) { + let application = await import_prisma.prisma.application.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { + destinationDocker: true, + settings: true, + gitSource: { include: { githubApp: true, gitlabApp: true } }, + secrets: true, + persistentStorage: true, + connectedDatabase: true, + previewApplication: true, + dockerRegistry: true + } + }); + if (!application) { + throw { status: 404, message: "Application not found." }; + } + application = decryptApplication(application); + const buildPack = application?.buildPack || null; + const { baseImage, baseBuildImage, baseBuildImages, baseImages } = setDefaultBaseImage(buildPack); + if (application && !application.baseImage) { + application.baseImage = baseImage; + } + if (application && !application.baseBuildImage) { + application.baseBuildImage = baseBuildImage; + } + return { ...application, baseBuildImages, baseImages }; +} +function decryptApplication(application) { + if (application) { + if (application?.gitSource?.githubApp?.clientSecret) { + application.gitSource.githubApp.clientSecret = (0, import_common.decrypt)(application.gitSource.githubApp.clientSecret) || null; + } + if (application?.gitSource?.githubApp?.webhookSecret) { + application.gitSource.githubApp.webhookSecret = (0, import_common.decrypt)(application.gitSource.githubApp.webhookSecret) || null; + } + if (application?.gitSource?.githubApp?.privateKey) { + application.gitSource.githubApp.privateKey = (0, import_common.decrypt)(application.gitSource.githubApp.privateKey) || null; + } + if (application?.gitSource?.gitlabApp?.appSecret) { + application.gitSource.gitlabApp.appSecret = (0, import_common.decrypt)(application.gitSource.gitlabApp.appSecret) || null; + } + if (application?.secrets.length > 0) { + application.secrets = application.secrets.map((s) => { + s.value = (0, import_common.decrypt)(s.value) || null; + return s; + }); + } + return application; + } +} +const staticApps = ["static", "react", "vuejs", "svelte", "gatsby", "astro", "eleventy"]; +const nodeBased = [ + "react", + "preact", + "vuejs", + "svelte", + "gatsby", + "astro", + "eleventy", + "node", + "nestjs", + "nuxtjs", + "nextjs" +]; +function setDefaultBaseImage(buildPack, deploymentType = null) { + const nodeVersions = [ + { + value: "node:lts", + label: "node:lts" + }, + { + value: "node:18", + label: "node:18" + }, + { + value: "node:17", + label: "node:17" + }, + { + value: "node:16", + label: "node:16" + }, + { + value: "node:14", + label: "node:14" + }, + { + value: "node:12", + label: "node:12" + } + ]; + const staticVersions = [ + { + value: "webdevops/nginx:alpine", + label: "webdevops/nginx:alpine" + }, + { + value: "webdevops/apache:alpine", + label: "webdevops/apache:alpine" + }, + { + value: "nginx:alpine", + label: "nginx:alpine" + }, + { + value: "httpd:alpine", + label: "httpd:alpine (Apache)" + } + ]; + const rustVersions = [ + { + value: "rust:latest", + label: "rust:latest" + }, + { + value: "rust:1.60", + label: "rust:1.60" + }, + { + value: "rust:1.60-buster", + label: "rust:1.60-buster" + }, + { + value: "rust:1.60-bullseye", + label: "rust:1.60-bullseye" + }, + { + value: "rust:1.60-slim-buster", + label: "rust:1.60-slim-buster" + }, + { + value: "rust:1.60-slim-bullseye", + label: "rust:1.60-slim-bullseye" + }, + { + value: "rust:1.60-alpine3.14", + label: "rust:1.60-alpine3.14" + }, + { + value: "rust:1.60-alpine3.15", + label: "rust:1.60-alpine3.15" + } + ]; + const phpVersions = [ + { + value: "webdevops/php-apache:8.2", + label: "webdevops/php-apache:8.2" + }, + { + value: "webdevops/php-nginx:8.2", + label: "webdevops/php-nginx:8.2" + }, + { + value: "webdevops/php-apache:8.1", + label: "webdevops/php-apache:8.1" + }, + { + value: "webdevops/php-nginx:8.1", + label: "webdevops/php-nginx:8.1" + }, + { + value: "webdevops/php-apache:8.0", + label: "webdevops/php-apache:8.0" + }, + { + value: "webdevops/php-nginx:8.0", + label: "webdevops/php-nginx:8.0" + }, + { + value: "webdevops/php-apache:7.4", + label: "webdevops/php-apache:7.4" + }, + { + value: "webdevops/php-nginx:7.4", + label: "webdevops/php-nginx:7.4" + }, + { + value: "webdevops/php-apache:7.3", + label: "webdevops/php-apache:7.3" + }, + { + value: "webdevops/php-nginx:7.3", + label: "webdevops/php-nginx:7.3" + }, + { + value: "webdevops/php-apache:7.2", + label: "webdevops/php-apache:7.2" + }, + { + value: "webdevops/php-nginx:7.2", + label: "webdevops/php-nginx:7.2" + }, + { + value: "webdevops/php-apache:7.1", + label: "webdevops/php-apache:7.1" + }, + { + value: "webdevops/php-nginx:7.1", + label: "webdevops/php-nginx:7.1" + }, + { + value: "webdevops/php-apache:7.0", + label: "webdevops/php-apache:7.0" + }, + { + value: "webdevops/php-nginx:7.0", + label: "webdevops/php-nginx:7.0" + }, + { + value: "webdevops/php-apache:5.6", + label: "webdevops/php-apache:5.6" + }, + { + value: "webdevops/php-nginx:5.6", + label: "webdevops/php-nginx:5.6" + }, + { + value: "webdevops/php-apache:8.2-alpine", + label: "webdevops/php-apache:8.2-alpine" + }, + { + value: "webdevops/php-nginx:8.2-alpine", + label: "webdevops/php-nginx:8.2-alpine" + }, + { + value: "webdevops/php-apache:8.1-alpine", + label: "webdevops/php-apache:8.1-alpine" + }, + { + value: "webdevops/php-nginx:8.1-alpine", + label: "webdevops/php-nginx:8.1-alpine" + }, + { + value: "webdevops/php-apache:8.0-alpine", + label: "webdevops/php-apache:8.0-alpine" + }, + { + value: "webdevops/php-nginx:8.0-alpine", + label: "webdevops/php-nginx:8.0-alpine" + }, + { + value: "webdevops/php-apache:7.4-alpine", + label: "webdevops/php-apache:7.4-alpine" + }, + { + value: "webdevops/php-nginx:7.4-alpine", + label: "webdevops/php-nginx:7.4-alpine" + }, + { + value: "webdevops/php-apache:7.3-alpine", + label: "webdevops/php-apache:7.3-alpine" + }, + { + value: "webdevops/php-nginx:7.3-alpine", + label: "webdevops/php-nginx:7.3-alpine" + }, + { + value: "webdevops/php-apache:7.2-alpine", + label: "webdevops/php-apache:7.2-alpine" + }, + { + value: "webdevops/php-nginx:7.2-alpine", + label: "webdevops/php-nginx:7.2-alpine" + }, + { + value: "webdevops/php-apache:7.1-alpine", + label: "webdevops/php-apache:7.1-alpine" + }, + { + value: "php:8.1-fpm", + label: "php:8.1-fpm" + }, + { + value: "php:8.0-fpm", + label: "php:8.0-fpm" + }, + { + value: "php:8.1-fpm-alpine", + label: "php:8.1-fpm-alpine" + }, + { + value: "php:8.0-fpm-alpine", + label: "php:8.0-fpm-alpine" + } + ]; + const pythonVersions = [ + { + value: "python:3.10-alpine", + label: "python:3.10-alpine" + }, + { + value: "python:3.10-buster", + label: "python:3.10-buster" + }, + { + value: "python:3.10-bullseye", + label: "python:3.10-bullseye" + }, + { + value: "python:3.10-slim-bullseye", + label: "python:3.10-slim-bullseye" + }, + { + value: "python:3.9-alpine", + label: "python:3.9-alpine" + }, + { + value: "python:3.9-buster", + label: "python:3.9-buster" + }, + { + value: "python:3.9-bullseye", + label: "python:3.9-bullseye" + }, + { + value: "python:3.9-slim-bullseye", + label: "python:3.9-slim-bullseye" + }, + { + value: "python:3.8-alpine", + label: "python:3.8-alpine" + }, + { + value: "python:3.8-buster", + label: "python:3.8-buster" + }, + { + value: "python:3.8-bullseye", + label: "python:3.8-bullseye" + }, + { + value: "python:3.8-slim-bullseye", + label: "python:3.8-slim-bullseye" + }, + { + value: "python:3.7-alpine", + label: "python:3.7-alpine" + }, + { + value: "python:3.7-buster", + label: "python:3.7-buster" + }, + { + value: "python:3.7-bullseye", + label: "python:3.7-bullseye" + }, + { + value: "python:3.7-slim-bullseye", + label: "python:3.7-slim-bullseye" + } + ]; + const herokuVersions = [ + { + value: "heroku/builder:22", + label: "heroku/builder:22" + }, + { + value: "heroku/buildpacks:20", + label: "heroku/buildpacks:20" + }, + { + value: "heroku/builder-classic:22", + label: "heroku/builder-classic:22" + } + ]; + let payload = { + baseImage: null, + baseBuildImage: null, + baseImages: [], + baseBuildImages: [] + }; + if (nodeBased.includes(buildPack)) { + if (deploymentType === "static") { + payload.baseImage = (0, import_common.isARM)(process.arch) ? "nginx:alpine" : "webdevops/nginx:alpine"; + payload.baseImages = (0, import_common.isARM)(process.arch) ? staticVersions.filter((version) => !version.value.includes("webdevops")) : staticVersions; + payload.baseBuildImage = "node:lts"; + payload.baseBuildImages = nodeVersions; + } else { + payload.baseImage = "node:lts"; + payload.baseImages = nodeVersions; + payload.baseBuildImage = "node:lts"; + payload.baseBuildImages = nodeVersions; + } + } + if (staticApps.includes(buildPack)) { + payload.baseImage = (0, import_common.isARM)(process.arch) ? "nginx:alpine" : "webdevops/nginx:alpine"; + payload.baseImages = (0, import_common.isARM)(process.arch) ? staticVersions.filter((version) => !version.value.includes("webdevops")) : staticVersions; + payload.baseBuildImage = "node:lts"; + payload.baseBuildImages = nodeVersions; + } + if (buildPack === "python") { + payload.baseImage = "python:3.10-alpine"; + payload.baseImages = pythonVersions; + } + if (buildPack === "rust") { + payload.baseImage = "rust:latest"; + payload.baseBuildImage = "rust:latest"; + payload.baseImages = rustVersions; + payload.baseBuildImages = rustVersions; + } + if (buildPack === "deno") { + payload.baseImage = "denoland/deno:latest"; + } + if (buildPack === "php") { + payload.baseImage = (0, import_common.isARM)(process.arch) ? "php:8.1-fpm-alpine" : "webdevops/php-apache:8.2-alpine"; + payload.baseImages = (0, import_common.isARM)(process.arch) ? phpVersions.filter((version) => !version.value.includes("webdevops")) : phpVersions; + } + if (buildPack === "laravel") { + payload.baseImage = (0, import_common.isARM)(process.arch) ? "php:8.1-fpm-alpine" : "webdevops/php-apache:8.2-alpine"; + payload.baseImages = (0, import_common.isARM)(process.arch) ? phpVersions.filter((version) => !version.value.includes("webdevops")) : phpVersions; + payload.baseBuildImage = "node:18"; + payload.baseBuildImages = nodeVersions; + } + if (buildPack === "heroku") { + payload.baseImage = "heroku/buildpacks:20"; + payload.baseImages = herokuVersions; + } + return payload; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + deployApplication, + generateConfigHash, + getApplicationFromDB, + setDefaultBaseImage +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/auth.js b/apps/trpc-experimental/server/build/trpc/routers/auth.js new file mode 100644 index 000000000..5f41172d4 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/auth.js @@ -0,0 +1,201 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var auth_exports = {}; +__export(auth_exports, { + authRouter: () => authRouter +}); +module.exports = __toCommonJS(auth_exports); +var import_zod = require("zod"); +var import_trpc = require("../trpc"); +var import_server = require("@trpc/server"); +var import_common = require("../../lib/common"); +var import_env = require("../../env"); +var import_jsonwebtoken = __toESM(require("jsonwebtoken")); +var import_prisma = require("../../prisma"); +var import_cuid = __toESM(require("cuid")); +const authRouter = (0, import_trpc.router)({ + register: import_trpc.publicProcedure.input( + import_zod.z.object({ + email: import_zod.z.string(), + password: import_zod.z.string() + }) + ).mutation(async ({ input }) => { + const { email, password } = input; + const userFound = await import_prisma.prisma.user.findUnique({ + where: { email }, + include: { teams: true, permission: true } + }); + if (userFound) { + throw new import_server.TRPCError({ + code: "BAD_REQUEST", + message: "User already exists." + }); + } + const settings = await (0, import_common.listSettings)(); + if (!settings?.isRegistrationEnabled) { + throw new import_server.TRPCError({ + code: "FORBIDDEN", + message: "Registration is disabled." + }); + } + const usersCount = await import_prisma.prisma.user.count(); + const uid = usersCount === 0 ? "0" : (0, import_cuid.default)(); + const permission = "owner"; + const isAdmin = true; + const hashedPassword = await (0, import_common.hashPassword)(password); + if (usersCount === 0) { + await import_prisma.prisma.user.create({ + data: { + id: uid, + email, + password: hashedPassword, + type: "email", + teams: { + create: { + id: uid, + name: (0, import_common.uniqueName)(), + destinationDocker: { connect: { network: "coolify" } } + } + }, + permission: { create: { teamId: uid, permission } } + }, + include: { teams: true } + }); + await import_prisma.prisma.setting.update({ + where: { id: "0" }, + data: { isRegistrationEnabled: false } + }); + } else { + await import_prisma.prisma.user.create({ + data: { + id: uid, + email, + password: hashedPassword, + type: "email", + teams: { + create: { + id: uid, + name: (0, import_common.uniqueName)() + } + }, + permission: { create: { teamId: uid, permission } } + }, + include: { teams: true } + }); + } + const payload = { + userId: uid, + teamId: uid, + permission, + isAdmin + }; + return { + ...payload, + token: import_jsonwebtoken.default.sign(payload, import_env.env.COOLIFY_SECRET_KEY) + }; + }), + login: import_trpc.publicProcedure.input( + import_zod.z.object({ + email: import_zod.z.string(), + password: import_zod.z.string() + }) + ).mutation(async ({ input }) => { + const { email, password } = input; + const userFound = await import_prisma.prisma.user.findUnique({ + where: { email }, + include: { teams: true, permission: true } + }); + if (!userFound) { + throw new import_server.TRPCError({ + code: "BAD_REQUEST", + message: "User already exists." + }); + } + if (userFound.type === "email") { + if (userFound.password === "RESETME") { + const hashedPassword = await (0, import_common.hashPassword)(password); + if (userFound.updatedAt < new Date(Date.now() - 1e3 * 60 * 10)) { + if (userFound.id === "0") { + await import_prisma.prisma.user.update({ + where: { email: userFound.email }, + data: { password: "RESETME" } + }); + } else { + await import_prisma.prisma.user.update({ + where: { email: userFound.email }, + data: { password: "RESETTIMEOUT" } + }); + } + } else { + await import_prisma.prisma.user.update({ + where: { email: userFound.email }, + data: { password: hashedPassword } + }); + const payload2 = { + userId: userFound.id, + teamId: userFound.id, + permission: userFound.permission, + isAdmin: true + }; + return { + ...payload2, + token: import_jsonwebtoken.default.sign(payload2, import_env.env.COOLIFY_SECRET_KEY) + }; + } + } + if (!userFound.password) { + throw new import_server.TRPCError({ + code: "BAD_REQUEST", + message: "Something went wrong. Please try again later." + }); + } + const passwordMatch = (0, import_common.comparePassword)(password, userFound.password); + if (!passwordMatch) { + throw new import_server.TRPCError({ + code: "BAD_REQUEST", + message: "Incorrect password." + }); + } + const payload = { + userId: userFound.id, + teamId: userFound.id, + permission: userFound.permission, + isAdmin: true + }; + return { + ...payload, + token: import_jsonwebtoken.default.sign(payload, import_env.env.COOLIFY_SECRET_KEY) + }; + } + throw new import_server.TRPCError({ + code: "BAD_REQUEST", + message: "Not implemented yet." + }); + }) +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + authRouter +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/dashboard.js b/apps/trpc-experimental/server/build/trpc/routers/dashboard.js new file mode 100644 index 000000000..cd1519b5d --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/dashboard.js @@ -0,0 +1,87 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var dashboard_exports = {}; +__export(dashboard_exports, { + dashboardRouter: () => dashboardRouter +}); +module.exports = __toCommonJS(dashboard_exports); +var import_trpc = require("../trpc"); +var import_common = require("../../lib/common"); +var import_prisma = require("../../prisma"); +const dashboardRouter = (0, import_trpc.router)({ + resources: import_trpc.privateProcedure.query(async ({ ctx }) => { + const id = ctx.user?.teamId === "0" ? void 0 : ctx.user?.teamId; + let applications = await import_prisma.prisma.application.findMany({ + where: { teams: { some: { id } } }, + include: { settings: true, destinationDocker: true, teams: true } + }); + const databases = await import_prisma.prisma.database.findMany({ + where: { teams: { some: { id } } }, + include: { settings: true, destinationDocker: true, teams: true } + }); + const services = await import_prisma.prisma.service.findMany({ + where: { teams: { some: { id } } }, + include: { destinationDocker: true, teams: true } + }); + const gitSources = await import_prisma.prisma.gitSource.findMany({ + where: { + OR: [{ teams: { some: { id } } }, { isSystemWide: true }] + }, + include: { teams: true } + }); + const destinations = await import_prisma.prisma.destinationDocker.findMany({ + where: { teams: { some: { id } } }, + include: { teams: true } + }); + const settings = await (0, import_common.listSettings)(); + let foundUnconfiguredApplication = false; + for (const application of applications) { + if ((!application.buildPack || !application.branch) && !application.simpleDockerfile || !application.destinationDockerId || !application.settings?.isBot && !application?.fqdn && application.buildPack !== "compose") { + foundUnconfiguredApplication = true; + } + } + let foundUnconfiguredService = false; + for (const service of services) { + if (!service.fqdn) { + foundUnconfiguredService = true; + } + } + let foundUnconfiguredDatabase = false; + for (const database of databases) { + if (!database.version) { + foundUnconfiguredDatabase = true; + } + } + return { + foundUnconfiguredApplication, + foundUnconfiguredDatabase, + foundUnconfiguredService, + applications, + databases, + services, + gitSources, + destinations, + settings + }; + }) +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + dashboardRouter +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/databases/index.js b/apps/trpc-experimental/server/build/trpc/routers/databases/index.js new file mode 100644 index 000000000..70c2fc4d2 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/databases/index.js @@ -0,0 +1,384 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var databases_exports = {}; +__export(databases_exports, { + databasesRouter: () => databasesRouter +}); +module.exports = __toCommonJS(databases_exports); +var import_zod = require("zod"); +var import_promises = __toESM(require("fs/promises")); +var import_trpc = require("../../trpc"); +var import_common = require("../../../lib/common"); +var import_prisma = require("../../../prisma"); +var import_executeCommand = require("../../../lib/executeCommand"); +var import_docker = require("../../../lib/docker"); +var import_lib = require("./lib"); +var import_js_yaml = __toESM(require("js-yaml")); +var import_lib2 = require("../services/lib"); +const databasesRouter = (0, import_trpc.router)({ + usage: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).query(async ({ ctx, input }) => { + const teamId = ctx.user?.teamId; + const { id } = input; + let usage = {}; + const database = await import_prisma.prisma.database.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { destinationDocker: true, settings: true } + }); + if (database.dbUserPassword) + database.dbUserPassword = (0, import_common.decrypt)(database.dbUserPassword); + if (database.rootUserPassword) + database.rootUserPassword = (0, import_common.decrypt)(database.rootUserPassword); + if (database.destinationDockerId) { + [usage] = await Promise.all([(0, import_common.getContainerUsage)(database.destinationDocker.id, id)]); + } + return { + success: true, + data: { + usage + } + }; + }), + save: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).mutation(async ({ ctx, input }) => { + const teamId = ctx.user?.teamId; + const { + id, + name, + defaultDatabase, + dbUser, + dbUserPassword, + rootUser, + rootUserPassword, + version, + isRunning + } = input; + const database = await import_prisma.prisma.database.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { destinationDocker: true, settings: true } + }); + if (database.dbUserPassword) + database.dbUserPassword = (0, import_common.decrypt)(database.dbUserPassword); + if (database.rootUserPassword) + database.rootUserPassword = (0, import_common.decrypt)(database.rootUserPassword); + if (isRunning) { + if (database.dbUserPassword !== dbUserPassword) { + await (0, import_lib.updatePasswordInDb)(database, dbUser, dbUserPassword, false); + } else if (database.rootUserPassword !== rootUserPassword) { + await (0, import_lib.updatePasswordInDb)(database, rootUser, rootUserPassword, true); + } + } + const encryptedDbUserPassword = dbUserPassword && (0, import_common.encrypt)(dbUserPassword); + const encryptedRootUserPassword = rootUserPassword && (0, import_common.encrypt)(rootUserPassword); + await import_prisma.prisma.database.update({ + where: { id }, + data: { + name, + defaultDatabase, + dbUser, + dbUserPassword: encryptedDbUserPassword, + rootUser, + rootUserPassword: encryptedRootUserPassword, + version + } + }); + }), + saveSettings: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + isPublic: import_zod.z.boolean(), + appendOnly: import_zod.z.boolean().default(true) + }) + ).mutation(async ({ ctx, input }) => { + const teamId = ctx.user?.teamId; + const { id, isPublic, appendOnly = true } = input; + let publicPort = null; + const { + destinationDocker: { remoteEngine, engine, remoteIpAddress } + } = await import_prisma.prisma.database.findUnique({ where: { id }, include: { destinationDocker: true } }); + if (isPublic) { + publicPort = await (0, import_lib2.getFreePublicPort)({ id, remoteEngine, engine, remoteIpAddress }); + } + await import_prisma.prisma.database.update({ + where: { id }, + data: { + settings: { + upsert: { update: { isPublic, appendOnly }, create: { isPublic, appendOnly } } + } + } + }); + const database = await import_prisma.prisma.database.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { destinationDocker: true, settings: true } + }); + const { arch } = await (0, import_common.listSettings)(); + if (database.dbUserPassword) + database.dbUserPassword = (0, import_common.decrypt)(database.dbUserPassword); + if (database.rootUserPassword) + database.rootUserPassword = (0, import_common.decrypt)(database.rootUserPassword); + const { destinationDockerId, destinationDocker, publicPort: oldPublicPort } = database; + const { privatePort } = (0, import_lib.generateDatabaseConfiguration)(database, arch); + if (destinationDockerId) { + if (isPublic) { + await import_prisma.prisma.database.update({ where: { id }, data: { publicPort } }); + await (0, import_common.startTraefikTCPProxy)(destinationDocker, id, publicPort, privatePort); + } else { + await import_prisma.prisma.database.update({ where: { id }, data: { publicPort: null } }); + await (0, import_docker.stopTcpHttpProxy)(id, destinationDocker, oldPublicPort); + } + } + return { publicPort }; + }), + saveSecret: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + name: import_zod.z.string(), + value: import_zod.z.string(), + isNew: import_zod.z.boolean().default(true) + }) + ).mutation(async ({ ctx, input }) => { + let { id, name, value, isNew } = input; + if (isNew) { + const found = await import_prisma.prisma.databaseSecret.findFirst({ where: { name, databaseId: id } }); + if (found) { + throw `Secret ${name} already exists.`; + } else { + value = (0, import_common.encrypt)(value.trim()); + await import_prisma.prisma.databaseSecret.create({ + data: { name, value, database: { connect: { id } } } + }); + } + } else { + value = (0, import_common.encrypt)(value.trim()); + const found = await import_prisma.prisma.databaseSecret.findFirst({ where: { databaseId: id, name } }); + if (found) { + await import_prisma.prisma.databaseSecret.updateMany({ + where: { databaseId: id, name }, + data: { value } + }); + } else { + await import_prisma.prisma.databaseSecret.create({ + data: { name, value, database: { connect: { id } } } + }); + } + } + }), + start: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).mutation(async ({ ctx, input }) => { + const { id } = input; + const teamId = ctx.user?.teamId; + const database = await import_prisma.prisma.database.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { destinationDocker: true, settings: true, databaseSecret: true } + }); + const { arch } = await (0, import_common.listSettings)(); + if (database.dbUserPassword) + database.dbUserPassword = (0, import_common.decrypt)(database.dbUserPassword); + if (database.rootUserPassword) + database.rootUserPassword = (0, import_common.decrypt)(database.rootUserPassword); + const { + type, + destinationDockerId, + destinationDocker, + publicPort, + settings: { isPublic }, + databaseSecret + } = database; + const { privatePort, command, environmentVariables, image, volume, ulimits } = (0, import_lib.generateDatabaseConfiguration)(database, arch); + const network = destinationDockerId && destinationDocker.network; + const volumeName = volume.split(":")[0]; + const labels = await (0, import_lib.makeLabelForStandaloneDatabase)({ id, image, volume }); + const { workdir } = await (0, import_common.createDirectories)({ repository: type, buildId: id }); + if (databaseSecret.length > 0) { + databaseSecret.forEach((secret) => { + environmentVariables[secret.name] = (0, import_common.decrypt)(secret.value); + }); + } + const composeFile = { + version: "3.8", + services: { + [id]: { + container_name: id, + image, + command, + environment: environmentVariables, + volumes: [volume], + ulimits, + labels, + ...(0, import_docker.defaultComposeConfiguration)(network) + } + }, + networks: { + [network]: { + external: true + } + }, + volumes: { + [volumeName]: { + name: volumeName + } + } + }; + const composeFileDestination = `${workdir}/docker-compose.yaml`; + await import_promises.default.writeFile(composeFileDestination, import_js_yaml.default.dump(composeFile)); + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDocker.id, + command: `docker compose -f ${composeFileDestination} up -d` + }); + if (isPublic) + await (0, import_common.startTraefikTCPProxy)(destinationDocker, id, publicPort, privatePort); + }), + stop: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).mutation(async ({ ctx, input }) => { + const { id } = input; + const teamId = ctx.user?.teamId; + const database = await import_prisma.prisma.database.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { destinationDocker: true, settings: true } + }); + if (database.dbUserPassword) + database.dbUserPassword = (0, import_common.decrypt)(database.dbUserPassword); + if (database.rootUserPassword) + database.rootUserPassword = (0, import_common.decrypt)(database.rootUserPassword); + const everStarted = await (0, import_docker.stopDatabaseContainer)(database); + if (everStarted) + await (0, import_docker.stopTcpHttpProxy)(id, database.destinationDocker, database.publicPort); + await import_prisma.prisma.database.update({ + where: { id }, + data: { + settings: { upsert: { update: { isPublic: false }, create: { isPublic: false } } } + } + }); + await import_prisma.prisma.database.update({ where: { id }, data: { publicPort: null } }); + }), + getDatabaseById: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).query(async ({ ctx, input }) => { + const { id } = input; + const teamId = ctx.user?.teamId; + const database = await import_prisma.prisma.database.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { destinationDocker: true, settings: true } + }); + if (!database) { + throw { status: 404, message: "Database not found." }; + } + const settings = await (0, import_common.listSettings)(); + if (database.dbUserPassword) + database.dbUserPassword = (0, import_common.decrypt)(database.dbUserPassword); + if (database.rootUserPassword) + database.rootUserPassword = (0, import_common.decrypt)(database.rootUserPassword); + const configuration = (0, import_lib.generateDatabaseConfiguration)(database, settings.arch); + return { + success: true, + data: { + privatePort: configuration?.privatePort, + database, + versions: await (0, import_lib.getDatabaseVersions)(database.type, settings.arch), + settings + } + }; + }), + status: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).query(async ({ ctx, input }) => { + const id = input.id; + const teamId = ctx.user?.teamId; + let isRunning = false; + const database = await import_prisma.prisma.database.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { destinationDocker: true, settings: true } + }); + if (database) { + const { destinationDockerId, destinationDocker } = database; + if (destinationDockerId) { + try { + const { stdout } = await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDocker.id, + command: `docker inspect --format '{{json .State}}' ${id}` + }); + if (JSON.parse(stdout).Running) { + isRunning = true; + } + } catch (error) { + } + } + } + return { + success: true, + data: { + isRunning + } + }; + }), + cleanup: import_trpc.privateProcedure.query(async ({ ctx }) => { + const teamId = ctx.user?.teamId; + let databases = await import_prisma.prisma.database.findMany({ + where: { teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { settings: true, destinationDocker: true, teams: true } + }); + for (const database of databases) { + if (!database?.version) { + const { id } = database; + if (database.destinationDockerId) { + const everStarted = await (0, import_docker.stopDatabaseContainer)(database); + if (everStarted) + await (0, import_docker.stopTcpHttpProxy)(id, database.destinationDocker, database.publicPort); + } + await import_prisma.prisma.databaseSettings.deleteMany({ where: { databaseId: id } }); + await import_prisma.prisma.databaseSecret.deleteMany({ where: { databaseId: id } }); + await import_prisma.prisma.database.delete({ where: { id } }); + } + } + return {}; + }), + delete: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string(), force: import_zod.z.boolean().default(false) })).mutation(async ({ ctx, input }) => { + const { id, force } = input; + const teamId = ctx.user?.teamId; + const database = await import_prisma.prisma.database.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { destinationDocker: true, settings: true } + }); + if (!force) { + if (database.dbUserPassword) + database.dbUserPassword = (0, import_common.decrypt)(database.dbUserPassword); + if (database.rootUserPassword) + database.rootUserPassword = (0, import_common.decrypt)(database.rootUserPassword); + if (database.destinationDockerId) { + const everStarted = await (0, import_docker.stopDatabaseContainer)(database); + if (everStarted) + await (0, import_docker.stopTcpHttpProxy)(id, database.destinationDocker, database.publicPort); + } + } + await import_prisma.prisma.databaseSettings.deleteMany({ where: { databaseId: id } }); + await import_prisma.prisma.databaseSecret.deleteMany({ where: { databaseId: id } }); + await import_prisma.prisma.database.delete({ where: { id } }); + return {}; + }) +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + databasesRouter +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/databases/lib.js b/apps/trpc-experimental/server/build/trpc/routers/databases/lib.js new file mode 100644 index 000000000..2cb21ef78 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/databases/lib.js @@ -0,0 +1,316 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var lib_exports = {}; +__export(lib_exports, { + generateDatabaseConfiguration: () => generateDatabaseConfiguration, + getDatabaseImage: () => getDatabaseImage, + getDatabaseVersions: () => getDatabaseVersions, + makeLabelForStandaloneDatabase: () => makeLabelForStandaloneDatabase, + supportedDatabaseTypesAndVersions: () => supportedDatabaseTypesAndVersions, + updatePasswordInDb: () => updatePasswordInDb +}); +module.exports = __toCommonJS(lib_exports); +var import_common = require("../../../lib/common"); +var import_executeCommand = require("../../../lib/executeCommand"); +var import_prisma = require("../../../prisma"); +const supportedDatabaseTypesAndVersions = [ + { + name: "mongodb", + fancyName: "MongoDB", + baseImage: "bitnami/mongodb", + 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: "mariadb", + fancyName: "MariaDB", + baseImage: "bitnami/mariadb", + 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", + 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", + 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", + baseImageARM: "couchdb", + versions: ["3.2.2", "3.1.2", "2.3.1"], + versionsARM: ["3.2.2", "3.1.2", "2.3.1"] + }, + { + name: "edgedb", + fancyName: "EdgeDB", + baseImage: "edgedb/edgedb", + versions: ["latest", "2.1", "2.0", "1.4"] + } +]; +function getDatabaseImage(type, arch) { + const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type); + if (found) { + if ((0, import_common.isARM)(arch)) { + return found.baseImageARM || found.baseImage; + } + return found.baseImage; + } + return ""; +} +function generateDatabaseConfiguration(database, arch) { + const { id, dbUser, dbUserPassword, rootUser, rootUserPassword, defaultDatabase, version: version2, type } = database; + const baseImage = getDatabaseImage(type, arch); + if (type === "mysql") { + const configuration = { + privatePort: 3306, + environmentVariables: { + MYSQL_USER: dbUser, + MYSQL_PASSWORD: dbUserPassword, + MYSQL_ROOT_PASSWORD: rootUserPassword, + MYSQL_ROOT_USER: rootUser, + MYSQL_DATABASE: defaultDatabase + }, + image: `${baseImage}:${version2}`, + volume: `${id}-${type}-data:/bitnami/mysql/data`, + ulimits: {} + }; + if ((0, import_common.isARM)(arch)) { + configuration.volume = `${id}-${type}-data:/var/lib/mysql`; + } + return configuration; + } else if (type === "mariadb") { + const configuration = { + privatePort: 3306, + environmentVariables: { + MARIADB_ROOT_USER: rootUser, + MARIADB_ROOT_PASSWORD: rootUserPassword, + MARIADB_USER: dbUser, + MARIADB_PASSWORD: dbUserPassword, + MARIADB_DATABASE: defaultDatabase + }, + image: `${baseImage}:${version2}`, + volume: `${id}-${type}-data:/bitnami/mariadb`, + ulimits: {} + }; + if ((0, import_common.isARM)(arch)) { + configuration.volume = `${id}-${type}-data:/var/lib/mysql`; + } + return configuration; + } else if (type === "mongodb") { + const configuration = { + privatePort: 27017, + environmentVariables: { + MONGODB_ROOT_USER: rootUser, + MONGODB_ROOT_PASSWORD: rootUserPassword + }, + image: `${baseImage}:${version2}`, + volume: `${id}-${type}-data:/bitnami/mongodb`, + ulimits: {} + }; + if ((0, import_common.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") { + const configuration = { + privatePort: 5432, + environmentVariables: { + POSTGRESQL_POSTGRES_PASSWORD: rootUserPassword, + POSTGRESQL_PASSWORD: dbUserPassword, + POSTGRESQL_USERNAME: dbUser, + POSTGRESQL_DATABASE: defaultDatabase + }, + image: `${baseImage}:${version2}`, + volume: `${id}-${type}-data:/bitnami/postgresql`, + ulimits: {} + }; + if ((0, import_common.isARM)(arch)) { + configuration.volume = `${id}-${type}-data:/var/lib/postgresql`; + configuration.environmentVariables = { + POSTGRES_PASSWORD: dbUserPassword, + POSTGRES_USER: dbUser, + POSTGRES_DB: defaultDatabase + }; + } + return configuration; + } else if (type === "redis") { + const { + settings: { appendOnly } + } = database; + const configuration = { + privatePort: 6379, + command: void 0, + environmentVariables: { + REDIS_PASSWORD: dbUserPassword, + REDIS_AOF_ENABLED: appendOnly ? "yes" : "no" + }, + image: `${baseImage}:${version2}`, + volume: `${id}-${type}-data:/bitnami/redis/data`, + ulimits: {} + }; + if ((0, import_common.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") { + const configuration = { + privatePort: 5984, + environmentVariables: { + COUCHDB_PASSWORD: dbUserPassword, + COUCHDB_USER: dbUser + }, + image: `${baseImage}:${version2}`, + volume: `${id}-${type}-data:/bitnami/couchdb`, + ulimits: {} + }; + if ((0, import_common.isARM)(arch)) { + configuration.volume = `${id}-${type}-data:/opt/couchdb/data`; + } + return configuration; + } else if (type === "edgedb") { + const configuration = { + privatePort: 5656, + environmentVariables: { + EDGEDB_SERVER_PASSWORD: rootUserPassword, + EDGEDB_SERVER_USER: rootUser, + EDGEDB_SERVER_DATABASE: defaultDatabase, + EDGEDB_SERVER_TLS_CERT_MODE: "generate_self_signed" + }, + image: `${baseImage}:${version2}`, + volume: `${id}-${type}-data:/var/lib/edgedb/data`, + ulimits: {} + }; + return configuration; + } + return null; +} +function getDatabaseVersions(type, arch) { + const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type); + if (found) { + if ((0, import_common.isARM)(arch)) { + return found.versionsARM || found.versions; + } + return found.versions; + } + return []; +} +async function updatePasswordInDb(database, user, newPassword, isRoot) { + const { + id, + type, + rootUser, + rootUserPassword, + dbUser, + dbUserPassword, + defaultDatabase, + destinationDockerId, + destinationDocker: { id: dockerId } + } = database; + if (destinationDockerId) { + if (type === "mysql") { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker exec ${id} mysql -u ${rootUser} -p${rootUserPassword} -e "ALTER USER '${user}'@'%' IDENTIFIED WITH caching_sha2_password BY '${newPassword}';"` + }); + } else if (type === "mariadb") { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker exec ${id} mysql -u ${rootUser} -p${rootUserPassword} -e "SET PASSWORD FOR '${user}'@'%' = PASSWORD('${newPassword}');"` + }); + } else if (type === "postgresql") { + if (isRoot) { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker exec ${id} psql postgresql://postgres:${rootUserPassword}@${id}:5432/${defaultDatabase} -c "ALTER role postgres WITH PASSWORD '${newPassword}'"` + }); + } else { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker exec ${id} psql postgresql://${dbUser}:${dbUserPassword}@${id}:5432/${defaultDatabase} -c "ALTER role ${user} WITH PASSWORD '${newPassword}'"` + }); + } + } else if (type === "mongodb") { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker exec ${id} mongo 'mongodb://${rootUser}:${rootUserPassword}@${id}:27017/admin?readPreference=primary&ssl=false' --eval "db.changeUserPassword('${user}','${newPassword}')"` + }); + } else if (type === "redis") { + await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker exec ${id} redis-cli -u redis://${dbUserPassword}@${id}:6379 --raw CONFIG SET requirepass ${newPassword}` + }); + } + } +} +async function makeLabelForStandaloneDatabase({ id, image, volume }) { + const database = await import_prisma.prisma.database.findFirst({ where: { id } }); + delete database.destinationDockerId; + delete database.createdAt; + delete database.updatedAt; + return [ + "coolify.managed=true", + `coolify.version=${import_common.version}`, + `coolify.type=standalone-database`, + `coolify.name=${database.name}`, + `coolify.configuration=${(0, import_common.base64Encode)( + JSON.stringify({ + version: import_common.version, + image, + volume, + ...database + }) + )}` + ]; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + generateDatabaseConfiguration, + getDatabaseImage, + getDatabaseVersions, + makeLabelForStandaloneDatabase, + supportedDatabaseTypesAndVersions, + updatePasswordInDb +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/destinations/index.js b/apps/trpc-experimental/server/build/trpc/routers/destinations/index.js new file mode 100644 index 000000000..787431e46 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/destinations/index.js @@ -0,0 +1,220 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var destinations_exports = {}; +__export(destinations_exports, { + destinationsRouter: () => destinationsRouter +}); +module.exports = __toCommonJS(destinations_exports); +var import_zod = require("zod"); +var import_trpc = require("../../trpc"); +var import_common = require("../../../lib/common"); +var import_prisma = require("../../../prisma"); +var import_executeCommand = require("../../../lib/executeCommand"); +var import_docker = require("../../../lib/docker"); +const destinationsRouter = (0, import_trpc.router)({ + restartProxy: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).mutation(async ({ input, ctx }) => { + const { id } = input; + await (0, import_common.stopTraefikProxy)(id); + await (0, import_common.startTraefikProxy)(id); + await import_prisma.prisma.destinationDocker.update({ + where: { id }, + data: { isCoolifyProxyUsed: true } + }); + }), + startProxy: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).mutation(async ({ input, ctx }) => { + const { id } = input; + await (0, import_common.startTraefikProxy)(id); + }), + stopProxy: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).mutation(async ({ input, ctx }) => { + const { id } = input; + await (0, import_common.stopTraefikProxy)(id); + }), + saveSettings: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + engine: import_zod.z.string(), + isCoolifyProxyUsed: import_zod.z.boolean() + }) + ).mutation(async ({ input, ctx }) => { + const { id, engine, isCoolifyProxyUsed } = input; + await import_prisma.prisma.destinationDocker.updateMany({ + where: { engine }, + data: { isCoolifyProxyUsed } + }); + }), + status: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).query(async ({ input, ctx }) => { + const { id } = input; + const destination = await import_prisma.prisma.destinationDocker.findUnique({ where: { id } }); + const { found: isRunning } = await (0, import_docker.checkContainer)({ + dockerId: destination.id, + container: "coolify-proxy", + remove: true + }); + return { + isRunning + }; + }), + save: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + name: import_zod.z.string(), + htmlUrl: import_zod.z.string(), + apiUrl: import_zod.z.string(), + customPort: import_zod.z.number(), + customUser: import_zod.z.string(), + isSystemWide: import_zod.z.boolean().default(false) + }) + ).mutation(async ({ input, ctx }) => { + const { teamId } = ctx.user; + let { + id, + name, + network, + engine, + isCoolifyProxyUsed, + remoteIpAddress, + remoteUser, + remotePort + } = input; + if (id === "new") { + if (engine) { + const { stdout } = await await (0, import_executeCommand.executeCommand)({ + command: `docker network ls --filter 'name=^${network}$' --format '{{json .}}'` + }); + if (stdout === "") { + await await (0, import_executeCommand.executeCommand)({ + command: `docker network create --attachable ${network}` + }); + } + await import_prisma.prisma.destinationDocker.create({ + data: { name, teams: { connect: { id: teamId } }, engine, network, isCoolifyProxyUsed } + }); + const destinations = await import_prisma.prisma.destinationDocker.findMany({ where: { engine } }); + const destination = destinations.find((destination2) => destination2.network === network); + if (destinations.length > 0) { + const proxyConfigured = destinations.find( + (destination2) => destination2.network !== network && destination2.isCoolifyProxyUsed === true + ); + if (proxyConfigured) { + isCoolifyProxyUsed = !!proxyConfigured.isCoolifyProxyUsed; + } + await import_prisma.prisma.destinationDocker.updateMany({ + where: { engine }, + data: { isCoolifyProxyUsed } + }); + } + if (isCoolifyProxyUsed) { + await (0, import_common.startTraefikProxy)(destination.id); + } + return { id: destination.id }; + } else { + const destination = await import_prisma.prisma.destinationDocker.create({ + data: { + name, + teams: { connect: { id: teamId } }, + engine, + network, + isCoolifyProxyUsed, + remoteEngine: true, + remoteIpAddress, + remoteUser, + remotePort: Number(remotePort) + } + }); + return { id: destination.id }; + } + } else { + await import_prisma.prisma.destinationDocker.update({ where: { id }, data: { name, engine, network } }); + return {}; + } + }), + check: import_trpc.privateProcedure.input( + import_zod.z.object({ + network: import_zod.z.string() + }) + ).query(async ({ input, ctx }) => { + const { network } = input; + const found = await import_prisma.prisma.destinationDocker.findFirst({ where: { network } }); + if (found) { + throw { + message: `Network already exists: ${network}` + }; + } + }), + delete: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).mutation(async ({ input, ctx }) => { + const { id } = input; + const { network, remoteVerified, engine, isCoolifyProxyUsed } = await import_prisma.prisma.destinationDocker.findUnique({ where: { id } }); + if (isCoolifyProxyUsed) { + if (engine || remoteVerified) { + const { stdout: found } = await (0, import_executeCommand.executeCommand)({ + dockerId: id, + command: `docker ps -a --filter network=${network} --filter name=coolify-proxy --format '{{.}}'` + }); + if (found) { + await (0, import_executeCommand.executeCommand)({ + dockerId: id, + command: `docker network disconnect ${network} coolify-proxy` + }); + await (0, import_executeCommand.executeCommand)({ dockerId: id, command: `docker network rm ${network}` }); + } + } + } + await import_prisma.prisma.destinationDocker.delete({ where: { id } }); + }), + getDestinationById: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).query(async ({ input, ctx }) => { + const { id } = input; + const { teamId } = ctx.user; + const destination = await import_prisma.prisma.destinationDocker.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { sshKey: true, application: true, service: true, database: true } + }); + if (!destination && id !== "new") { + throw { status: 404, message: `Destination not found.` }; + } + const settings = await (0, import_common.listSettings)(); + return { + destination, + settings + }; + }) +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + destinationsRouter +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/index.js b/apps/trpc-experimental/server/build/trpc/routers/index.js new file mode 100644 index 000000000..a2eb93e72 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/index.js @@ -0,0 +1,25 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var routers_exports = {}; +module.exports = __toCommonJS(routers_exports); +__reExport(routers_exports, require("./auth"), module.exports); +__reExport(routers_exports, require("./dashboard"), module.exports); +__reExport(routers_exports, require("./settings"), module.exports); +__reExport(routers_exports, require("./applications"), module.exports); +__reExport(routers_exports, require("./services"), module.exports); +__reExport(routers_exports, require("./databases"), module.exports); +__reExport(routers_exports, require("./sources"), module.exports); +__reExport(routers_exports, require("./destinations"), module.exports); diff --git a/apps/trpc-experimental/server/build/trpc/routers/services/index.js b/apps/trpc-experimental/server/build/trpc/routers/services/index.js new file mode 100644 index 000000000..369203aaa --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/services/index.js @@ -0,0 +1,846 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var services_exports = {}; +__export(services_exports, { + getServiceFromDB: () => getServiceFromDB, + servicesRouter: () => servicesRouter +}); +module.exports = __toCommonJS(services_exports); +var import_zod = require("zod"); +var import_js_yaml = __toESM(require("js-yaml")); +var import_promises = __toESM(require("fs/promises")); +var import_path = __toESM(require("path")); +var import_trpc = require("../../trpc"); +var import_common = require("../../../lib/common"); +var import_prisma = require("../../../prisma"); +var import_executeCommand = require("../../../lib/executeCommand"); +var import_lib = require("./lib"); +var import_docker = require("../../../lib/docker"); +var import_cuid = __toESM(require("cuid")); +var import_dayjs = require("../../../lib/dayjs"); +const servicesRouter = (0, import_trpc.router)({ + getLogs: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + containerId: import_zod.z.string(), + since: import_zod.z.number().optional().default(0) + }) + ).query(async ({ input, ctx }) => { + let { id, containerId, since } = input; + if (since !== 0) { + since = (0, import_dayjs.day)(since).unix(); + } + const { + destinationDockerId, + destinationDocker: { id: dockerId } + } = await import_prisma.prisma.service.findUnique({ + where: { id }, + include: { destinationDocker: true } + }); + if (destinationDockerId) { + try { + const { default: ansi } = await import("strip-ansi"); + const { stdout, stderr } = await (0, import_executeCommand.executeCommand)({ + dockerId, + command: `docker logs --since ${since} --tail 5000 --timestamps ${containerId}` + }); + const stripLogsStdout = stdout.toString().split("\n").map((l) => ansi(l)).filter((a) => a); + const stripLogsStderr = stderr.toString().split("\n").map((l) => ansi(l)).filter((a) => a); + const logs = stripLogsStderr.concat(stripLogsStdout); + const sortedLogs = logs.sort( + (a, b) => (0, import_dayjs.day)(a.split(" ")[0]).isAfter((0, import_dayjs.day)(b.split(" ")[0])) ? 1 : -1 + ); + return { + data: { + logs: sortedLogs + } + }; + } catch (error) { + const { statusCode, stderr } = error; + if (stderr.startsWith("Error: No such container")) { + return { + data: { + logs: [], + noContainer: true + } + }; + } + if (statusCode === 404) { + return { + data: { + logs: [] + } + }; + } + } + } + return { + message: "No logs found." + }; + }), + deleteStorage: import_trpc.privateProcedure.input( + import_zod.z.object({ + storageId: import_zod.z.string() + }) + ).mutation(async ({ input, ctx }) => { + const { storageId } = input; + await import_prisma.prisma.servicePersistentStorage.deleteMany({ where: { id: storageId } }); + }), + saveStorage: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + path: import_zod.z.string(), + isNewStorage: import_zod.z.boolean(), + storageId: import_zod.z.string().optional().nullable(), + containerId: import_zod.z.string().optional() + }) + ).mutation(async ({ input, ctx }) => { + const { id, path: path2, isNewStorage, storageId, containerId } = input; + if (isNewStorage) { + const volumeName = `${id}-custom${path2.replace(/\//gi, "-")}`; + const found = await import_prisma.prisma.servicePersistentStorage.findFirst({ + where: { path: path2, containerId } + }); + if (found) { + throw { + status: 500, + message: "Persistent storage already exists for this container and path." + }; + } + await import_prisma.prisma.servicePersistentStorage.create({ + data: { path: path2, volumeName, containerId, service: { connect: { id } } } + }); + } else { + await import_prisma.prisma.servicePersistentStorage.update({ + where: { id: storageId }, + data: { path: path2, containerId } + }); + } + }), + getStorages: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).query(async ({ input, ctx }) => { + const { id } = input; + const persistentStorages = await import_prisma.prisma.servicePersistentStorage.findMany({ + where: { serviceId: id } + }); + return { + success: true, + data: { + persistentStorages + } + }; + }), + deleteSecret: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string(), name: import_zod.z.string() })).mutation(async ({ input, ctx }) => { + const { id, name } = input; + await import_prisma.prisma.serviceSecret.deleteMany({ where: { serviceId: id, name } }); + }), + saveService: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + name: import_zod.z.string(), + fqdn: import_zod.z.string().optional(), + exposePort: import_zod.z.string().optional(), + type: import_zod.z.string(), + serviceSetting: import_zod.z.any(), + version: import_zod.z.string().optional() + }) + ).mutation(async ({ input, ctx }) => { + const teamId = ctx.user?.teamId; + let { id, name, fqdn, exposePort, type, serviceSetting, version } = input; + if (fqdn) + fqdn = fqdn.toLowerCase(); + if (exposePort) + exposePort = Number(exposePort); + type = (0, import_common.fixType)(type); + const data = { + fqdn, + name, + exposePort, + version + }; + const templates = await (0, import_common.getTemplates)(); + const service = await import_prisma.prisma.service.findUnique({ where: { id } }); + const foundTemplate = templates.find((t) => (0, import_common.fixType)(t.type) === (0, import_common.fixType)(service.type)); + for (const setting of serviceSetting) { + let { id: settingId, name: name2, value, changed = false, isNew = false, variableName } = setting; + if (value) { + if (changed) { + await import_prisma.prisma.serviceSetting.update({ where: { id: settingId }, data: { value } }); + } + if (isNew) { + if (!variableName) { + variableName = foundTemplate?.variables.find((v) => v.name === name2).id; + } + await import_prisma.prisma.serviceSetting.create({ + data: { name: name2, value, variableName, service: { connect: { id } } } + }); + } + } + } + await import_prisma.prisma.service.update({ + where: { id }, + data + }); + }), + createSecret: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + name: import_zod.z.string(), + value: import_zod.z.string(), + isBuildSecret: import_zod.z.boolean().optional(), + isPRMRSecret: import_zod.z.boolean().optional(), + isNew: import_zod.z.boolean().optional() + }) + ).mutation(async ({ input }) => { + let { id, name, value, isNew } = input; + if (isNew) { + const found = await import_prisma.prisma.serviceSecret.findFirst({ where: { name, serviceId: id } }); + if (found) { + throw `Secret ${name} already exists.`; + } else { + value = (0, import_common.encrypt)(value.trim()); + await import_prisma.prisma.serviceSecret.create({ + data: { name, value, service: { connect: { id } } } + }); + } + } else { + value = (0, import_common.encrypt)(value.trim()); + const found = await import_prisma.prisma.serviceSecret.findFirst({ where: { serviceId: id, name } }); + if (found) { + await import_prisma.prisma.serviceSecret.updateMany({ + where: { serviceId: id, name }, + data: { value } + }); + } else { + await import_prisma.prisma.serviceSecret.create({ + data: { name, value, service: { connect: { id } } } + }); + } + } + }), + getSecrets: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).query(async ({ input, ctx }) => { + const { id } = input; + const teamId = ctx.user?.teamId; + const service = await getServiceFromDB({ id, teamId }); + let secrets = await import_prisma.prisma.serviceSecret.findMany({ + where: { serviceId: id }, + orderBy: { createdAt: "desc" } + }); + const templates = await (0, import_common.getTemplates)(); + if (!templates) + throw new Error("No templates found. Please contact support."); + const foundTemplate = templates.find((t) => (0, import_common.fixType)(t.type) === service.type); + secrets = secrets.map((secret) => { + const foundVariable = foundTemplate?.variables?.find((v) => v.name === secret.name) || null; + if (foundVariable) { + secret.readOnly = foundVariable.readOnly; + } + secret.value = (0, import_common.decrypt)(secret.value); + return secret; + }); + return { + success: true, + data: { + secrets + } + }; + }), + wordpress: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string(), ftpEnabled: import_zod.z.boolean() })).mutation(async ({ input, ctx }) => { + const { id } = input; + const teamId = ctx.user?.teamId; + const { + service: { + destinationDocker: { engine, remoteEngine, remoteIpAddress } + } + } = await import_prisma.prisma.wordpress.findUnique({ + where: { serviceId: id }, + include: { service: { include: { destinationDocker: true } } } + }); + const publicPort = await (0, import_lib.getFreePublicPort)({ id, remoteEngine, engine, remoteIpAddress }); + let ftpUser = (0, import_cuid.default)(); + let ftpPassword = (0, import_lib.generatePassword)({}); + const hostkeyDir = import_common.isDev ? "/tmp/hostkeys" : "/app/ssl/hostkeys"; + try { + const data = await import_prisma.prisma.wordpress.update({ + where: { serviceId: id }, + data: { ftpEnabled }, + include: { service: { include: { destinationDocker: true } } } + }); + const { + service: { destinationDockerId, destinationDocker }, + ftpPublicPort, + ftpUser: user, + ftpPassword: savedPassword, + ftpHostKey, + ftpHostKeyPrivate + } = data; + const { network, engine: engine2 } = destinationDocker; + if (ftpEnabled) { + if (user) + ftpUser = user; + if (savedPassword) + ftpPassword = (0, import_common.decrypt)(savedPassword); + const { stdout: password } = await (0, import_executeCommand.executeCommand)({ + command: `echo ${ftpPassword} | openssl passwd -1 -stdin`, + shell: true + }); + if (destinationDockerId) { + try { + await import_promises.default.stat(hostkeyDir); + } catch (error) { + await (0, import_executeCommand.executeCommand)({ command: `mkdir -p ${hostkeyDir}` }); + } + if (!ftpHostKey) { + await (0, import_executeCommand.executeCommand)({ + command: `ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N "" -q -f ${hostkeyDir}/${id}.ed25519` + }); + const { stdout: ftpHostKey2 } = await (0, import_executeCommand.executeCommand)({ + command: `cat ${hostkeyDir}/${id}.ed25519` + }); + await import_prisma.prisma.wordpress.update({ + where: { serviceId: id }, + data: { ftpHostKey: (0, import_common.encrypt)(ftpHostKey2) } + }); + } else { + await (0, import_executeCommand.executeCommand)({ + command: `echo "${(0, import_common.decrypt)(ftpHostKey)}" > ${hostkeyDir}/${id}.ed25519`, + shell: true + }); + } + if (!ftpHostKeyPrivate) { + await (0, import_executeCommand.executeCommand)({ + command: `ssh-keygen -t rsa -b 4096 -N "" -f ${hostkeyDir}/${id}.rsa` + }); + const { stdout: ftpHostKeyPrivate2 } = await (0, import_executeCommand.executeCommand)({ + command: `cat ${hostkeyDir}/${id}.rsa` + }); + await import_prisma.prisma.wordpress.update({ + where: { serviceId: id }, + data: { ftpHostKeyPrivate: (0, import_common.encrypt)(ftpHostKeyPrivate2) } + }); + } else { + await (0, import_executeCommand.executeCommand)({ + command: `echo "${(0, import_common.decrypt)(ftpHostKeyPrivate)}" > ${hostkeyDir}/${id}.rsa`, + shell: true + }); + } + await import_prisma.prisma.wordpress.update({ + where: { serviceId: id }, + data: { + ftpPublicPort: publicPort, + ftpUser: user ? void 0 : ftpUser, + ftpPassword: savedPassword ? void 0 : (0, import_common.encrypt)(ftpPassword) + } + }); + try { + const { found: isRunning } = await (0, import_docker.checkContainer)({ + dockerId: destinationDocker.id, + container: `${id}-ftp` + }); + if (isRunning) { + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDocker.id, + command: `docker stop -t 0 ${id}-ftp && docker rm ${id}-ftp`, + shell: true + }); + } + } catch (error) { + } + const volumes = [ + `${id}-wordpress-data:/home/${ftpUser}/wordpress`, + `${import_common.isDev ? hostkeyDir : "/var/lib/docker/volumes/coolify-ssl-certs/_data/hostkeys"}/${id}.ed25519:/etc/ssh/ssh_host_ed25519_key`, + `${import_common.isDev ? hostkeyDir : "/var/lib/docker/volumes/coolify-ssl-certs/_data/hostkeys"}/${id}.rsa:/etc/ssh/ssh_host_rsa_key`, + `${import_common.isDev ? hostkeyDir : "/var/lib/docker/volumes/coolify-ssl-certs/_data/hostkeys"}/${id}.sh:/etc/sftp.d/chmod.sh` + ]; + const compose = { + 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 import_promises.default.writeFile( + `${hostkeyDir}/${id}.sh`, + `#!/bin/bash +chmod 600 /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key +userdel -f xfs +chown -R 33:33 /home/${ftpUser}/wordpress/` + ); + await (0, import_executeCommand.executeCommand)({ command: `chmod +x ${hostkeyDir}/${id}.sh` }); + await import_promises.default.writeFile(`${hostkeyDir}/${id}-docker-compose.yml`, import_js_yaml.default.dump(compose)); + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDocker.id, + command: `docker compose -f ${hostkeyDir}/${id}-docker-compose.yml up -d` + }); + } + return { + publicPort, + ftpUser, + ftpPassword + }; + } else { + await import_prisma.prisma.wordpress.update({ + where: { serviceId: id }, + data: { ftpPublicPort: null } + }); + try { + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDocker.id, + command: `docker stop -t 0 ${id}-ftp && docker rm ${id}-ftp`, + shell: true + }); + } catch (error) { + } + await (0, import_docker.stopTcpHttpProxy)(id, destinationDocker, ftpPublicPort); + } + } catch ({ status, message }) { + throw message; + } finally { + try { + await (0, import_executeCommand.executeCommand)({ + command: `rm -fr ${hostkeyDir}/${id}-docker-compose.yml ${hostkeyDir}/${id}.ed25519 ${hostkeyDir}/${id}.ed25519.pub ${hostkeyDir}/${id}.rsa ${hostkeyDir}/${id}.rsa.pub ${hostkeyDir}/${id}.sh` + }); + } catch (error) { + } + } + }), + start: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).mutation(async ({ input, ctx }) => { + const { id } = input; + const teamId = ctx.user?.teamId; + const service = await getServiceFromDB({ id, teamId }); + const arm = (0, import_common.isARM)(service.arch); + const { type, destinationDockerId, destinationDocker, persistentStorage, exposePort } = service; + const { workdir } = await (0, import_common.createDirectories)({ repository: type, buildId: id }); + const template = await (0, import_lib.parseAndFindServiceTemplates)(service, workdir, true); + const network = destinationDockerId && destinationDocker.network; + const config = {}; + for (const s in template.services) { + let newEnvironments = []; + if (arm) { + if (template.services[s]?.environmentArm?.length > 0) { + for (const environment of template.services[s].environmentArm) { + let [env, ...value] = environment.split("="); + value = value.join("="); + if (!value.startsWith("$$secret") && value !== "") { + newEnvironments.push(`${env}=${value}`); + } + } + } + } else { + if (template.services[s]?.environment?.length > 0) { + for (const environment of template.services[s].environment) { + let [env, ...value] = environment.split("="); + value = value.join("="); + if (!value.startsWith("$$secret") && value !== "") { + newEnvironments.push(`${env}=${value}`); + } + } + } + } + const secrets = await (0, import_lib.verifyAndDecryptServiceSecrets)(id); + for (const secret of secrets) { + const { name, value } = secret; + if (value) { + const foundEnv = !!template.services[s].environment?.find( + (env) => env.startsWith(`${name}=`) + ); + const foundNewEnv = !!newEnvironments?.find((env) => env.startsWith(`${name}=`)); + if (foundEnv && !foundNewEnv) { + newEnvironments.push(`${name}=${value}`); + } + if (!foundEnv && !foundNewEnv && s === id) { + newEnvironments.push(`${name}=${value}`); + } + } + } + const customVolumes = await import_prisma.prisma.servicePersistentStorage.findMany({ + where: { serviceId: id } + }); + let volumes = /* @__PURE__ */ new Set(); + if (arm) { + template.services[s]?.volumesArm && template.services[s].volumesArm.length > 0 && template.services[s].volumesArm.forEach((v) => volumes.add(v)); + } else { + template.services[s]?.volumes && template.services[s].volumes.length > 0 && template.services[s].volumes.forEach((v) => volumes.add(v)); + } + if (service.type === "plausibleanalytics" && service.plausibleAnalytics?.id) { + let temp = Array.from(volumes); + temp.forEach((a) => { + const t = a.replace(service.id, service.plausibleAnalytics.id); + volumes.delete(a); + volumes.add(t); + }); + } + if (customVolumes.length > 0) { + for (const customVolume of customVolumes) { + const { volumeName, path: path2, containerId } = customVolume; + if (volumes && volumes.size > 0 && !volumes.has(`${volumeName}:${path2}`) && containerId === service) { + volumes.add(`${volumeName}:${path2}`); + } + } + } + let ports = []; + if (template.services[s].proxy?.length > 0) { + for (const proxy of template.services[s].proxy) { + if (proxy.hostPort) { + ports.push(`${proxy.hostPort}:${proxy.port}`); + } + } + } else { + if (template.services[s].ports?.length === 1) { + for (const port of template.services[s].ports) { + if (exposePort) { + ports.push(`${exposePort}:${port}`); + } + } + } + } + let image = template.services[s].image; + if (arm && template.services[s].imageArm) { + image = template.services[s].imageArm; + } + config[s] = { + container_name: s, + build: template.services[s].build || void 0, + command: template.services[s].command, + entrypoint: template.services[s]?.entrypoint, + image, + expose: template.services[s].ports, + ports: ports.length > 0 ? ports : void 0, + volumes: Array.from(volumes), + environment: newEnvironments, + depends_on: template.services[s]?.depends_on, + ulimits: template.services[s]?.ulimits, + cap_drop: template.services[s]?.cap_drop, + cap_add: template.services[s]?.cap_add, + labels: (0, import_common.makeLabelForServices)(type), + ...(0, import_docker.defaultComposeConfiguration)(network) + }; + if (template.services[s]?.files?.length > 0) { + if (!config[s].build) { + config[s].build = { + context: workdir, + dockerfile: `Dockerfile.${s}` + }; + } + let Dockerfile = ` + FROM ${template.services[s].image}`; + for (const file of template.services[s].files) { + const { location, content } = file; + const source = import_path.default.join(workdir, location); + await import_promises.default.mkdir(import_path.default.dirname(source), { recursive: true }); + await import_promises.default.writeFile(source, content); + Dockerfile += ` + COPY .${location} ${location}`; + } + await import_promises.default.writeFile(`${workdir}/Dockerfile.${s}`, Dockerfile); + } + } + const { volumeMounts } = (0, import_lib.persistentVolumes)(id, persistentStorage, config); + const composeFile = { + version: "3.8", + services: config, + networks: { + [network]: { + external: true + } + }, + volumes: volumeMounts + }; + const composeFileDestination = `${workdir}/docker-compose.yaml`; + await import_promises.default.writeFile(composeFileDestination, import_js_yaml.default.dump(composeFile)); + let fastify = null; + await (0, import_lib.startServiceContainers)(fastify, id, teamId, destinationDocker.id, composeFileDestination); + if (service.type === "minio") { + try { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDocker.id, + command: `docker container ls -a --filter 'name=${id}-' --format {{.ID}}` + }); + if (containers) { + const containerArray = containers.split("\n"); + if (containerArray.length > 0) { + for (const container of containerArray) { + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker stop -t 0 ${container}` + }); + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker rm --force ${container}` + }); + } + } + } + } catch (error) { + } + try { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDocker.id, + command: `docker container ls -a --filter 'name=${id}-' --format {{.ID}}` + }); + if (containers) { + const containerArray = containers.split("\n"); + if (containerArray.length > 0) { + for (const container of containerArray) { + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker stop -t 0 ${container}` + }); + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker rm --force ${container}` + }); + } + } + } + } catch (error) { + } + } + }), + stop: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).mutation(async ({ input, ctx }) => { + const { id } = input; + const teamId = ctx.user?.teamId; + const { destinationDockerId } = await getServiceFromDB({ id, teamId }); + if (destinationDockerId) { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker ps -a --filter 'label=com.docker.compose.project=${id}' --format {{.ID}}` + }); + if (containers) { + const containerArray = containers.split("\n"); + if (containerArray.length > 0) { + for (const container of containerArray) { + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker stop -t 0 ${container}` + }); + await (0, import_executeCommand.executeCommand)({ + dockerId: destinationDockerId, + command: `docker rm --force ${container}` + }); + } + } + } + return {}; + } + }), + getServices: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).query(async ({ input, ctx }) => { + const { id } = input; + const teamId = ctx.user?.teamId; + const service = await getServiceFromDB({ id, teamId }); + if (!service) { + throw { status: 404, message: "Service not found." }; + } + let template = {}; + let tags = []; + if (service.type) { + template = await (0, import_lib.parseAndFindServiceTemplates)(service); + tags = await (0, import_common.getTags)(service.type); + } + return { + success: true, + data: { + settings: await (0, import_common.listSettings)(), + service, + template, + tags + } + }; + }), + status: import_trpc.privateProcedure.input(import_zod.z.object({ id: import_zod.z.string() })).query(async ({ ctx, input }) => { + const id = input.id; + const teamId = ctx.user?.teamId; + if (!teamId) { + throw { status: 400, message: "Team not found." }; + } + const service = await getServiceFromDB({ id, teamId }); + const { destinationDockerId } = service; + let payload = {}; + if (destinationDockerId) { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: service.destinationDocker.id, + command: `docker ps -a --filter "label=com.docker.compose.project=${id}" --format '{{json .}}'` + }); + if (containers) { + const containersArray = containers.trim().split("\n"); + if (containersArray.length > 0 && containersArray[0] !== "") { + const templates = await (0, import_common.getTemplates)(); + let template = templates.find((t) => t.type === service.type); + const templateStr = JSON.stringify(template); + if (templateStr) { + template = JSON.parse(templateStr.replaceAll("$$id", service.id)); + } + for (const container of containersArray) { + let isRunning = false; + let isExited = false; + let isRestarting = false; + let isExcluded = false; + const containerObj = JSON.parse(container); + const exclude = template?.services[containerObj.Names]?.exclude; + if (exclude) { + payload[containerObj.Names] = { + status: { + isExcluded: true, + isRunning: false, + isExited: false, + isRestarting: false + } + }; + continue; + } + const status = containerObj.State; + if (status === "running") { + isRunning = true; + } + if (status === "exited") { + isExited = true; + } + if (status === "restarting") { + isRestarting = true; + } + payload[containerObj.Names] = { + status: { + isExcluded, + isRunning, + isExited, + isRestarting + } + }; + } + } + } + } + return payload; + }), + cleanup: import_trpc.privateProcedure.query(async ({ ctx }) => { + const teamId = ctx.user?.teamId; + let services = await import_prisma.prisma.service.findMany({ + where: { teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { destinationDocker: true, teams: true } + }); + for (const service of services) { + if (!service.fqdn) { + if (service.destinationDockerId) { + const { stdout: containers } = await (0, import_executeCommand.executeCommand)({ + dockerId: service.destinationDockerId, + command: `docker ps -a --filter 'label=com.docker.compose.project=${service.id}' --format {{.ID}}` + }); + if (containers) { + const containerArray = containers.split("\n"); + if (containerArray.length > 0) { + for (const container of containerArray) { + await (0, import_executeCommand.executeCommand)({ + dockerId: service.destinationDockerId, + command: `docker stop -t 0 ${container}` + }); + await (0, import_executeCommand.executeCommand)({ + dockerId: service.destinationDockerId, + command: `docker rm --force ${container}` + }); + } + } + } + } + await (0, import_common.removeService)({ id: service.id }); + } + } + }), + delete: import_trpc.privateProcedure.input(import_zod.z.object({ force: import_zod.z.boolean(), id: import_zod.z.string() })).mutation(async ({ input }) => { + const { id } = input; + await import_prisma.prisma.serviceSecret.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.serviceSetting.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.servicePersistentStorage.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.meiliSearch.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.fider.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.ghost.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.umami.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.hasura.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.plausibleAnalytics.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.minio.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.vscodeserver.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.wordpress.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.glitchTip.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.moodle.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.appwrite.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.searxng.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.weblate.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.taiga.deleteMany({ where: { serviceId: id } }); + await import_prisma.prisma.service.delete({ where: { id } }); + return {}; + }) +}); +async function getServiceFromDB({ + id, + teamId +}) { + const settings = await import_prisma.prisma.setting.findFirst(); + const body = await import_prisma.prisma.service.findFirst({ + where: { id, teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + include: { + destinationDocker: true, + persistentStorage: true, + serviceSecret: true, + serviceSetting: true, + wordpress: true, + plausibleAnalytics: true + } + }); + if (!body) { + return null; + } + if (body?.serviceSecret.length > 0) { + body.serviceSecret = body.serviceSecret.map((s) => { + s.value = (0, import_common.decrypt)(s.value); + return s; + }); + } + if (body.wordpress) { + body.wordpress.ftpPassword = (0, import_common.decrypt)(body.wordpress.ftpPassword); + } + return { ...body, settings }; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + getServiceFromDB, + servicesRouter +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/services/lib.js b/apps/trpc-experimental/server/build/trpc/routers/services/lib.js new file mode 100644 index 000000000..f374502d9 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/services/lib.js @@ -0,0 +1,371 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var lib_exports = {}; +__export(lib_exports, { + generatePassword: () => generatePassword, + getFreePublicPort: () => getFreePublicPort, + parseAndFindServiceTemplates: () => parseAndFindServiceTemplates, + persistentVolumes: () => persistentVolumes, + startServiceContainers: () => startServiceContainers, + verifyAndDecryptServiceSecrets: () => verifyAndDecryptServiceSecrets +}); +module.exports = __toCommonJS(lib_exports); +var import_common = require("../../../lib/common"); +var import_bcryptjs = __toESM(require("bcryptjs")); +var import_prisma = require("../../../prisma"); +var import_crypto = __toESM(require("crypto")); +var import_executeCommand = require("../../../lib/executeCommand"); +async function parseAndFindServiceTemplates(service, workdir, isDeploy = false) { + const templates = await (0, import_common.getTemplates)(); + const foundTemplate = templates.find((t) => (0, import_common.fixType)(t.type) === service.type); + let parsedTemplate = {}; + if (foundTemplate) { + if (!isDeploy) { + for (const [key, value] of Object.entries(foundTemplate.services)) { + const realKey = key.replace("$$id", service.id); + let name = value.name; + if (!name) { + if (Object.keys(foundTemplate.services).length === 1) { + name = foundTemplate.name || service.name.toLowerCase(); + } else { + if (key === "$$id") { + name = foundTemplate.name || key.replaceAll("$$id-", "") || service.name.toLowerCase(); + } else { + name = key.replaceAll("$$id-", "") || service.name.toLowerCase(); + } + } + } + parsedTemplate[realKey] = { + value, + name, + documentation: value.documentation || foundTemplate.documentation || "https://docs.coollabs.io", + image: value.image, + files: value?.files, + environment: [], + fqdns: [], + hostPorts: [], + proxy: {} + }; + if (value.environment?.length > 0) { + for (const env of value.environment) { + let [envKey, ...envValue] = env.split("="); + envValue = envValue.join("="); + let variable = null; + if (foundTemplate?.variables) { + variable = foundTemplate?.variables.find((v) => v.name === envKey) || foundTemplate?.variables.find((v) => v.id === envValue); + } + if (variable) { + const id = variable.id.replaceAll("$$", ""); + const label = variable?.label; + const description = variable?.description; + const defaultValue = variable?.defaultValue; + const main = variable?.main || "$$id"; + const type = variable?.type || "input"; + const placeholder = variable?.placeholder || ""; + const readOnly = variable?.readOnly || false; + const required = variable?.required || false; + if (envValue.startsWith("$$config") || variable?.showOnConfiguration) { + if (envValue.startsWith("$$config_coolify")) { + continue; + } + parsedTemplate[realKey].environment.push({ + id, + name: envKey, + value: envValue, + main, + label, + description, + defaultValue, + type, + placeholder, + required, + readOnly + }); + } + } + } + } + if (value?.proxy && value.proxy.length > 0) { + for (const proxyValue of value.proxy) { + if (proxyValue.domain) { + const variable = foundTemplate?.variables.find((v) => v.id === proxyValue.domain); + if (variable) { + const { id, name: name2, label, description, defaultValue, required = false } = variable; + const found = await import_prisma.prisma.serviceSetting.findFirst({ + where: { serviceId: service.id, variableName: proxyValue.domain } + }); + parsedTemplate[realKey].fqdns.push({ + id, + name: name2, + value: found?.value || "", + label, + description, + defaultValue, + required + }); + } + } + if (proxyValue.hostPort) { + const variable = foundTemplate?.variables.find((v) => v.id === proxyValue.hostPort); + if (variable) { + const { id, name: name2, label, description, defaultValue, required = false } = variable; + const found = await import_prisma.prisma.serviceSetting.findFirst({ + where: { serviceId: service.id, variableName: proxyValue.hostPort } + }); + parsedTemplate[realKey].hostPorts.push({ + id, + name: name2, + value: found?.value || "", + label, + description, + defaultValue, + required + }); + } + } + } + } + } + } else { + parsedTemplate = foundTemplate; + } + let strParsedTemplate = JSON.stringify(parsedTemplate); + strParsedTemplate = strParsedTemplate.replaceAll("$$id", service.id); + strParsedTemplate = strParsedTemplate.replaceAll( + "$$core_version", + service.version || foundTemplate.defaultVersion + ); + if (workdir) { + strParsedTemplate = strParsedTemplate.replaceAll("$$workdir", workdir); + } + if (service.serviceSetting.length > 0) { + for (const setting of service.serviceSetting) { + const { value, variableName } = setting; + const regex = new RegExp(`\\$\\$config_${variableName.replace("$$config_", "")}"`, "gi"); + if (value === "$$generate_fqdn") { + strParsedTemplate = strParsedTemplate.replaceAll(regex, service.fqdn + '"' || '"'); + } else if (value === "$$generate_fqdn_slash") { + strParsedTemplate = strParsedTemplate.replaceAll(regex, service.fqdn + '/"'); + } else if (value === "$$generate_domain") { + strParsedTemplate = strParsedTemplate.replaceAll(regex, (0, import_common.getDomain)(service.fqdn) + '"'); + } else if (service.destinationDocker?.network && value === "$$generate_network") { + strParsedTemplate = strParsedTemplate.replaceAll( + regex, + service.destinationDocker.network + '"' + ); + } else { + strParsedTemplate = strParsedTemplate.replaceAll(regex, value + '"'); + } + } + } + if (service.serviceSecret.length > 0) { + for (const secret of service.serviceSecret) { + let { name, value } = secret; + name = name.toLowerCase(); + const regexHashed = new RegExp(`\\$\\$hashed\\$\\$secret_${name}`, "gi"); + const regex = new RegExp(`\\$\\$secret_${name}`, "gi"); + if (value) { + strParsedTemplate = strParsedTemplate.replaceAll( + regexHashed, + import_bcryptjs.default.hashSync(value.replaceAll('"', '\\"'), 10) + ); + strParsedTemplate = strParsedTemplate.replaceAll(regex, value.replaceAll('"', '\\"')); + } else { + strParsedTemplate = strParsedTemplate.replaceAll(regexHashed, ""); + strParsedTemplate = strParsedTemplate.replaceAll(regex, ""); + } + } + } + parsedTemplate = JSON.parse(strParsedTemplate); + } + return parsedTemplate; +} +function generatePassword({ + length = 24, + symbols = false, + isHex = false +}) { + if (isHex) { + return import_crypto.default.randomBytes(length).toString("hex"); + } + const password = generator.generate({ + length, + numbers: true, + strict: true, + symbols + }); + return password; +} +async function getFreePublicPort({ id, remoteEngine, engine, remoteIpAddress }) { + const { default: isReachable } = await import("is-port-reachable"); + const data = await import_prisma.prisma.setting.findFirst(); + const { minPort, maxPort } = data; + if (remoteEngine) { + const dbUsed = await (await import_prisma.prisma.database.findMany({ + where: { + publicPort: { not: null }, + id: { not: id }, + destinationDocker: { remoteIpAddress } + }, + select: { publicPort: true } + })).map((a) => a.publicPort); + const wpFtpUsed = await (await import_prisma.prisma.wordpress.findMany({ + where: { + ftpPublicPort: { not: null }, + id: { not: id }, + service: { destinationDocker: { remoteIpAddress } } + }, + select: { ftpPublicPort: true } + })).map((a) => a.ftpPublicPort); + const wpUsed = await (await import_prisma.prisma.wordpress.findMany({ + where: { + mysqlPublicPort: { not: null }, + id: { not: id }, + service: { destinationDocker: { remoteIpAddress } } + }, + select: { mysqlPublicPort: true } + })).map((a) => a.mysqlPublicPort); + const minioUsed = await (await import_prisma.prisma.minio.findMany({ + where: { + publicPort: { not: null }, + id: { not: id }, + service: { destinationDocker: { remoteIpAddress } } + }, + select: { publicPort: true } + })).map((a) => a.publicPort); + const usedPorts = [...dbUsed, ...wpFtpUsed, ...wpUsed, ...minioUsed]; + const range = (0, import_common.generateRangeArray)(minPort, maxPort); + const availablePorts = range.filter((port) => !usedPorts.includes(port)); + for (const port of availablePorts) { + const found = await isReachable(port, { host: remoteIpAddress }); + if (!found) { + return port; + } + } + return false; + } else { + const dbUsed = await (await import_prisma.prisma.database.findMany({ + where: { publicPort: { not: null }, id: { not: id }, destinationDocker: { engine } }, + select: { publicPort: true } + })).map((a) => a.publicPort); + const wpFtpUsed = await (await import_prisma.prisma.wordpress.findMany({ + where: { + ftpPublicPort: { not: null }, + id: { not: id }, + service: { destinationDocker: { engine } } + }, + select: { ftpPublicPort: true } + })).map((a) => a.ftpPublicPort); + const wpUsed = await (await import_prisma.prisma.wordpress.findMany({ + where: { + mysqlPublicPort: { not: null }, + id: { not: id }, + service: { destinationDocker: { engine } } + }, + select: { mysqlPublicPort: true } + })).map((a) => a.mysqlPublicPort); + const minioUsed = await (await import_prisma.prisma.minio.findMany({ + where: { + publicPort: { not: null }, + id: { not: id }, + service: { destinationDocker: { engine } } + }, + select: { publicPort: true } + })).map((a) => a.publicPort); + const usedPorts = [...dbUsed, ...wpFtpUsed, ...wpUsed, ...minioUsed]; + const range = (0, import_common.generateRangeArray)(minPort, maxPort); + const availablePorts = range.filter((port) => !usedPorts.includes(port)); + for (const port of availablePorts) { + const found = await isReachable(port, { host: "localhost" }); + if (!found) { + return port; + } + } + return false; + } +} +async function verifyAndDecryptServiceSecrets(id) { + const secrets = await import_prisma.prisma.serviceSecret.findMany({ where: { serviceId: id } }); + let decryptedSecrets = secrets.map((secret) => { + const { name, value } = secret; + if (value) { + let rawValue = (0, import_common.decrypt)(value); + rawValue = rawValue.replaceAll(/\$/gi, "$$$"); + return { name, value: rawValue }; + } + return { name, value }; + }); + return decryptedSecrets; +} +function persistentVolumes(id, persistentStorage, config) { + let volumeSet = /* @__PURE__ */ new Set(); + if (Object.keys(config).length > 0) { + for (const [key, value] of Object.entries(config)) { + if (value.volumes) { + for (const volume of value.volumes) { + if (!volume.startsWith("/")) { + volumeSet.add(volume); + } + } + } + } + } + const volumesArray = Array.from(volumeSet); + const persistentVolume = persistentStorage?.map((storage) => { + return `${id}${storage.path.replace(/\//gi, "-")}:${storage.path}`; + }) || []; + let volumes = [...persistentVolume]; + if (volumesArray) + volumes = [...volumesArray, ...volumes]; + const composeVolumes = volumes.length > 0 && volumes.map((volume) => { + return { + [`${volume.split(":")[0]}`]: { + name: volume.split(":")[0] + } + }; + }) || []; + const volumeMounts = Object.assign({}, ...composeVolumes) || {}; + return { volumeMounts }; +} +async function startServiceContainers(fastify, id, teamId, dockerId, composeFileDestination) { + try { + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker compose -f ${composeFileDestination} pull` }); + } catch (error) { + } + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker compose -f ${composeFileDestination} build --no-cache` }); + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker compose -f ${composeFileDestination} create` }); + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker compose -f ${composeFileDestination} start` }); + await (0, import_common.asyncSleep)(1e3); + await (0, import_executeCommand.executeCommand)({ dockerId, command: `docker compose -f ${composeFileDestination} up -d` }); +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + generatePassword, + getFreePublicPort, + parseAndFindServiceTemplates, + persistentVolumes, + startServiceContainers, + verifyAndDecryptServiceSecrets +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/settings.js b/apps/trpc-experimental/server/build/trpc/routers/settings.js new file mode 100644 index 000000000..425a0d819 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/settings.js @@ -0,0 +1,108 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var settings_exports = {}; +__export(settings_exports, { + settingsRouter: () => settingsRouter +}); +module.exports = __toCommonJS(settings_exports); +var import_trpc = require("../trpc"); +var import_server = require("@trpc/server"); +var import_common = require("../../lib/common"); +var import_env = require("../../env"); +var import_jsonwebtoken = __toESM(require("jsonwebtoken")); +const settingsRouter = (0, import_trpc.router)({ + getBaseSettings: import_trpc.publicProcedure.query(async () => { + const settings = await (0, import_common.listSettings)(); + return { + success: true, + data: { + isRegistrationEnabled: settings?.isRegistrationEnabled + } + }; + }), + getInstanceSettings: import_trpc.privateProcedure.query(async ({ ctx }) => { + try { + const settings = await (0, import_common.listSettings)(); + let isAdmin = false; + let permission = null; + let token = null; + let pendingInvitations = []; + if (!settings) { + throw new import_server.TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An unexpected error occurred, please try again later." + }); + } + if (ctx.user) { + const currentUser = await (0, import_common.getCurrentUser)(ctx.user.userId); + if (currentUser) { + const foundPermission = currentUser.permission.find( + (p) => p.teamId === ctx.user?.teamId + )?.permission; + if (foundPermission) { + permission = foundPermission; + isAdmin = foundPermission === "owner" || foundPermission === "admin"; + } + const payload = { + userId: ctx.user?.userId, + teamId: ctx.user?.teamId, + permission, + isAdmin, + iat: Math.floor(Date.now() / 1e3) + }; + token = import_jsonwebtoken.default.sign(payload, import_env.env.COOLIFY_SECRET_KEY); + } + pendingInvitations = await (0, import_common.getTeamInvitation)(ctx.user.userId); + } + return { + success: true, + data: { + token, + userId: ctx.user?.userId, + teamId: ctx.user?.teamId, + permission, + isAdmin, + ipv4: ctx.user?.teamId ? settings.ipv4 : null, + ipv6: ctx.user?.teamId ? settings.ipv6 : null, + version: import_common.version, + whiteLabeled: import_env.env.COOLIFY_WHITE_LABELED === "true", + whiteLabeledIcon: import_env.env.COOLIFY_WHITE_LABELED_ICON, + isRegistrationEnabled: settings.isRegistrationEnabled, + pendingInvitations + } + }; + } catch (error) { + throw new import_server.TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An unexpected error occurred, please try again later.", + cause: error + }); + } + }) +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + settingsRouter +}); diff --git a/apps/trpc-experimental/server/build/trpc/routers/sources/index.js b/apps/trpc-experimental/server/build/trpc/routers/sources/index.js new file mode 100644 index 000000000..08f10e593 --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/routers/sources/index.js @@ -0,0 +1,241 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var sources_exports = {}; +__export(sources_exports, { + sourcesRouter: () => sourcesRouter +}); +module.exports = __toCommonJS(sources_exports); +var import_zod = require("zod"); +var import_trpc = require("../../trpc"); +var import_common = require("../../../lib/common"); +var import_prisma = require("../../../prisma"); +var import_cuid = __toESM(require("cuid")); +const sourcesRouter = (0, import_trpc.router)({ + save: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + name: import_zod.z.string(), + htmlUrl: import_zod.z.string(), + apiUrl: import_zod.z.string(), + customPort: import_zod.z.number(), + customUser: import_zod.z.string(), + isSystemWide: import_zod.z.boolean().default(false) + }) + ).mutation(async ({ input, ctx }) => { + let { id, name, htmlUrl, apiUrl, customPort, customUser, isSystemWide } = input; + if (customPort) + customPort = Number(customPort); + await import_prisma.prisma.gitSource.update({ + where: { id }, + data: { name, htmlUrl, apiUrl, customPort, customUser, isSystemWide } + }); + }), + newGitHubApp: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + name: import_zod.z.string(), + htmlUrl: import_zod.z.string(), + apiUrl: import_zod.z.string(), + organization: import_zod.z.string(), + customPort: import_zod.z.number(), + isSystemWide: import_zod.z.boolean().default(false) + }) + ).mutation(async ({ ctx, input }) => { + const { teamId } = ctx.user; + let { id, name, htmlUrl, apiUrl, organization, customPort, isSystemWide } = input; + if (customPort) + customPort = Number(customPort); + if (id === "new") { + const newId = (0, import_cuid.default)(); + await import_prisma.prisma.gitSource.create({ + data: { + id: newId, + name, + htmlUrl, + apiUrl, + organization, + customPort, + isSystemWide, + type: "github", + teams: { connect: { id: teamId } } + } + }); + return { + id: newId + }; + } + return null; + }), + newGitLabApp: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string(), + type: import_zod.z.string(), + name: import_zod.z.string(), + htmlUrl: import_zod.z.string(), + apiUrl: import_zod.z.string(), + oauthId: import_zod.z.number(), + appId: import_zod.z.string(), + appSecret: import_zod.z.string(), + groupName: import_zod.z.string().optional().nullable(), + customPort: import_zod.z.number().optional().nullable(), + customUser: import_zod.z.string().optional().nullable() + }) + ).mutation(async ({ input, ctx }) => { + const { teamId } = ctx.user; + let { + id, + type, + name, + htmlUrl, + apiUrl, + oauthId, + appId, + appSecret, + groupName, + customPort, + customUser + } = input; + if (oauthId) + oauthId = Number(oauthId); + if (customPort) + customPort = Number(customPort); + const encryptedAppSecret = (0, import_common.encrypt)(appSecret); + if (id === "new") { + const newId = (0, import_cuid.default)(); + await import_prisma.prisma.gitSource.create({ + data: { + id: newId, + type, + apiUrl, + htmlUrl, + name, + customPort, + customUser, + teams: { connect: { id: teamId } } + } + }); + await import_prisma.prisma.gitlabApp.create({ + data: { + teams: { connect: { id: teamId } }, + appId, + oauthId, + groupName, + appSecret: encryptedAppSecret, + gitSource: { connect: { id: newId } } + } + }); + return { + status: 201, + id: newId + }; + } else { + await import_prisma.prisma.gitSource.update({ + where: { id }, + data: { type, apiUrl, htmlUrl, name, customPort, customUser } + }); + await import_prisma.prisma.gitlabApp.update({ + where: { id }, + data: { + appId, + oauthId, + groupName, + appSecret: encryptedAppSecret + } + }); + } + }), + delete: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).mutation(async ({ input, ctx }) => { + const { id } = input; + const source = await import_prisma.prisma.gitSource.delete({ + where: { id }, + include: { githubApp: true, gitlabApp: true } + }); + if (source.githubAppId) { + await import_prisma.prisma.githubApp.delete({ where: { id: source.githubAppId } }); + } + if (source.gitlabAppId) { + await import_prisma.prisma.gitlabApp.delete({ where: { id: source.gitlabAppId } }); + } + }), + getSourceById: import_trpc.privateProcedure.input( + import_zod.z.object({ + id: import_zod.z.string() + }) + ).query(async ({ input, ctx }) => { + const { id } = input; + const { teamId } = ctx.user; + const settings = await import_prisma.prisma.setting.findFirst({}); + if (id === "new") { + return { + source: { + name: null, + type: null, + htmlUrl: null, + apiUrl: null, + organization: null, + customPort: 22, + customUser: "git" + }, + settings + }; + } + const source = await import_prisma.prisma.gitSource.findFirst({ + where: { + id, + OR: [ + { teams: { some: { id: teamId === "0" ? void 0 : teamId } } }, + { isSystemWide: true } + ] + }, + include: { githubApp: true, gitlabApp: true } + }); + if (!source) { + throw { status: 404, message: "Source not found." }; + } + if (source?.githubApp?.clientSecret) + source.githubApp.clientSecret = (0, import_common.decrypt)(source.githubApp.clientSecret); + if (source?.githubApp?.webhookSecret) + source.githubApp.webhookSecret = (0, import_common.decrypt)(source.githubApp.webhookSecret); + if (source?.githubApp?.privateKey) + source.githubApp.privateKey = (0, import_common.decrypt)(source.githubApp.privateKey); + if (source?.gitlabApp?.appSecret) + source.gitlabApp.appSecret = (0, import_common.decrypt)(source.gitlabApp.appSecret); + return { + success: true, + data: { + source, + settings + } + }; + }) +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + sourcesRouter +}); diff --git a/apps/trpc-experimental/server/build/trpc/trpc.js b/apps/trpc-experimental/server/build/trpc/trpc.js new file mode 100644 index 000000000..1b7ee2c0f --- /dev/null +++ b/apps/trpc-experimental/server/build/trpc/trpc.js @@ -0,0 +1,65 @@ +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var trpc_exports = {}; +__export(trpc_exports, { + privateProcedure: () => privateProcedure, + publicProcedure: () => publicProcedure, + router: () => router +}); +module.exports = __toCommonJS(trpc_exports); +var import_server = require("@trpc/server"); +var import_superjson = __toESM(require("superjson")); +const t = import_server.initTRPC.context().create({ + transformer: import_superjson.default, + errorFormatter({ shape }) { + return shape; + } +}); +const logger = t.middleware(async ({ path, type, next }) => { + const start = Date.now(); + const result = await next(); + const durationMs = Date.now() - start; + result.ok ? console.log("OK request timing:", { path, type, durationMs }) : console.log("Non-OK request timing", { path, type, durationMs }); + return result; +}); +const isAdmin = t.middleware(async ({ ctx, next }) => { + if (!ctx.user) { + throw new import_server.TRPCError({ code: "UNAUTHORIZED" }); + } + return next({ + ctx: { + user: ctx.user + } + }); +}); +const router = t.router; +const privateProcedure = t.procedure.use(isAdmin); +const publicProcedure = t.procedure; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + privateProcedure, + publicProcedure, + router +}); diff --git a/apps/server/db/.gitkeep b/apps/trpc-experimental/server/db/.gitkeep similarity index 100% rename from apps/server/db/.gitkeep rename to apps/trpc-experimental/server/db/.gitkeep diff --git a/apps/trpc-experimental/server/db/dev.db b/apps/trpc-experimental/server/db/dev.db new file mode 100644 index 000000000..3aba23ddd Binary files /dev/null and b/apps/trpc-experimental/server/db/dev.db differ diff --git a/apps/trpc-experimental/server/db/migration.db b/apps/trpc-experimental/server/db/migration.db new file mode 100644 index 000000000..d555f31d5 Binary files /dev/null and b/apps/trpc-experimental/server/db/migration.db differ diff --git a/apps/trpc-experimental/server/db/migration.db-journal b/apps/trpc-experimental/server/db/migration.db-journal new file mode 100644 index 000000000..3deb841d8 Binary files /dev/null and b/apps/trpc-experimental/server/db/migration.db-journal differ diff --git a/apps/server/devTags.json b/apps/trpc-experimental/server/devTags.json similarity index 100% rename from apps/server/devTags.json rename to apps/trpc-experimental/server/devTags.json diff --git a/apps/server/devTemplates.yaml b/apps/trpc-experimental/server/devTemplates.yaml similarity index 100% rename from apps/server/devTemplates.yaml rename to apps/trpc-experimental/server/devTemplates.yaml diff --git a/apps/server/nodemon.json b/apps/trpc-experimental/server/nodemon.json similarity index 100% rename from apps/server/nodemon.json rename to apps/trpc-experimental/server/nodemon.json diff --git a/apps/server/package.json b/apps/trpc-experimental/server/package.json similarity index 100% rename from apps/server/package.json rename to apps/trpc-experimental/server/package.json diff --git a/apps/server/prisma/migrations/20220131142425_init/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220131142425_init/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220131142425_init/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220131142425_init/migration.sql diff --git a/apps/server/prisma/migrations/20220210104005_redis_aol/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220210104005_redis_aol/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220210104005_redis_aol/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220210104005_redis_aol/migration.sql diff --git a/apps/server/prisma/migrations/20220212142309_unique_secret_by_application/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220212142309_unique_secret_by_application/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220212142309_unique_secret_by_application/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220212142309_unique_secret_by_application/migration.sql diff --git a/apps/server/prisma/migrations/20220217211304_dualcerts/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220217211304_dualcerts/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220217211304_dualcerts/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220217211304_dualcerts/migration.sql diff --git a/apps/server/prisma/migrations/20220219231255_prmr_secrets/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220219231255_prmr_secrets/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220219231255_prmr_secrets/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220219231255_prmr_secrets/migration.sql diff --git a/apps/server/prisma/migrations/20220220141136_public_portrange/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220220141136_public_portrange/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220220141136_public_portrange/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220220141136_public_portrange/migration.sql diff --git a/apps/server/prisma/migrations/20220301101928_proxyhash/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220301101928_proxyhash/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220301101928_proxyhash/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220301101928_proxyhash/migration.sql diff --git a/apps/server/prisma/migrations/20220304141408_service_secrets/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220304141408_service_secrets/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220304141408_service_secrets/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220304141408_service_secrets/migration.sql diff --git a/apps/server/prisma/migrations/20220311213422_autodeploy/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220311213422_autodeploy/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220311213422_autodeploy/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220311213422_autodeploy/migration.sql diff --git a/apps/server/prisma/migrations/20220320141424_phpmodules/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220320141424_phpmodules/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220320141424_phpmodules/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220320141424_phpmodules/migration.sql diff --git a/apps/server/prisma/migrations/20220322135800_persistent_storage/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220322135800_persistent_storage/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220322135800_persistent_storage/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220322135800_persistent_storage/migration.sql diff --git a/apps/server/prisma/migrations/20220327180323_ghost/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220327180323_ghost/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220327180323_ghost/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220327180323_ghost/migration.sql diff --git a/apps/server/prisma/migrations/20220402135305_python/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220402135305_python/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220402135305_python/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220402135305_python/migration.sql diff --git a/apps/server/prisma/migrations/20220402210645_meilisearch/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220402210645_meilisearch/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220402210645_meilisearch/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220402210645_meilisearch/migration.sql diff --git a/apps/server/prisma/migrations/20220405151428_wordpress_sftp/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220405151428_wordpress_sftp/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220405151428_wordpress_sftp/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220405151428_wordpress_sftp/migration.sql diff --git a/apps/server/prisma/migrations/20220407220809_unique_storage_fix/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220407220809_unique_storage_fix/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220407220809_unique_storage_fix/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220407220809_unique_storage_fix/migration.sql diff --git a/apps/server/prisma/migrations/20220408070805_added_expose_port/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220408070805_added_expose_port/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220408070805_added_expose_port/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220408070805_added_expose_port/migration.sql diff --git a/apps/server/prisma/migrations/20220418214843_persistent_storage_services/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220418214843_persistent_storage_services/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220418214843_persistent_storage_services/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220418214843_persistent_storage_services/migration.sql diff --git a/apps/server/prisma/migrations/20220419203408_multiply_dockerfile_locations/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220419203408_multiply_dockerfile_locations/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220419203408_multiply_dockerfile_locations/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220419203408_multiply_dockerfile_locations/migration.sql diff --git a/apps/server/prisma/migrations/20220420202031_deno_configurations/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220420202031_deno_configurations/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220420202031_deno_configurations/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220420202031_deno_configurations/migration.sql diff --git a/apps/server/prisma/migrations/20220420210057_branch_for_builds/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220420210057_branch_for_builds/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220420210057_branch_for_builds/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220420210057_branch_for_builds/migration.sql diff --git a/apps/server/prisma/migrations/20220425071132_umami/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220425071132_umami/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220425071132_umami/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220425071132_umami/migration.sql diff --git a/apps/server/prisma/migrations/20220425075326_auto_update_coolify/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220425075326_auto_update_coolify/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220425075326_auto_update_coolify/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220425075326_auto_update_coolify/migration.sql diff --git a/apps/server/prisma/migrations/20220426125053_select_base_image/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220426125053_select_base_image/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220426125053_select_base_image/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220426125053_select_base_image/migration.sql diff --git a/apps/server/prisma/migrations/20220427133656_hasura/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220427133656_hasura/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220427133656_hasura/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220427133656_hasura/migration.sql diff --git a/apps/server/prisma/migrations/20220429202516_fider/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220429202516_fider/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220429202516_fider/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220429202516_fider/migration.sql diff --git a/apps/server/prisma/migrations/20220429214112_fider_correction/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220429214112_fider_correction/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220429214112_fider_correction/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220429214112_fider_correction/migration.sql diff --git a/apps/server/prisma/migrations/20220430111953_ssl_dns_check_settings/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220430111953_ssl_dns_check_settings/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220430111953_ssl_dns_check_settings/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220430111953_ssl_dns_check_settings/migration.sql diff --git a/apps/server/prisma/migrations/20220430124553_expose_port_for_services/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220430124553_expose_port_for_services/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220430124553_expose_port_for_services/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220430124553_expose_port_for_services/migration.sql diff --git a/apps/server/prisma/migrations/20220509130501_custom_plausible_script/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220509130501_custom_plausible_script/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220509130501_custom_plausible_script/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220509130501_custom_plausible_script/migration.sql diff --git a/apps/server/prisma/migrations/20220510081125_custom_wordpress_db/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220510081125_custom_wordpress_db/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220510081125_custom_wordpress_db/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220510081125_custom_wordpress_db/migration.sql diff --git a/apps/server/prisma/migrations/20220517081328_traefik/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220517081328_traefik/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220517081328_traefik/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220517081328_traefik/migration.sql diff --git a/apps/server/prisma/migrations/20220519095648_minio_apifqdn/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220519095648_minio_apifqdn/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220519095648_minio_apifqdn/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220519095648_minio_apifqdn/migration.sql diff --git a/apps/server/prisma/migrations/20220708132655_deployment_type_for_applications/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220708132655_deployment_type_for_applications/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220708132655_deployment_type_for_applications/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220708132655_deployment_type_for_applications/migration.sql diff --git a/apps/server/prisma/migrations/20220712083523_custom_port_git_sources/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220712083523_custom_port_git_sources/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220712083523_custom_port_git_sources/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220712083523_custom_port_git_sources/migration.sql diff --git a/apps/server/prisma/migrations/20220718083646_moodle/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220718083646_moodle/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220718083646_moodle/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220718083646_moodle/migration.sql diff --git a/apps/server/prisma/migrations/20220718114551_remote_docker_engine/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220718114551_remote_docker_engine/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220718114551_remote_docker_engine/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220718114551_remote_docker_engine/migration.sql diff --git a/apps/server/prisma/migrations/20220721084020_ssh_key/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220721084020_ssh_key/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220721084020_ssh_key/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220721084020_ssh_key/migration.sql diff --git a/apps/server/prisma/migrations/20220722203927_ipaddress/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220722203927_ipaddress/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220722203927_ipaddress/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220722203927_ipaddress/migration.sql diff --git a/apps/server/prisma/migrations/20220725191205_architecture/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220725191205_architecture/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220725191205_architecture/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220725191205_architecture/migration.sql diff --git a/apps/server/prisma/migrations/20220726121333_fix_ssh_key/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220726121333_fix_ssh_key/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220726121333_fix_ssh_key/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220726121333_fix_ssh_key/migration.sql diff --git a/apps/server/prisma/migrations/20220806090621_fqdn_not_unique_anymore/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220806090621_fqdn_not_unique_anymore/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220806090621_fqdn_not_unique_anymore/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220806090621_fqdn_not_unique_anymore/migration.sql diff --git a/apps/server/prisma/migrations/20220806102340_rde_ssh_local_port/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220806102340_rde_ssh_local_port/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220806102340_rde_ssh_local_port/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220806102340_rde_ssh_local_port/migration.sql diff --git a/apps/server/prisma/migrations/20220815092230_glitchtip/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220815092230_glitchtip/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220815092230_glitchtip/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220815092230_glitchtip/migration.sql diff --git a/apps/server/prisma/migrations/20220815133844_appwrite/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220815133844_appwrite/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220815133844_appwrite/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220815133844_appwrite/migration.sql diff --git a/apps/server/prisma/migrations/20220816133447_bot_deployments/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220816133447_bot_deployments/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220816133447_bot_deployments/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220816133447_bot_deployments/migration.sql diff --git a/apps/server/prisma/migrations/20220817082342_custom_dns_servers/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220817082342_custom_dns_servers/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220817082342_custom_dns_servers/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220817082342_custom_dns_servers/migration.sql diff --git a/apps/server/prisma/migrations/20220818093615_public_repositories/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220818093615_public_repositories/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220818093615_public_repositories/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220818093615_public_repositories/migration.sql diff --git a/apps/server/prisma/migrations/20220823070532_service_searxng/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220823070532_service_searxng/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220823070532_service_searxng/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220823070532_service_searxng/migration.sql diff --git a/apps/server/prisma/migrations/20220825064811_concurrent_build_settings/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220825064811_concurrent_build_settings/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220825064811_concurrent_build_settings/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220825064811_concurrent_build_settings/migration.sql diff --git a/apps/server/prisma/migrations/20220825072007_build_queue_improvements/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220825072007_build_queue_improvements/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220825072007_build_queue_improvements/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220825072007_build_queue_improvements/migration.sql diff --git a/apps/server/prisma/migrations/20220831095714_service_weblate/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220831095714_service_weblate/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220831095714_service_weblate/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220831095714_service_weblate/migration.sql diff --git a/apps/server/prisma/migrations/20220902115640_service_taiga/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220902115640_service_taiga/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220902115640_service_taiga/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220902115640_service_taiga/migration.sql diff --git a/apps/server/prisma/migrations/20220905062318_database_branching/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220905062318_database_branching/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220905062318_database_branching/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220905062318_database_branching/migration.sql diff --git a/apps/server/prisma/migrations/20220905113241_prisma_migration/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220905113241_prisma_migration/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220905113241_prisma_migration/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220905113241_prisma_migration/migration.sql diff --git a/apps/server/prisma/migrations/20220905115321_application_connected_database/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220905115321_application_connected_database/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220905115321_application_connected_database/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220905115321_application_connected_database/migration.sql diff --git a/apps/server/prisma/migrations/20220906120112_enable_api_debug_logging/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220906120112_enable_api_debug_logging/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220906120112_enable_api_debug_logging/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220906120112_enable_api_debug_logging/migration.sql diff --git a/apps/server/prisma/migrations/20220907092244_database_secrets/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220907092244_database_secrets/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220907092244_database_secrets/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220907092244_database_secrets/migration.sql diff --git a/apps/server/prisma/migrations/20220913092100_preview_applications/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220913092100_preview_applications/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220913092100_preview_applications/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220913092100_preview_applications/migration.sql diff --git a/apps/server/prisma/migrations/20220922064605_custom_certificates/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220922064605_custom_certificates/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220922064605_custom_certificates/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220922064605_custom_certificates/migration.sql diff --git a/apps/server/prisma/migrations/20220923122227_custom_ssl_for_applications/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220923122227_custom_ssl_for_applications/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220923122227_custom_ssl_for_applications/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220923122227_custom_ssl_for_applications/migration.sql diff --git a/apps/server/prisma/migrations/20220928083348_system_wide_git_sources/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20220928083348_system_wide_git_sources/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20220928083348_system_wide_git_sources/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20220928083348_system_wide_git_sources/migration.sql diff --git a/apps/server/prisma/migrations/20221002084246_no_unique_appid_on_previews/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221002084246_no_unique_appid_on_previews/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221002084246_no_unique_appid_on_previews/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221002084246_no_unique_appid_on_previews/migration.sql diff --git a/apps/server/prisma/migrations/20221002091630_forked_previews/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221002091630_forked_previews/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221002091630_forked_previews/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221002091630_forked_previews/migration.sql diff --git a/apps/server/prisma/migrations/20221005120323_initial_docker_compose/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221005120323_initial_docker_compose/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221005120323_initial_docker_compose/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221005120323_initial_docker_compose/migration.sql diff --git a/apps/server/prisma/migrations/20221005132352_docker_compose_configuration/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221005132352_docker_compose_configuration/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221005132352_docker_compose_configuration/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221005132352_docker_compose_configuration/migration.sql diff --git a/apps/server/prisma/migrations/20221017134342_standardized_service_configs/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221017134342_standardized_service_configs/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221017134342_standardized_service_configs/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221017134342_standardized_service_configs/migration.sql diff --git a/apps/server/prisma/migrations/20221018090939_service_peristent_volumes_predefined/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221018090939_service_peristent_volumes_predefined/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221018090939_service_peristent_volumes_predefined/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221018090939_service_peristent_volumes_predefined/migration.sql diff --git a/apps/server/prisma/migrations/20221021112429_serivce_settings_extended/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221021112429_serivce_settings_extended/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221021112429_serivce_settings_extended/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221021112429_serivce_settings_extended/migration.sql diff --git a/apps/server/prisma/migrations/20221021185630_service_template_version/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221021185630_service_template_version/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221021185630_service_template_version/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221021185630_service_template_version/migration.sql diff --git a/apps/server/prisma/migrations/20221026115123_service_persistent_unique/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221026115123_service_persistent_unique/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221026115123_service_persistent_unique/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221026115123_service_persistent_unique/migration.sql diff --git a/apps/server/prisma/migrations/20221028074301_wordpress_optional_fields/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221028074301_wordpress_optional_fields/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221028074301_wordpress_optional_fields/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221028074301_wordpress_optional_fields/migration.sql diff --git a/apps/server/prisma/migrations/20221104092223_default_redirect_proxy/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221104092223_default_redirect_proxy/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221104092223_default_redirect_proxy/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221104092223_default_redirect_proxy/migration.sql diff --git a/apps/server/prisma/migrations/20221114093217_application_storage_path_migration/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221114093217_application_storage_path_migration/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221114093217_application_storage_path_migration/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221114093217_application_storage_path_migration/migration.sql diff --git a/apps/server/prisma/migrations/20221123122143_remote_haproxy_from_db/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221123122143_remote_haproxy_from_db/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221123122143_remote_haproxy_from_db/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221123122143_remote_haproxy_from_db/migration.sql diff --git a/apps/server/prisma/migrations/20221123133429_docker_registries/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221123133429_docker_registries/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221123133429_docker_registries/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221123133429_docker_registries/migration.sql diff --git a/apps/server/prisma/migrations/20221128104158_do_not_track/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221128104158_do_not_track/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221128104158_do_not_track/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221128104158_do_not_track/migration.sql diff --git a/apps/server/prisma/migrations/20221128104718_fix_defaults/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221128104718_fix_defaults/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221128104718_fix_defaults/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221128104718_fix_defaults/migration.sql diff --git a/apps/server/prisma/migrations/20221128105615_custom_sentry/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221128105615_custom_sentry/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221128105615_custom_sentry/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221128105615_custom_sentry/migration.sql diff --git a/apps/server/prisma/migrations/20221129081832_fix_defaults/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221129081832_fix_defaults/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221129081832_fix_defaults/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221129081832_fix_defaults/migration.sql diff --git a/apps/server/prisma/migrations/20221129121702_preview_separator/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221129121702_preview_separator/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221129121702_preview_separator/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221129121702_preview_separator/migration.sql diff --git a/apps/server/prisma/migrations/20221129130036_keep_local_docker_images/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221129130036_keep_local_docker_images/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221129130036_keep_local_docker_images/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221129130036_keep_local_docker_images/migration.sql diff --git a/apps/server/prisma/migrations/20221130142058_reconfigure_docker_registries/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221130142058_reconfigure_docker_registries/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221130142058_reconfigure_docker_registries/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221130142058_reconfigure_docker_registries/migration.sql diff --git a/apps/server/prisma/migrations/20221201115801_simple_dockerfile_deployment/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221201115801_simple_dockerfile_deployment/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221201115801_simple_dockerfile_deployment/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221201115801_simple_dockerfile_deployment/migration.sql diff --git a/apps/server/prisma/migrations/20221201133847_push_image_to_docker_registry/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20221201133847_push_image_to_docker_registry/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20221201133847_push_image_to_docker_registry/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20221201133847_push_image_to_docker_registry/migration.sql diff --git a/apps/server/prisma/migrations/20230117092356_http2_protocol/migration.sql b/apps/trpc-experimental/server/prisma/migrations/20230117092356_http2_protocol/migration.sql similarity index 100% rename from apps/server/prisma/migrations/20230117092356_http2_protocol/migration.sql rename to apps/trpc-experimental/server/prisma/migrations/20230117092356_http2_protocol/migration.sql diff --git a/apps/server/prisma/migrations/migration_lock.toml b/apps/trpc-experimental/server/prisma/migrations/migration_lock.toml similarity index 100% rename from apps/server/prisma/migrations/migration_lock.toml rename to apps/trpc-experimental/server/prisma/migrations/migration_lock.toml diff --git a/apps/server/prisma/schema.prisma b/apps/trpc-experimental/server/prisma/schema.prisma similarity index 100% rename from apps/server/prisma/schema.prisma rename to apps/trpc-experimental/server/prisma/schema.prisma diff --git a/apps/server/prisma/seed.js b/apps/trpc-experimental/server/prisma/seed.js similarity index 100% rename from apps/server/prisma/seed.js rename to apps/trpc-experimental/server/prisma/seed.js diff --git a/apps/server/src/api/index.ts b/apps/trpc-experimental/server/src/api/index.ts similarity index 100% rename from apps/server/src/api/index.ts rename to apps/trpc-experimental/server/src/api/index.ts diff --git a/apps/server/src/config.ts b/apps/trpc-experimental/server/src/config.ts similarity index 100% rename from apps/server/src/config.ts rename to apps/trpc-experimental/server/src/config.ts diff --git a/apps/server/src/env.js b/apps/trpc-experimental/server/src/env.js similarity index 100% rename from apps/server/src/env.js rename to apps/trpc-experimental/server/src/env.js diff --git a/apps/server/src/index.ts b/apps/trpc-experimental/server/src/index.ts similarity index 100% rename from apps/server/src/index.ts rename to apps/trpc-experimental/server/src/index.ts diff --git a/apps/server/src/jobs/applicationBuildQueue.ts b/apps/trpc-experimental/server/src/jobs/applicationBuildQueue.ts similarity index 100% rename from apps/server/src/jobs/applicationBuildQueue.ts rename to apps/trpc-experimental/server/src/jobs/applicationBuildQueue.ts diff --git a/apps/server/src/lib/buildPacks/common.ts b/apps/trpc-experimental/server/src/lib/buildPacks/common.ts similarity index 100% rename from apps/server/src/lib/buildPacks/common.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/common.ts diff --git a/apps/server/src/lib/buildPacks/compose.ts b/apps/trpc-experimental/server/src/lib/buildPacks/compose.ts similarity index 100% rename from apps/server/src/lib/buildPacks/compose.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/compose.ts diff --git a/apps/server/src/lib/buildPacks/deno.ts b/apps/trpc-experimental/server/src/lib/buildPacks/deno.ts similarity index 100% rename from apps/server/src/lib/buildPacks/deno.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/deno.ts diff --git a/apps/server/src/lib/buildPacks/docker.ts b/apps/trpc-experimental/server/src/lib/buildPacks/docker.ts similarity index 100% rename from apps/server/src/lib/buildPacks/docker.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/docker.ts diff --git a/apps/server/src/lib/buildPacks/gatsby.ts b/apps/trpc-experimental/server/src/lib/buildPacks/gatsby.ts similarity index 100% rename from apps/server/src/lib/buildPacks/gatsby.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/gatsby.ts diff --git a/apps/server/src/lib/buildPacks/heroku.ts b/apps/trpc-experimental/server/src/lib/buildPacks/heroku.ts similarity index 100% rename from apps/server/src/lib/buildPacks/heroku.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/heroku.ts diff --git a/apps/server/src/lib/buildPacks/index.ts b/apps/trpc-experimental/server/src/lib/buildPacks/index.ts similarity index 100% rename from apps/server/src/lib/buildPacks/index.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/index.ts diff --git a/apps/server/src/lib/buildPacks/laravel.ts b/apps/trpc-experimental/server/src/lib/buildPacks/laravel.ts similarity index 100% rename from apps/server/src/lib/buildPacks/laravel.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/laravel.ts diff --git a/apps/server/src/lib/buildPacks/nestjs.ts b/apps/trpc-experimental/server/src/lib/buildPacks/nestjs.ts similarity index 100% rename from apps/server/src/lib/buildPacks/nestjs.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/nestjs.ts diff --git a/apps/server/src/lib/buildPacks/nextjs.ts b/apps/trpc-experimental/server/src/lib/buildPacks/nextjs.ts similarity index 100% rename from apps/server/src/lib/buildPacks/nextjs.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/nextjs.ts diff --git a/apps/server/src/lib/buildPacks/node.ts b/apps/trpc-experimental/server/src/lib/buildPacks/node.ts similarity index 100% rename from apps/server/src/lib/buildPacks/node.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/node.ts diff --git a/apps/server/src/lib/buildPacks/nuxtjs.ts b/apps/trpc-experimental/server/src/lib/buildPacks/nuxtjs.ts similarity index 100% rename from apps/server/src/lib/buildPacks/nuxtjs.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/nuxtjs.ts diff --git a/apps/server/src/lib/buildPacks/php.ts b/apps/trpc-experimental/server/src/lib/buildPacks/php.ts similarity index 100% rename from apps/server/src/lib/buildPacks/php.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/php.ts diff --git a/apps/server/src/lib/buildPacks/python.ts b/apps/trpc-experimental/server/src/lib/buildPacks/python.ts similarity index 100% rename from apps/server/src/lib/buildPacks/python.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/python.ts diff --git a/apps/server/src/lib/buildPacks/react.ts b/apps/trpc-experimental/server/src/lib/buildPacks/react.ts similarity index 100% rename from apps/server/src/lib/buildPacks/react.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/react.ts diff --git a/apps/server/src/lib/buildPacks/rust.ts b/apps/trpc-experimental/server/src/lib/buildPacks/rust.ts similarity index 100% rename from apps/server/src/lib/buildPacks/rust.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/rust.ts diff --git a/apps/server/src/lib/buildPacks/static.ts b/apps/trpc-experimental/server/src/lib/buildPacks/static.ts similarity index 100% rename from apps/server/src/lib/buildPacks/static.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/static.ts diff --git a/apps/server/src/lib/buildPacks/svelte.ts b/apps/trpc-experimental/server/src/lib/buildPacks/svelte.ts similarity index 100% rename from apps/server/src/lib/buildPacks/svelte.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/svelte.ts diff --git a/apps/server/src/lib/buildPacks/vuejs.ts b/apps/trpc-experimental/server/src/lib/buildPacks/vuejs.ts similarity index 100% rename from apps/server/src/lib/buildPacks/vuejs.ts rename to apps/trpc-experimental/server/src/lib/buildPacks/vuejs.ts diff --git a/apps/server/src/lib/common.ts b/apps/trpc-experimental/server/src/lib/common.ts similarity index 100% rename from apps/server/src/lib/common.ts rename to apps/trpc-experimental/server/src/lib/common.ts diff --git a/apps/server/src/lib/dayjs.ts b/apps/trpc-experimental/server/src/lib/dayjs.ts similarity index 100% rename from apps/server/src/lib/dayjs.ts rename to apps/trpc-experimental/server/src/lib/dayjs.ts diff --git a/apps/server/src/lib/docker.ts b/apps/trpc-experimental/server/src/lib/docker.ts similarity index 100% rename from apps/server/src/lib/docker.ts rename to apps/trpc-experimental/server/src/lib/docker.ts diff --git a/apps/server/src/lib/executeCommand.ts b/apps/trpc-experimental/server/src/lib/executeCommand.ts similarity index 100% rename from apps/server/src/lib/executeCommand.ts rename to apps/trpc-experimental/server/src/lib/executeCommand.ts diff --git a/apps/server/src/lib/importers/github.ts b/apps/trpc-experimental/server/src/lib/importers/github.ts similarity index 100% rename from apps/server/src/lib/importers/github.ts rename to apps/trpc-experimental/server/src/lib/importers/github.ts diff --git a/apps/server/src/lib/importers/gitlab.ts b/apps/trpc-experimental/server/src/lib/importers/gitlab.ts similarity index 100% rename from apps/server/src/lib/importers/gitlab.ts rename to apps/trpc-experimental/server/src/lib/importers/gitlab.ts diff --git a/apps/server/src/lib/importers/index.ts b/apps/trpc-experimental/server/src/lib/importers/index.ts similarity index 100% rename from apps/server/src/lib/importers/index.ts rename to apps/trpc-experimental/server/src/lib/importers/index.ts diff --git a/apps/server/src/lib/logging.ts b/apps/trpc-experimental/server/src/lib/logging.ts similarity index 100% rename from apps/server/src/lib/logging.ts rename to apps/trpc-experimental/server/src/lib/logging.ts diff --git a/apps/server/src/lib/ssh.ts b/apps/trpc-experimental/server/src/lib/ssh.ts similarity index 100% rename from apps/server/src/lib/ssh.ts rename to apps/trpc-experimental/server/src/lib/ssh.ts diff --git a/apps/server/src/prisma.ts b/apps/trpc-experimental/server/src/prisma.ts similarity index 100% rename from apps/server/src/prisma.ts rename to apps/trpc-experimental/server/src/prisma.ts diff --git a/apps/server/src/scheduler.ts b/apps/trpc-experimental/server/src/scheduler.ts similarity index 100% rename from apps/server/src/scheduler.ts rename to apps/trpc-experimental/server/src/scheduler.ts diff --git a/apps/server/src/server.ts b/apps/trpc-experimental/server/src/server.ts similarity index 100% rename from apps/server/src/server.ts rename to apps/trpc-experimental/server/src/server.ts diff --git a/apps/server/src/tags.json b/apps/trpc-experimental/server/src/tags.json similarity index 100% rename from apps/server/src/tags.json rename to apps/trpc-experimental/server/src/tags.json diff --git a/apps/server/src/templates.json b/apps/trpc-experimental/server/src/templates.json similarity index 100% rename from apps/server/src/templates.json rename to apps/trpc-experimental/server/src/templates.json diff --git a/apps/server/src/trpc/context.ts b/apps/trpc-experimental/server/src/trpc/context.ts similarity index 100% rename from apps/server/src/trpc/context.ts rename to apps/trpc-experimental/server/src/trpc/context.ts diff --git a/apps/server/src/trpc/index.ts b/apps/trpc-experimental/server/src/trpc/index.ts similarity index 100% rename from apps/server/src/trpc/index.ts rename to apps/trpc-experimental/server/src/trpc/index.ts diff --git a/apps/server/src/trpc/routers/applications/index.ts b/apps/trpc-experimental/server/src/trpc/routers/applications/index.ts similarity index 100% rename from apps/server/src/trpc/routers/applications/index.ts rename to apps/trpc-experimental/server/src/trpc/routers/applications/index.ts diff --git a/apps/server/src/trpc/routers/applications/lib.ts b/apps/trpc-experimental/server/src/trpc/routers/applications/lib.ts similarity index 100% rename from apps/server/src/trpc/routers/applications/lib.ts rename to apps/trpc-experimental/server/src/trpc/routers/applications/lib.ts diff --git a/apps/server/src/trpc/routers/auth.ts b/apps/trpc-experimental/server/src/trpc/routers/auth.ts similarity index 100% rename from apps/server/src/trpc/routers/auth.ts rename to apps/trpc-experimental/server/src/trpc/routers/auth.ts diff --git a/apps/server/src/trpc/routers/dashboard.ts b/apps/trpc-experimental/server/src/trpc/routers/dashboard.ts similarity index 100% rename from apps/server/src/trpc/routers/dashboard.ts rename to apps/trpc-experimental/server/src/trpc/routers/dashboard.ts diff --git a/apps/server/src/trpc/routers/databases/index.ts b/apps/trpc-experimental/server/src/trpc/routers/databases/index.ts similarity index 100% rename from apps/server/src/trpc/routers/databases/index.ts rename to apps/trpc-experimental/server/src/trpc/routers/databases/index.ts diff --git a/apps/server/src/trpc/routers/databases/lib.ts b/apps/trpc-experimental/server/src/trpc/routers/databases/lib.ts similarity index 100% rename from apps/server/src/trpc/routers/databases/lib.ts rename to apps/trpc-experimental/server/src/trpc/routers/databases/lib.ts diff --git a/apps/server/src/trpc/routers/destinations/index.ts b/apps/trpc-experimental/server/src/trpc/routers/destinations/index.ts similarity index 100% rename from apps/server/src/trpc/routers/destinations/index.ts rename to apps/trpc-experimental/server/src/trpc/routers/destinations/index.ts diff --git a/apps/server/src/trpc/routers/index.ts b/apps/trpc-experimental/server/src/trpc/routers/index.ts similarity index 100% rename from apps/server/src/trpc/routers/index.ts rename to apps/trpc-experimental/server/src/trpc/routers/index.ts diff --git a/apps/server/src/trpc/routers/services/index.ts b/apps/trpc-experimental/server/src/trpc/routers/services/index.ts similarity index 100% rename from apps/server/src/trpc/routers/services/index.ts rename to apps/trpc-experimental/server/src/trpc/routers/services/index.ts diff --git a/apps/server/src/trpc/routers/services/lib.ts b/apps/trpc-experimental/server/src/trpc/routers/services/lib.ts similarity index 100% rename from apps/server/src/trpc/routers/services/lib.ts rename to apps/trpc-experimental/server/src/trpc/routers/services/lib.ts diff --git a/apps/server/src/trpc/routers/settings.ts b/apps/trpc-experimental/server/src/trpc/routers/settings.ts similarity index 100% rename from apps/server/src/trpc/routers/settings.ts rename to apps/trpc-experimental/server/src/trpc/routers/settings.ts diff --git a/apps/server/src/trpc/routers/sources/index.ts b/apps/trpc-experimental/server/src/trpc/routers/sources/index.ts similarity index 100% rename from apps/server/src/trpc/routers/sources/index.ts rename to apps/trpc-experimental/server/src/trpc/routers/sources/index.ts diff --git a/apps/server/src/trpc/trpc.ts b/apps/trpc-experimental/server/src/trpc/trpc.ts similarity index 100% rename from apps/server/src/trpc/trpc.ts rename to apps/trpc-experimental/server/src/trpc/trpc.ts diff --git a/apps/server/tags.json b/apps/trpc-experimental/server/tags.json similarity index 100% rename from apps/server/tags.json rename to apps/trpc-experimental/server/tags.json diff --git a/apps/server/templates.json b/apps/trpc-experimental/server/templates.json similarity index 100% rename from apps/server/templates.json rename to apps/trpc-experimental/server/templates.json diff --git a/apps/server/tsconfig.json b/apps/trpc-experimental/server/tsconfig.json similarity index 100% rename from apps/server/tsconfig.json rename to apps/trpc-experimental/server/tsconfig.json