Added types for haproxy/configuration
This commit is contained in:
parent
51a5b3b602
commit
8a401f50cb
@ -1,9 +1,7 @@
|
|||||||
import cuid from 'cuid';
|
import cuid from 'cuid';
|
||||||
import bcrypt from 'bcrypt';
|
import bcrypt from 'bcrypt';
|
||||||
|
|
||||||
import { prisma } from './common';
|
import { prisma } from './common';
|
||||||
import { asyncExecShell, uniqueName } from '$lib/common';
|
import { asyncExecShell, uniqueName } from '$lib/common';
|
||||||
|
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { startCoolifyProxy } from '$lib/haproxy';
|
import { startCoolifyProxy } from '$lib/haproxy';
|
||||||
import type { User } from '@prisma/client';
|
import type { User } from '@prisma/client';
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import { dev } from '$app/env';
|
import { dev } from '$app/env';
|
||||||
import got from 'got';
|
import got, { type Got } from 'got';
|
||||||
import mustache from 'mustache';
|
import mustache from 'mustache';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
|
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { checkContainer, checkHAProxy } from '.';
|
import { checkContainer, checkHAProxy } from '.';
|
||||||
import { asyncExecShell, getDomain, getEngine } from '$lib/common';
|
import { asyncExecShell, getDomain, getEngine } from '$lib/common';
|
||||||
|
|
||||||
const url = dev ? 'http://localhost:5555' : 'http://coolify-haproxy:5555';
|
const url = dev ? 'http://localhost:5555' : 'http://coolify-haproxy:5555';
|
||||||
|
|
||||||
let template = `program api
|
const template = `program api
|
||||||
command /usr/bin/dataplaneapi -f /usr/local/etc/haproxy/dataplaneapi.hcl --userlist haproxy-dataplaneapi
|
command /usr/bin/dataplaneapi -f /usr/local/etc/haproxy/dataplaneapi.hcl --userlist haproxy-dataplaneapi
|
||||||
no option start-on-reload
|
no option start-on-reload
|
||||||
|
|
||||||
@ -127,7 +126,8 @@ backend {{domain}}
|
|||||||
server {{id}} {{id}}:{{port}} check fall 10
|
server {{id}} {{id}}:{{port}} check fall 10
|
||||||
{{/coolify}}
|
{{/coolify}}
|
||||||
`;
|
`;
|
||||||
export async function haproxyInstance() {
|
|
||||||
|
export async function haproxyInstance(): Promise<Got> {
|
||||||
const { proxyPassword } = await db.listSettings();
|
const { proxyPassword } = await db.listSettings();
|
||||||
return got.extend({
|
return got.extend({
|
||||||
prefixUrl: url,
|
prefixUrl: url,
|
||||||
@ -136,31 +136,96 @@ export async function haproxyInstance() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function configureHAProxy() {
|
export async function configureHAProxy(): Promise<void> {
|
||||||
const haproxy = await haproxyInstance();
|
const haproxy = await haproxyInstance();
|
||||||
await checkHAProxy(haproxy);
|
await checkHAProxy(haproxy);
|
||||||
|
|
||||||
try {
|
const data = {
|
||||||
const data = {
|
applications: [],
|
||||||
applications: [],
|
services: [],
|
||||||
services: [],
|
coolify: []
|
||||||
coolify: []
|
};
|
||||||
};
|
const applications = await db.prisma.application.findMany({
|
||||||
const applications = await db.prisma.application.findMany({
|
include: { destinationDocker: true, settings: true }
|
||||||
include: { destinationDocker: true, settings: true }
|
});
|
||||||
});
|
for (const application of applications) {
|
||||||
for (const application of applications) {
|
const {
|
||||||
const {
|
fqdn,
|
||||||
fqdn,
|
id,
|
||||||
id,
|
port,
|
||||||
port,
|
destinationDocker,
|
||||||
destinationDocker,
|
destinationDockerId,
|
||||||
destinationDockerId,
|
settings: { previews },
|
||||||
settings: { previews },
|
updatedAt
|
||||||
updatedAt
|
} = application;
|
||||||
} = application;
|
if (destinationDockerId) {
|
||||||
if (destinationDockerId) {
|
const { engine, network } = destinationDocker;
|
||||||
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 services = await db.prisma.service.findMany({
|
||||||
|
include: {
|
||||||
|
destinationDocker: true,
|
||||||
|
minio: true,
|
||||||
|
plausibleAnalytics: true,
|
||||||
|
vscodeserver: true,
|
||||||
|
wordpress: true,
|
||||||
|
ghost: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const service of services) {
|
||||||
|
const { fqdn, id, type, destinationDocker, destinationDockerId, updatedAt } = service;
|
||||||
|
if (destinationDockerId) {
|
||||||
|
const { engine } = destinationDocker;
|
||||||
|
const found = db.supportedServiceTypesAndVersions.find((a) => a.name === type);
|
||||||
|
if (found) {
|
||||||
|
const port = found.ports.main;
|
||||||
|
const publicPort = service[type]?.publicPort;
|
||||||
const isRunning = await checkContainer(engine, id);
|
const isRunning = await checkContainer(engine, id);
|
||||||
if (fqdn) {
|
if (fqdn) {
|
||||||
const domain = getDomain(fqdn);
|
const domain = getDomain(fqdn);
|
||||||
@ -168,9 +233,10 @@ export async function configureHAProxy() {
|
|||||||
const isWWW = fqdn.includes('www.');
|
const isWWW = fqdn.includes('www.');
|
||||||
const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`;
|
const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`;
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
data.applications.push({
|
data.services.push({
|
||||||
id,
|
id,
|
||||||
port: port || 3000,
|
port,
|
||||||
|
publicPort,
|
||||||
domain,
|
domain,
|
||||||
isRunning,
|
isRunning,
|
||||||
isHttps,
|
isHttps,
|
||||||
@ -179,108 +245,38 @@ export async function configureHAProxy() {
|
|||||||
updatedAt: updatedAt.getTime()
|
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) {
|
|
||||||
let 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 services = await db.prisma.service.findMany({
|
}
|
||||||
include: {
|
const { fqdn } = await db.prisma.setting.findFirst();
|
||||||
destinationDocker: true,
|
if (fqdn) {
|
||||||
minio: true,
|
const domain = getDomain(fqdn);
|
||||||
plausibleAnalytics: true,
|
const isHttps = fqdn.startsWith('https://');
|
||||||
vscodeserver: true,
|
const isWWW = fqdn.includes('www.');
|
||||||
wordpress: true,
|
const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`;
|
||||||
ghost: true
|
data.coolify.push({
|
||||||
|
id: dev ? 'host.docker.internal' : 'coolify',
|
||||||
|
port: 3000,
|
||||||
|
domain,
|
||||||
|
isHttps,
|
||||||
|
redirectValue,
|
||||||
|
redirectTo: isWWW ? domain.replace('www.', '') : 'www.' + domain
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const output = mustache.render(template, data);
|
||||||
|
const newHash = crypto.createHash('md5').update(output).digest('hex');
|
||||||
|
const { proxyHash, id } = await db.listSettings();
|
||||||
|
if (proxyHash !== newHash) {
|
||||||
|
await db.prisma.setting.update({ where: { id }, data: { proxyHash: newHash } });
|
||||||
|
await haproxy.post(`v2/services/haproxy/configuration/raw`, {
|
||||||
|
searchParams: {
|
||||||
|
skip_version: true
|
||||||
|
},
|
||||||
|
body: output,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const service of services) {
|
|
||||||
const { fqdn, id, type, destinationDocker, destinationDockerId, updatedAt } = service;
|
|
||||||
if (destinationDockerId) {
|
|
||||||
const { engine } = destinationDocker;
|
|
||||||
const found = db.supportedServiceTypesAndVersions.find((a) => a.name === type);
|
|
||||||
if (found) {
|
|
||||||
const port = found.ports.main;
|
|
||||||
const publicPort = service[type]?.publicPort;
|
|
||||||
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.services.push({
|
|
||||||
id,
|
|
||||||
port,
|
|
||||||
publicPort,
|
|
||||||
domain,
|
|
||||||
isRunning,
|
|
||||||
isHttps,
|
|
||||||
redirectValue,
|
|
||||||
redirectTo: isWWW ? domain.replace('www.', '') : 'www.' + domain,
|
|
||||||
updatedAt: updatedAt.getTime()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { fqdn } = await db.prisma.setting.findFirst();
|
|
||||||
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]`;
|
|
||||||
data.coolify.push({
|
|
||||||
id: dev ? 'host.docker.internal' : 'coolify',
|
|
||||||
port: 3000,
|
|
||||||
domain,
|
|
||||||
isHttps,
|
|
||||||
redirectValue,
|
|
||||||
redirectTo: isWWW ? domain.replace('www.', '') : 'www.' + domain
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const output = mustache.render(template, data);
|
|
||||||
const newHash = crypto.createHash('md5').update(output).digest('hex');
|
|
||||||
const { proxyHash, id } = await db.listSettings();
|
|
||||||
if (proxyHash !== newHash) {
|
|
||||||
await db.prisma.setting.update({ where: { id }, data: { proxyHash: newHash } });
|
|
||||||
await haproxy.post(`v2/services/haproxy/configuration/raw`, {
|
|
||||||
searchParams: {
|
|
||||||
skip_version: true
|
|
||||||
},
|
|
||||||
body: output,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'text/plain'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user