From 6bba37c36d2cd43e1bcc5d2520035ef8ecc54549 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 12 May 2022 13:02:14 +0200 Subject: [PATCH] WIP: Traefik?! --- docker-compose-traefik.yaml | 28 ++++++ package.json | 2 +- prisma/schema.prisma | 1 + src/lib/queues/proxyTcpHttp.ts | 5 +- src/routes/__layout.svelte | 14 +++ src/routes/traefik.json.ts | 152 +++++++++++++++++++++++++++++++++ src/routes/update.json.ts | 16 ++++ 7 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 docker-compose-traefik.yaml create mode 100644 src/routes/traefik.json.ts diff --git a/docker-compose-traefik.yaml b/docker-compose-traefik.yaml new file mode 100644 index 000000000..6d7ca2487 --- /dev/null +++ b/docker-compose-traefik.yaml @@ -0,0 +1,28 @@ +version: '3.8' + +services: + proxy: + image: traefik:v2.6 + command: + - --api.insecure=true + - --entrypoints.web.address=:80 + - --providers.docker=false + - --providers.docker.exposedbydefault=false + - --providers.http.endpoint=http://host.docker.internal:3000/traefik.json + - --providers.http.pollTimeout=5s + - --log.level=error + ports: + - '80:80' + - '443:443' + - '8080:8080' + volumes: + - /var/run/docker.sock:/var/run/docker.sock + extra_hosts: + - 'host.docker.internal:host-gateway' + networks: + - coolify-infra + +networks: + coolify-infra: + attachable: true + name: coolify-infra diff --git a/package.json b/package.json index 8648f9c47..782e43f09 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "dev:stop": "docker-compose -f docker-compose-dev.yaml down", "dev:logs": "docker-compose -f docker-compose-dev.yaml logs -f --tail 10", "studio": "npx prisma studio", - "start": "npx prisma migrate deploy && npx prisma generate && npx prisma db seed && node index.js", + "start": "npx prisma migrate deploy && npx prisma generate && npx prisma db seed && node build/index.js", "build": "svelte-kit build", "preview": "svelte-kit preview", "check": "svelte-check --tsconfig ./tsconfig.json", diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b0c2e233a..8196a6e51 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -20,6 +20,7 @@ model Setting { proxyHash String? isAutoUpdateEnabled Boolean @default(false) isDNSCheckEnabled Boolean @default(true) + disableHaproxy Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } diff --git a/src/lib/queues/proxyTcpHttp.ts b/src/lib/queues/proxyTcpHttp.ts index c268d2aa0..3d48c5c1d 100644 --- a/src/lib/queues/proxyTcpHttp.ts +++ b/src/lib/queues/proxyTcpHttp.ts @@ -6,11 +6,14 @@ export default async function (): Promise { try { + const settings = await prisma.setting.findFirst(); // Coolify Proxy const localDocker = await prisma.destinationDocker.findFirst({ where: { engine: '/var/run/docker.sock' } }); - if (localDocker && localDocker.isCoolifyProxyUsed) { + console.log(settings.disableHaproxy); + if (localDocker && localDocker.isCoolifyProxyUsed && !settings.disableHaproxy) { + console.log('asd'); await startCoolifyProxy('/var/run/docker.sock'); } // TCP Proxies diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte index d8a578c1a..0f5b481f5 100644 --- a/src/routes/__layout.svelte +++ b/src/routes/__layout.svelte @@ -124,6 +124,13 @@ return errorNotification(error); } } + async function migrateToTraefik() { + try { + await post(`/update.json`, { type: 'migrateToTraefik' }); + } catch ({ error }) { + return errorNotification(error); + } + } @@ -515,6 +522,13 @@ >Powered by Coolify {/if} + + + {/if}
diff --git a/src/routes/traefik.json.ts b/src/routes/traefik.json.ts new file mode 100644 index 000000000..ee7745c9c --- /dev/null +++ b/src/routes/traefik.json.ts @@ -0,0 +1,152 @@ +import { asyncExecShell, getDomain, getEngine } from '$lib/common'; +import * as db from '$lib/database'; +import { checkContainer } from '$lib/haproxy'; + +export const get = async () => { + const applications = await db.prisma.application.findMany({ + include: { destinationDocker: true, settings: true } + }); + const data = { + applications: [], + services: [], + coolify: [] + }; + for (const application of applications) { + const { + fqdn, + id, + port, + destinationDocker, + destinationDockerId, + settings: { previews }, + updatedAt + } = application; + if (destinationDockerId) { + const { engine, network } = destinationDocker; + const isRunning = await checkContainer(engine, id); + if (fqdn) { + const domain = getDomain(fqdn); + const isHttps = fqdn.startsWith('https://'); + const isWWW = fqdn.includes('www.'); + const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`; + if (isRunning) { + data.applications.push({ + id, + port: port || 3000, + domain, + isRunning, + isHttps, + redirectValue, + redirectTo: isWWW ? domain.replace('www.', '') : 'www.' + domain, + updatedAt: updatedAt.getTime() + }); + } + if (previews) { + const host = getEngine(engine); + const { stdout } = await asyncExecShell( + `DOCKER_HOST=${host} docker container ls --filter="status=running" --filter="network=${network}" --filter="name=${id}-" --format="{{json .Names}}"` + ); + const containers = stdout + .trim() + .split('\n') + .filter((a) => a) + .map((c) => c.replace(/"/g, '')); + if (containers.length > 0) { + for (const container of containers) { + const previewDomain = `${container.split('-')[1]}.${domain}`; + data.applications.push({ + id: container, + port: port || 3000, + domain: previewDomain, + isRunning, + isHttps, + redirectValue, + redirectTo: isWWW ? previewDomain.replace('www.', '') : 'www.' + previewDomain, + updatedAt: updatedAt.getTime() + }); + } + } + } + } + } + } + + const traefik = { + http: { + routers: {}, + services: {} + } + }; + for (const application of data.applications) { + const { id, port, domain, isHttps, redirectValue, redirectTo, updatedAt } = application; + traefik.http.routers[id] = { + entrypoints: ['web'], + rule: `Host(\`${domain}\`)`, + service: id + }; + traefik.http.services[id] = { + loadbalancer: { + servers: [ + { + url: `http://${id}:${port}` + } + ] + } + }; + } + return { + status: 200, + body: { + ...traefik + // "http": { + // "routers": { + // "coolify": { + // "entrypoints": [ + // "web" + // ], + // "middlewares": [ + // "coolify-hc" + // ], + // "rule": "Host(`staging.coolify.io`)", + // "service": "coolify" + // }, + // "static.example.coolify.io": { + // "entrypoints": [ + // "web" + // ], + // "rule": "Host(`static.example.coolify.io`)", + // "service": "static.example.coolify.io" + // } + // }, + // "services": { + // "coolify": { + // "loadbalancer": { + // "servers": [ + // { + // "url": "http://coolify:3000" + // } + // ] + // } + // }, + // "static.example.coolify.io": { + // "loadbalancer": { + // "servers": [ + // { + // "url": "http://cl32p06f58068518cs3thg6vbc7:80" + // } + // ] + // } + // } + // }, + // "middlewares": { + // "coolify-hc": { + // "replacepathregex": { + // "regex": "/dead.json", + // "replacement": "/undead.json" + // } + // } + // } + // } + } + }; +}; diff --git a/src/routes/update.json.ts b/src/routes/update.json.ts index 19845b90e..d584cde7b 100644 --- a/src/routes/update.json.ts +++ b/src/routes/update.json.ts @@ -61,6 +61,22 @@ export const post: RequestHandler = async (event) => { } catch (error) { return ErrorHandler(error); } + } else if (type === 'migrateToTraefik') { + try { + const settings = await db.prisma.setting.findFirst({}); + await db.prisma.setting.update({ + where: { id: settings.id }, + data: { disableHaproxy: true } + }); + await asyncExecShell(`docker stop -t 0 coolify-haproxy`); + await asyncExecShell(`docker rm coolify-haproxy`); + return { + status: 200, + body: {} + }; + } catch (error) { + return ErrorHandler(error); + } } return { status: 500