import { asyncExecShell, getEngine } from '$lib/common'; import { decrypt } from '$lib/crypto'; import { dockerInstance } from '$lib/docker'; import { startCoolifyProxy } from '$lib/haproxy'; import { getDatabaseImage } from '.'; import { prisma } from './common'; import type { DestinationDocker, Service, Application, Prisma } from '@prisma/client'; import type { CreateDockerDestination } from '$lib/types/destinations'; type DestinationConfigurationObject = { id: string; destinationId: string; }; type FindDestinationFromTeam = { id: string; teamId: string; }; export async function listDestinations(teamId: string): Promise { return await prisma.destinationDocker.findMany({ where: { teams: { some: { id: teamId } } } }); } export async function configureDestinationForService({ id, destinationId }: DestinationConfigurationObject): Promise { return await prisma.service.update({ where: { id }, data: { destinationDocker: { connect: { id: destinationId } } } }); } export async function configureDestinationForApplication({ id, destinationId }: DestinationConfigurationObject): Promise { return await prisma.application.update({ where: { id }, data: { destinationDocker: { connect: { id: destinationId } } } }); } export async function configureDestinationForDatabase({ id, destinationId }: DestinationConfigurationObject): Promise { await prisma.database.update({ where: { id }, data: { destinationDocker: { connect: { id: destinationId } } } }); const { destinationDockerId, destinationDocker: { engine }, version, type } = await prisma.database.findUnique({ where: { id }, include: { destinationDocker: true } }); if (destinationDockerId) { const host = getEngine(engine); if (type && version) { const baseImage = getDatabaseImage(type); await asyncExecShell( `DOCKER_HOST=${host} docker pull ${baseImage}:${version} && echo "FROM ${baseImage}:${version}" | docker build --label coolify.image="true" -t "${baseImage}:${version}" -` ); } } } export async function updateDestination({ id, name, engine, network }: Pick): Promise { return await prisma.destinationDocker.update({ where: { id }, data: { name, engine, network } }); } export async function newRemoteDestination({ name, teamId, engine, network, isCoolifyProxyUsed, remoteEngine }: CreateDockerDestination): Promise { const destination = await prisma.destinationDocker.create({ data: { name, teams: { connect: { id: teamId } }, engine, network, isCoolifyProxyUsed, remoteEngine } }); return destination.id; } export async function newLocalDestination({ name, teamId, engine, network, isCoolifyProxyUsed }: CreateDockerDestination): Promise { const host = getEngine(engine); const docker = dockerInstance({ destinationDocker: { engine, network } }); const found = await docker.engine.listNetworks({ filters: { name: [`^${network}$`] } }); if (found.length === 0) { await asyncExecShell(`DOCKER_HOST=${host} docker network create --attachable ${network}`); } await prisma.destinationDocker.create({ data: { name, teams: { connect: { id: teamId } }, engine, network, isCoolifyProxyUsed } }); const destinations = await prisma.destinationDocker.findMany({ where: { engine } }); const destination = destinations.find((destination) => destination.network === network); if (destinations.length > 0) { const proxyConfigured = destinations.find( (destination) => destination.network !== network && destination.isCoolifyProxyUsed === true ); if (proxyConfigured) { isCoolifyProxyUsed = !!proxyConfigured.isCoolifyProxyUsed; } await prisma.destinationDocker.updateMany({ where: { engine }, data: { isCoolifyProxyUsed } }); } if (isCoolifyProxyUsed) await startCoolifyProxy(engine); return destination.id; } export async function removeDestination({ id }: Pick): Promise { const destination = await prisma.destinationDocker.delete({ where: { id } }); if (destination.isCoolifyProxyUsed) { const host = getEngine(destination.engine); const { network } = destination; const { stdout: found } = await asyncExecShell( `DOCKER_HOST=${host} docker ps -a --filter network=${network} --filter name=coolify-haproxy --format '{{.}}'` ); if (found) { await asyncExecShell( `DOCKER_HOST="${host}" docker network disconnect ${network} coolify-haproxy` ); await asyncExecShell(`DOCKER_HOST="${host}" docker network rm ${network}`); } } } export async function getDestination({ id, teamId }: FindDestinationFromTeam): Promise { const destination = (await prisma.destinationDocker.findFirst({ where: { id, teams: { some: { id: teamId } } } })) as DestinationDocker & { sshPrivateKey?: string }; if (destination.remoteEngine) { destination.sshPrivateKey = decrypt(destination.sshPrivateKey); } return destination; } export async function getDestinationByApplicationId({ id, teamId }: FindDestinationFromTeam): Promise { return await prisma.destinationDocker.findFirst({ where: { application: { some: { id } }, teams: { some: { id: teamId } } } }); } export async function setDestinationSettings({ engine, isCoolifyProxyUsed }: { engine: string; isCoolifyProxyUsed: boolean; }): Promise { return await prisma.destinationDocker.updateMany({ where: { engine }, data: { isCoolifyProxyUsed } }); }