WIP better automatic proxy conf

This commit is contained in:
Andras Bacsai 2022-03-01 00:08:54 +01:00
parent 2daa043840
commit 69d1556a1d
6 changed files with 528 additions and 391 deletions

View File

@ -74,6 +74,7 @@
"js-cookie": "3.0.1",
"js-yaml": "4.1.0",
"jsonwebtoken": "8.5.1",
"mustache": "^4.2.0",
"node-forge": "1.2.1",
"svelte-kit-cookie-session": "2.1.2",
"tailwindcss-scrollbar": "^0.1.0",

10
pnpm-lock.yaml generated
View File

@ -35,6 +35,7 @@ specifiers:
js-yaml: 4.1.0
jsonwebtoken: 8.5.1
lint-staged: 12.3.4
mustache: ^4.2.0
node-forge: 1.2.1
postcss: 8.4.6
prettier: 2.5.1
@ -70,6 +71,7 @@ dependencies:
js-cookie: 3.0.1
js-yaml: 4.1.0
jsonwebtoken: 8.5.1
mustache: 4.2.0
node-forge: 1.2.1
svelte-kit-cookie-session: 2.1.2
tailwindcss-scrollbar: 0.1.0_tailwindcss@3.0.23
@ -4091,6 +4093,14 @@ packages:
msgpackr-extract: 1.0.15
dev: false
/mustache/4.2.0:
resolution:
{
integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==
}
hasBin: true
dev: false
/nan/2.15.0:
resolution:
{

View File

@ -16,6 +16,7 @@ model Setting {
maxPort Int @default(9100)
proxyPassword String
proxyUser String
proxyHash String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

View File

@ -0,0 +1,130 @@
import { dev } from '$app/env';
import got from 'got';
import mustache from 'mustache';
import crypto from 'crypto';
import * as db from '$lib/database';
import { checkContainer, checkHAProxy } from '.';
import { getDomain } from '$lib/common';
const url = dev ? 'http://localhost:5555' : 'http://coolify-haproxy:5555';
let template = `#coolhash={{hash}}
program api
command /usr/bin/dataplaneapi -f /usr/local/etc/haproxy/dataplaneapi.hcl --userlist haproxy-dataplaneapi
no option start-on-reload
global
stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin expose-fd listeners
log stdout format raw local0 debug
defaults
mode http
log global
timeout http-request 60s
timeout connect 10s
timeout client 60s
timeout server 60s
userlist haproxy-dataplaneapi
user admin insecure-password "\${HAPROXY_PASSWORD}"
frontend http
mode http
bind :80
bind :443 ssl crt /usr/local/etc/haproxy/ssl/ alpn h2,http/1.1
acl is_certbot path_beg /.well-known/acme-challenge/
{{#applications}}
{{#isHttps}}
http-request redirect scheme https code ${
dev ? 302 : 301
} if { hdr(host) -i {{domain}} } !{ ssl_fc }
{{/isHttps}}
http-request redirect location {{{redirectValue}}} code ${
dev ? 302 : 301
} if { req.hdr(host) -i {{redirectTo}} }
{{/applications}}
use_backend backend-certbot if is_certbot
use_backend %[req.hdr(host),lower]
frontend stats
bind *:8404
stats enable
stats uri /
stats refresh 5s
stats admin if TRUE
stats auth "\${HAPROXY_USERNAME}:\${HAPROXY_PASSWORD}"
backend backend-certbot
mode http
server certbot host.docker.internal:9080
{{#applications}}
backend {{domain}}
option forwardfor
server {{id}} {{id}}:{{port}}
{{/applications}}
`;
export async function haproxyInstance() {
const { proxyPassword } = await db.listSettings();
return got.extend({
prefixUrl: url,
username: 'admin',
password: proxyPassword
});
}
export async function configureHAProxy() {
const haproxy = await haproxyInstance();
await checkHAProxy(haproxy);
const data = {
applications: [],
services: []
};
const applications = await db.prisma.application.findMany({
include: { destinationDocker: true }
});
for (const application of applications) {
const {
fqdn,
id,
port,
destinationDocker: { engine }
} = application;
const isRunning = await checkContainer(engine, id);
if (isRunning) {
const domain = getDomain(fqdn);
const isHttps = fqdn.startsWith('https://');
const isWWW = fqdn.includes('www.');
const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`;
data.applications.push({
id,
port,
domain,
isHttps,
redirectValue,
redirectTo: isWWW ? domain : 'www.' + domain
});
}
}
const output = mustache.render(template, data);
const newHash = crypto.createHash('md5').update(JSON.stringify(template)).digest('hex');
const { proxyHash, id } = await db.listSettings();
console.log(proxyHash, newHash);
if (proxyHash !== newHash) {
await db.prisma.setting.update({ where: { id }, data: { proxyHash: newHash } });
console.log('HAProxy configuration changed, updating...');
await haproxy.post(`v2/services/haproxy/configuration/raw`, {
searchParams: {
skip_version: true
},
body: output,
headers: {
'Content-Type': 'text/plain'
}
});
} else {
console.log('HAProxy configuration is up to date');
}
}

View File

@ -214,306 +214,306 @@ export async function checkProxyConfigurations() {
console.log(error.response.body);
}
}
export async function configureHAProxy(
haproxy,
transactionId,
fqdn,
id,
port,
containerRunning,
engine
) {
const domain = getDomain(fqdn);
const isHttps = fqdn.startsWith('https://');
const isWWW = fqdn.includes('www.');
const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`;
const contTest = `{ req.hdr(host) -i ${isWWW ? domain.replace('www.', '') : `www.${domain}`} }`;
// export async function configureHAProxy(
// haproxy,
// transactionId,
// fqdn,
// id,
// port,
// containerRunning,
// engine
// ) {
// const domain = getDomain(fqdn);
// const isHttps = fqdn.startsWith('https://');
// const isWWW = fqdn.includes('www.');
// const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`;
// const contTest = `{ req.hdr(host) -i ${isWWW ? domain.replace('www.', '') : `www.${domain}`} }`;
// console.log({ fqdn, domain, id, port, containerRunning, isHttps, isWWW });
// // console.log({ fqdn, domain, id, port, containerRunning, isHttps, isWWW });
if (!containerRunning) {
try {
await haproxy.get(`v2/services/haproxy/configuration/backends/${domain}`).json();
console.log('removing', domain);
transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/backends/${domain}`, {
searchParams: {
transaction_id: transactionId
}
})
.json();
} catch (error) {
if (error?.response?.body) {
const json = JSON.parse(error.response.body);
if (json.code === 400 && json.message.includes('could not resolve address')) {
await stopCoolifyProxy(engine);
await startCoolifyProxy(engine);
}
}
//
}
try {
let rules: any;
// Force SSL off
rules = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
if (rules.data.length > 0) {
const rule = rules.data.find((rule) =>
rule.cond_test.includes(`{ hdr(host) -i ${domain} } !{ ssl_fc }`)
);
if (rule) {
if (!transactionId) transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/http_request_rules/${rule.index}`, {
searchParams: {
transaction_id: transactionId,
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
}
}
// if (!containerRunning) {
// try {
// await haproxy.get(`v2/services/haproxy/configuration/backends/${domain}`).json();
// console.log('removing', domain);
// transactionId = await getNextTransactionId();
// await haproxy
// .delete(`v2/services/haproxy/configuration/backends/${domain}`, {
// searchParams: {
// transaction_id: transactionId
// }
// })
// .json();
// } catch (error) {
// if (error?.response?.body) {
// const json = JSON.parse(error.response.body);
// if (json.code === 400 && json.message.includes('could not resolve address')) {
// await stopCoolifyProxy(engine);
// await startCoolifyProxy(engine);
// }
// }
// //
// }
// try {
// let rules: any;
// // Force SSL off
// rules = await haproxy
// .get(`v2/services/haproxy/configuration/http_request_rules`, {
// searchParams: {
// parent_name: 'http',
// parent_type: 'frontend'
// }
// })
// .json();
// if (rules.data.length > 0) {
// const rule = rules.data.find((rule) =>
// rule.cond_test.includes(`{ hdr(host) -i ${domain} } !{ ssl_fc }`)
// );
// if (rule) {
// if (!transactionId) transactionId = await getNextTransactionId();
// await haproxy
// .delete(`v2/services/haproxy/configuration/http_request_rules/${rule.index}`, {
// searchParams: {
// transaction_id: transactionId,
// parent_name: 'http',
// parent_type: 'frontend'
// }
// })
// .json();
// }
// }
// Force WWW off
rules = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
if (rules.data.length > 0) {
const rule = rules.data.find((rule) => rule.redir_value.includes(redirectValue));
if (rule) {
if (!transactionId) transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/http_request_rules/${rule.index}`, {
searchParams: {
transaction_id: transactionId,
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
}
}
} catch (error) {
console.log(error);
//
} finally {
try {
if (transactionId) return transactionId;
} catch (error) {
if (error?.response?.body) {
const json = JSON.parse(error.response.body);
if (json.code === 400 && json.message.includes('could not resolve address')) {
await stopCoolifyProxy(engine);
await startCoolifyProxy(engine);
}
}
}
}
return;
} else {
let serverConfigured = false;
let backendAvailable: any = null;
try {
backendAvailable = await haproxy
.get(`v2/services/haproxy/configuration/backends/${domain}`)
.json();
const server: any = await haproxy
.get(`v2/services/haproxy/configuration/servers/${id}`, {
searchParams: {
backend: domain
}
})
.json();
// // Force WWW off
// rules = await haproxy
// .get(`v2/services/haproxy/configuration/http_request_rules`, {
// searchParams: {
// parent_name: 'http',
// parent_type: 'frontend'
// }
// })
// .json();
// if (rules.data.length > 0) {
// const rule = rules.data.find((rule) => rule.redir_value.includes(redirectValue));
// if (rule) {
// if (!transactionId) transactionId = await getNextTransactionId();
// await haproxy
// .delete(`v2/services/haproxy/configuration/http_request_rules/${rule.index}`, {
// searchParams: {
// transaction_id: transactionId,
// parent_name: 'http',
// parent_type: 'frontend'
// }
// })
// .json();
// }
// }
// } catch (error) {
// console.log(error);
// //
// } finally {
// try {
// if (transactionId) return transactionId;
// } catch (error) {
// if (error?.response?.body) {
// const json = JSON.parse(error.response.body);
// if (json.code === 400 && json.message.includes('could not resolve address')) {
// await stopCoolifyProxy(engine);
// await startCoolifyProxy(engine);
// }
// }
// }
// }
// return;
// } else {
// let serverConfigured = false;
// let backendAvailable: any = null;
// try {
// backendAvailable = await haproxy
// .get(`v2/services/haproxy/configuration/backends/${domain}`)
// .json();
// const server: any = await haproxy
// .get(`v2/services/haproxy/configuration/servers/${id}`, {
// searchParams: {
// backend: domain
// }
// })
// .json();
if (backendAvailable && server) {
// Very sophisticated way to check if the server is already configured in proxy
if (backendAvailable.data.forwardfor.enabled === 'enabled') {
if (backendAvailable.data.name === domain) {
if (server.data.check === 'disabled') {
if (server.data.address === id) {
if (server.data.port === port) {
serverConfigured = true;
}
}
}
}
}
}
} catch (error) {
//
console.log(error);
}
if (serverConfigured) {
console.log('server configured', domain);
return;
}
// if (backendAvailable && server) {
// // Very sophisticated way to check if the server is already configured in proxy
// if (backendAvailable.data.forwardfor.enabled === 'enabled') {
// if (backendAvailable.data.name === domain) {
// if (server.data.check === 'disabled') {
// if (server.data.address === id) {
// if (server.data.port === port) {
// serverConfigured = true;
// }
// }
// }
// }
// }
// }
// } catch (error) {
// //
// console.log(error);
// }
// if (serverConfigured) {
// console.log('server configured', domain);
// return;
// }
if (backendAvailable) {
if (!transactionId) transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/backends/${domain}`, {
searchParams: {
transaction_id: transactionId
}
})
.json();
}
try {
console.log('adding ', domain);
if (!transactionId) transactionId = await getNextTransactionId();
await haproxy.post('v2/services/haproxy/configuration/backends', {
searchParams: {
transaction_id: transactionId
},
json: {
'init-addr': 'last,libc,none',
forwardfor: { enabled: 'enabled' },
name: domain
}
});
await haproxy.post('v2/services/haproxy/configuration/servers', {
searchParams: {
transaction_id: transactionId,
backend: domain
},
json: {
address: id,
check: 'disabled',
name: id,
port: port
}
});
let rules: any;
// if (backendAvailable) {
// if (!transactionId) transactionId = await getNextTransactionId();
// await haproxy
// .delete(`v2/services/haproxy/configuration/backends/${domain}`, {
// searchParams: {
// transaction_id: transactionId
// }
// })
// .json();
// }
// try {
// console.log('adding ', domain);
// if (!transactionId) transactionId = await getNextTransactionId();
// await haproxy.post('v2/services/haproxy/configuration/backends', {
// searchParams: {
// transaction_id: transactionId
// },
// json: {
// 'init-addr': 'last,libc,none',
// forwardfor: { enabled: 'enabled' },
// name: domain
// }
// });
// await haproxy.post('v2/services/haproxy/configuration/servers', {
// searchParams: {
// transaction_id: transactionId,
// backend: domain
// },
// json: {
// address: id,
// check: 'disabled',
// name: id,
// port: port
// }
// });
// let rules: any;
// Force SSL off
rules = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
if (rules.data.length > 0) {
const rule = rules.data.find((rule) =>
rule.cond_test.includes(`{ hdr(host) -i ${domain} } !{ ssl_fc }`)
);
if (rule) {
await haproxy
.delete(`v2/services/haproxy/configuration/http_request_rules/${rule.index}`, {
searchParams: {
transaction_id: transactionId,
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
}
}
// Generate SSL && force SSL on
if (isHttps) {
await letsEncrypt(domain, id, false);
rules = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
let nextRule = 0;
if (rules.data.length > 0) {
const rule = rules.data.find((rule) =>
rule.cond_test.includes(`{ hdr(host) -i ${domain} } !{ ssl_fc }`)
);
if (rule) return;
nextRule = rules.data[rules.data.length - 1].index + 1;
}
// // Force SSL off
// rules = await haproxy
// .get(`v2/services/haproxy/configuration/http_request_rules`, {
// searchParams: {
// parent_name: 'http',
// parent_type: 'frontend'
// }
// })
// .json();
// if (rules.data.length > 0) {
// const rule = rules.data.find((rule) =>
// rule.cond_test.includes(`{ hdr(host) -i ${domain} } !{ ssl_fc }`)
// );
// if (rule) {
// await haproxy
// .delete(`v2/services/haproxy/configuration/http_request_rules/${rule.index}`, {
// searchParams: {
// transaction_id: transactionId,
// parent_name: 'http',
// parent_type: 'frontend'
// }
// })
// .json();
// }
// }
// // Generate SSL && force SSL on
// if (isHttps) {
// await letsEncrypt(domain, id, false);
// rules = await haproxy
// .get(`v2/services/haproxy/configuration/http_request_rules`, {
// searchParams: {
// parent_name: 'http',
// parent_type: 'frontend'
// }
// })
// .json();
// let nextRule = 0;
// if (rules.data.length > 0) {
// const rule = rules.data.find((rule) =>
// rule.cond_test.includes(`{ hdr(host) -i ${domain} } !{ ssl_fc }`)
// );
// if (rule) return;
// nextRule = rules.data[rules.data.length - 1].index + 1;
// }
await haproxy
.post(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
transaction_id: transactionId,
parent_name: 'http',
parent_type: 'frontend'
},
json: {
index: nextRule,
cond: 'if',
cond_test: `{ hdr(host) -i ${domain} } !{ ssl_fc }`,
type: 'redirect',
redir_type: 'scheme',
redir_value: 'https',
redir_code: dev ? 302 : 301
}
})
.json();
}
// await haproxy
// .post(`v2/services/haproxy/configuration/http_request_rules`, {
// searchParams: {
// transaction_id: transactionId,
// parent_name: 'http',
// parent_type: 'frontend'
// },
// json: {
// index: nextRule,
// cond: 'if',
// cond_test: `{ hdr(host) -i ${domain} } !{ ssl_fc }`,
// type: 'redirect',
// redir_type: 'scheme',
// redir_value: 'https',
// redir_code: dev ? 302 : 301
// }
// })
// .json();
// }
// WWW redirect on
rules = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
let nextRule = 0;
if (rules.data.length > 0) {
const rule = rules.data.find((rule) => rule.redir_value.includes(redirectValue));
if (rule) return;
nextRule = rules.data[rules.data.length - 1].index + 1;
}
// // WWW redirect on
// rules = await haproxy
// .get(`v2/services/haproxy/configuration/http_request_rules`, {
// searchParams: {
// parent_name: 'http',
// parent_type: 'frontend'
// }
// })
// .json();
// let nextRule = 0;
// if (rules.data.length > 0) {
// const rule = rules.data.find((rule) => rule.redir_value.includes(redirectValue));
// if (rule) return;
// nextRule = rules.data[rules.data.length - 1].index + 1;
// }
await haproxy
.post(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
transaction_id: transactionId,
parent_name: 'http',
parent_type: 'frontend'
},
json: {
index: nextRule,
cond: 'if',
cond_test: contTest,
type: 'redirect',
redir_type: 'location',
redir_value: redirectValue,
redir_code: dev ? 302 : 301
}
})
.json();
} catch (error) {
console.log(error);
} finally {
try {
if (transactionId) return transactionId;
} catch (error) {
if (error?.response?.body) {
const json = JSON.parse(error.response.body);
if (json.code === 400 && json.message.includes('could not resolve address')) {
await stopCoolifyProxy(engine);
await startCoolifyProxy(engine);
}
}
}
}
}
}
// await haproxy
// .post(`v2/services/haproxy/configuration/http_request_rules`, {
// searchParams: {
// transaction_id: transactionId,
// parent_name: 'http',
// parent_type: 'frontend'
// },
// json: {
// index: nextRule,
// cond: 'if',
// cond_test: contTest,
// type: 'redirect',
// redir_type: 'location',
// redir_value: redirectValue,
// redir_code: dev ? 302 : 301
// }
// })
// .json();
// } catch (error) {
// console.log(error);
// } finally {
// try {
// if (transactionId) return transactionId;
// } catch (error) {
// if (error?.response?.body) {
// const json = JSON.parse(error.response.body);
// if (json.code === 400 && json.message.includes('could not resolve address')) {
// await stopCoolifyProxy(engine);
// await startCoolifyProxy(engine);
// }
// }
// }
// }
// }
// }
export async function configureCoolifyProxyOff(fqdn) {
const domain = getDomain(fqdn);

View File

@ -1,109 +1,104 @@
import * as db from '$lib/database';
import { getDomain } from '$lib/common';
import {
checkContainer,
checkHAProxy,
checkProxyConfigurations,
configureCoolifyProxyOn,
configureHAProxy,
forceSSLOnApplication,
haproxyInstance,
setWwwRedirection,
startCoolifyProxy,
startHttpProxy
} from '$lib/haproxy';
import { configureHAProxy } from '$lib/haproxy/configuration';
export default async function () {
const haproxy = await haproxyInstance();
await checkHAProxy(haproxy);
let transactionId;
try {
await checkProxyConfigurations();
return await configureHAProxy();
} catch (error) {
console.log(error);
console.log(error.response.body || error);
}
try {
const applications = await db.prisma.application.findMany({
include: { destinationDocker: true }
});
// const haproxy = await haproxyInstance();
// await checkHAProxy(haproxy);
// const transactionId = await getNextTransactionId();
// let executeTransaction = {
// applications: false,
// services: false
// }
// try {
// await checkProxyConfigurations();
// } catch (error) {
// console.log(error);
// }
// try {
// const applications = await db.prisma.application.findMany({
// include: { destinationDocker: true }
// });
for (const application of applications) {
const {
fqdn,
id,
port,
destinationDocker: { engine }
} = application;
const containerRunning = await checkContainer(engine, id);
transactionId = await configureHAProxy(
haproxy,
transactionId,
fqdn,
id,
port,
containerRunning,
engine
);
}
// for (const application of applications) {
// const {
// fqdn,
// id,
// port,
// destinationDocker: { engine }
// } = application;
// const containerRunning = await checkContainer(engine, id);
// executeTransaction.applications = await configureHAProxy(
// haproxy,
// transactionId,
// fqdn,
// id,
// port,
// containerRunning,
// engine
// );
// }
const services = await db.prisma.service.findMany({
include: {
destinationDocker: true,
minio: true,
plausibleAnalytics: true,
vscodeserver: true,
wordpress: true
}
});
// const services = await db.prisma.service.findMany({
// include: {
// destinationDocker: true,
// minio: true,
// plausibleAnalytics: true,
// vscodeserver: true,
// wordpress: true
// }
// });
for (const service of services) {
const {
fqdn,
id,
type,
destinationDocker: { engine }
} = service;
console.log({ fqdn, id, type, engine });
const found = db.supportedServiceTypesAndVersions.find((a) => a.name === type);
if (found) {
console.log(found);
const port = found.ports.main;
const publicPort = service[type]?.publicPort;
const containerRunning = await checkContainer(engine, id);
console.log(containerRunning);
transactionId = await configureHAProxy(
haproxy,
transactionId,
fqdn,
id,
port,
containerRunning,
engine
);
if (publicPort) {
const containerFound = await checkContainer(
service.destinationDocker.engine,
`haproxy-for-${publicPort}`
);
if (!containerFound) {
await startHttpProxy(service.destinationDocker, id, publicPort, 9000);
}
}
}
}
console.log(transactionId);
if (transactionId) await haproxy.put(`v2/services/haproxy/transactions/${transactionId}`);
// Check Coolify FQDN and configure proxy if needed
// const { fqdn } = await db.listSettings();
// if (fqdn) {
// const domain = getDomain(fqdn);
// await startCoolifyProxy('/var/run/docker.sock');
// await configureCoolifyProxyOn(fqdn);
// await setWwwRedirection(fqdn);
// const isHttps = fqdn.startsWith('https://');
// if (isHttps) await forceSSLOnApplication(domain);
// }
} catch (error) {
throw error;
}
// for (const service of services) {
// const {
// fqdn,
// id,
// type,
// destinationDocker: { engine }
// } = service;
// const found = db.supportedServiceTypesAndVersions.find((a) => a.name === type);
// if (found) {
// console.log(found);
// const port = found.ports.main;
// const publicPort = service[type]?.publicPort;
// const containerRunning = await checkContainer(engine, id);
// executeTransaction.services = await configureHAProxy(
// haproxy,
// transactionId,
// fqdn,
// id,
// port,
// containerRunning,
// engine
// );
// if (publicPort) {
// const containerFound = await checkContainer(
// service.destinationDocker.engine,
// `haproxy-for-${publicPort}`
// );
// if (!containerFound) {
// await startHttpProxy(service.destinationDocker, id, publicPort, 9000);
// }
// }
// }
// }
// if (executeTransaction.applications || executeTransaction.services) {
// await haproxy.put(`v2/services/haproxy/transactions/${transactionId}`);
// }
// // Check Coolify FQDN and configure proxy if needed
// // const { fqdn } = await db.listSettings();
// // if (fqdn) {
// // const domain = getDomain(fqdn);
// // await startCoolifyProxy('/var/run/docker.sock');
// // await configureCoolifyProxyOn(fqdn);
// // await setWwwRedirection(fqdn);
// // const isHttps = fqdn.startsWith('https://');
// // if (isHttps) await forceSSLOnApplication(domain);
// // }
// } catch (error) {
// throw error;
// }
}