This commit is contained in:
Andras Bacsai
2022-02-28 16:06:44 +01:00
parent 02abd038fa
commit f340ca9d05
14 changed files with 445 additions and 320 deletions

View File

@@ -2,6 +2,7 @@ import { dev } from '$app/env';
import { asyncExecShell, getDomain, getEngine } from '$lib/common'; import { asyncExecShell, getDomain, getEngine } from '$lib/common';
import got from 'got'; import got from 'got';
import * as db from '$lib/database'; import * as db from '$lib/database';
import { letsEncrypt } from '$lib/letsencrypt';
const url = dev ? 'http://localhost:5555' : 'http://coolify-haproxy:5555'; const url = dev ? 'http://localhost:5555' : 'http://coolify-haproxy:5555';
@@ -71,7 +72,9 @@ export async function removeProxyConfiguration(fqdn) {
export async function forceSSLOffApplication(domain) { export async function forceSSLOffApplication(domain) {
const haproxy = await haproxyInstance(); const haproxy = await haproxyInstance();
await checkHAProxy(haproxy); await checkHAProxy(haproxy);
let transactionId; let transactionId;
try { try {
const rules: any = await haproxy const rules: any = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, { .get(`v2/services/haproxy/configuration/http_request_rules`, {
@@ -87,7 +90,6 @@ export async function forceSSLOffApplication(domain) {
); );
if (rule) { if (rule) {
transactionId = await getNextTransactionId(); transactionId = await getNextTransactionId();
await haproxy await haproxy
.delete(`v2/services/haproxy/configuration/http_request_rules/${rule.index}`, { .delete(`v2/services/haproxy/configuration/http_request_rules/${rule.index}`, {
searchParams: { searchParams: {
@@ -188,168 +190,325 @@ export async function reloadHaproxy(engine) {
return await asyncExecShell(`DOCKER_HOST=${host} docker exec coolify-haproxy kill -HUP 1`); return await asyncExecShell(`DOCKER_HOST=${host} docker exec coolify-haproxy kill -HUP 1`);
} }
export async function checkProxyConfigurations() { export async function checkProxyConfigurations() {
const timeout = 10;
const haproxy = await haproxyInstance(); const haproxy = await haproxyInstance();
await checkHAProxy(haproxy); await checkHAProxy(haproxy);
try { try {
const stats: any = await haproxy.get(`v2/services/haproxy/stats/native`).json(); const stats: any = await haproxy.get(`v2/services/haproxy/stats/native`).json();
let transactionId = null;
for (const stat of stats[0].stats) { for (const stat of stats[0].stats) {
if (stat.stats.status === 'DOWN' && stat.type === 'server') { if (stat.stats.status !== 'no check' && stat.type === 'server') {
const { if (!transactionId) await getNextTransactionId();
name, const { backend_name: backendName } = stat;
backend_name: backendName, await haproxy
stats: { lastchg } .delete(`v2/services/haproxy/configuration/backends/${backendName}`, {
} = stat; searchParams: {
transaction_id: transactionId
const { fqdn } = await db.listSettings(); }
if (fqdn) { })
const domain = getDomain(fqdn); .json();
if (backendName === domain) {
return;
}
}
const application = await db.prisma.application.findUnique({
where: { id: name },
include: { destinationDocker: true }
});
const service = await db.prisma.service.findUnique({
where: { id: name },
include: { destinationDocker: true }
});
if (!application && !service) {
const transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/backends/${backendName}`, {
searchParams: {
transaction_id: transactionId
}
})
.json();
return await completeTransaction(transactionId);
}
if (application?.destinationDocker?.engine && lastchg > 120) {
const found = await checkContainer(application.destinationDocker.engine, name);
if (!found) {
const transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/backends/${backendName}`, {
searchParams: {
transaction_id: transactionId
}
})
.json();
return await completeTransaction(transactionId);
}
}
if (service?.destinationDocker?.engine && lastchg > 120) {
const found = await checkContainer(service.destinationDocker.engine, name);
if (!found) {
const transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/backends/${backendName}`, {
searchParams: {
transaction_id: transactionId
}
})
.json();
return await completeTransaction(transactionId);
}
}
if (lastchg > 120) {
const transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/backends/${backendName}`, {
searchParams: {
transaction_id: transactionId
}
})
.json();
await completeTransaction(transactionId);
}
} }
} }
if (transactionId) await completeTransaction(transactionId);
} catch (error) { } catch (error) {
console.log(error); console.log(error.response.body);
} }
} }
export async function configureProxyForApplication({ domain, imageId, applicationId, port }) { export async function configureHAProxy(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({ application: true, fqdn, domain, id, port, containerRunning, isHttps, isWWW });
const haproxy = await haproxyInstance(); const haproxy = await haproxyInstance();
await checkHAProxy(haproxy); await checkHAProxy(haproxy);
let serverConfigured = false; let transactionId;
let backendAvailable: any = null;
try { if (!containerRunning) {
backendAvailable = await haproxy try {
.get(`v2/services/haproxy/configuration/backends/${domain}`) await haproxy.get(`v2/services/haproxy/configuration/backends/${domain}`).json();
.json(); transactionId = await getNextTransactionId();
const server: any = await haproxy await haproxy
.get(`v2/services/haproxy/configuration/servers/${imageId}`, { .delete(`v2/services/haproxy/configuration/backends/${domain}`, {
searchParams: { searchParams: {
backend: domain transaction_id: transactionId
}
})
.json();
} catch (error) {
//
}
try {
if (!transactionId) await getNextTransactionId();
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();
} }
}) }
.json();
if (backendAvailable && server) { // Force WWW off
// Very sophisticated way to check if the server is already configured in proxy rules = await haproxy
if (backendAvailable.data.forwardfor.enabled === 'enabled') { .get(`v2/services/haproxy/configuration/http_request_rules`, {
if (backendAvailable.data.name === domain) { searchParams: {
if (server.data.check === 'enabled') { parent_name: 'http',
if (server.data.address === imageId) { parent_type: 'frontend'
if (server.data.port === port) { }
serverConfigured = true; })
.json();
if (rules.data.length > 0) {
const rule = rules.data.find((rule) => rule.redir_value.includes(redirectValue));
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();
}
}
} catch (error) {
console.log(error);
//
} finally {
try {
if (transactionId) {
console.log(transactionId);
await haproxy.put(`v2/services/haproxy/transactions/${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 {
console.log('adding ', domain);
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) {
//
} }
} catch (error) { if (serverConfigured) {
//console.log('error getting backend or server', error?.response?.body); console.log('server configured');
// return;
} }
if (!transactionId) transactionId = await getNextTransactionId();
if (serverConfigured) return; if (backendAvailable) {
const transactionId = await getNextTransactionId(); await haproxy
if (backendAvailable) { .delete(`v2/services/haproxy/configuration/backends/${domain}`, {
await haproxy searchParams: {
.delete(`v2/services/haproxy/configuration/backends/${domain}`, { transaction_id: transactionId
}
})
.json();
}
try {
console.log('adding ', domain);
await haproxy.post('v2/services/haproxy/configuration/backends', {
searchParams: { searchParams: {
transaction_id: transactionId transaction_id: transactionId
},
json: {
'init-addr': 'last,libc,none',
forwardfor: { enabled: 'enabled' },
name: domain
} }
}) });
.json();
}
try {
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', { await haproxy.post('v2/services/haproxy/configuration/servers', {
searchParams: { searchParams: {
transaction_id: transactionId, transaction_id: transactionId,
backend: domain backend: domain
}, },
json: { json: {
address: imageId, address: id,
check: 'enabled', check: 'disabled',
name: imageId, name: id,
port: port 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();
}
} }
});
} catch (error) { // Generate SSL && force SSL on
throw error?.response?.body || error;
} finally { if (isHttps) {
await completeTransaction(transactionId); 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();
}
// 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);
throw error?.response?.body || error;
} finally {
try {
if (transactionId) {
console.log('Committing transaction');
await haproxy.put(`v2/services/haproxy/transactions/${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);
}
}
}
}
} }
} }
@@ -444,7 +603,7 @@ export async function configureCoolifyProxyOn(fqdn) {
}, },
json: { json: {
address: dev ? 'host.docker.internal' : 'coolify', address: dev ? 'host.docker.internal' : 'coolify',
check: 'enabled', check: 'enable',
fall: 10, fall: 10,
name: 'coolify', name: 'coolify',
port: 3000 port: 3000
@@ -587,6 +746,7 @@ export async function configureNetworkCoolifyProxy(engine) {
} }
export async function configureSimpleServiceProxyOn({ id, domain, port }) { export async function configureSimpleServiceProxyOn({ id, domain, port }) {
console.log({ service: true, id, domain, port });
const haproxy = await haproxyInstance(); const haproxy = await haproxyInstance();
await checkHAProxy(haproxy); await checkHAProxy(haproxy);
let serverConfigured = false; let serverConfigured = false;
@@ -637,7 +797,7 @@ export async function configureSimpleServiceProxyOn({ id, domain, port }) {
}, },
json: { json: {
address: id, address: id,
check: 'enabled', check: 'enable',
name: id, name: id,
port: port port: port
} }
@@ -676,29 +836,37 @@ export async function removeWwwRedirection(fqdn) {
const haproxy = await haproxyInstance(); const haproxy = await haproxyInstance();
await checkHAProxy(); await checkHAProxy();
const rules: any = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, { let transactionId;
searchParams: {
parent_name: 'http', try {
parent_type: 'frontend' const rules: any = 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) {
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();
} }
})
.json();
if (rules.data.length > 0) {
const rule = rules.data.find((rule) => rule.redir_value.includes(redirectValue));
if (rule) {
const 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();
await completeTransaction(transactionId);
} }
} catch (error) {
console.log(error);
} finally {
if (transactionId) await completeTransaction(transactionId);
} }
} }
export async function setWwwRedirection(fqdn) { export async function setWwwRedirection(fqdn) {

View File

@@ -14,7 +14,7 @@ export default async function ({
buildId buildId
}): Promise<any> { }): Promise<any> {
try { try {
saveBuildLog({ line: 'GitHub importer started', buildId, applicationId }); saveBuildLog({ line: 'GitHub importer started.', buildId, applicationId });
const { privateKey, appId, installationId } = await db.getUniqueGithubApp({ githubAppId }); const { privateKey, appId, installationId } = await db.getUniqueGithubApp({ githubAppId });
const githubPrivateKey = privateKey.replace(/\\n/g, '\n').replace(/"/g, ''); const githubPrivateKey = privateKey.replace(/\\n/g, '\n').replace(/"/g, '');

View File

@@ -5,7 +5,7 @@ import * as db from '$lib/database';
import cuid from 'cuid'; import cuid from 'cuid';
import getPort, { portNumbers } from 'get-port'; import getPort, { portNumbers } from 'get-port';
export async function letsEncrypt({ domain, isCoolify = false, id = null }) { export async function letsEncrypt(domain, id = null, isCoolify = false) {
try { try {
const data = await db.prisma.setting.findFirst(); const data = await db.prisma.setting.findFirst();
const { minPort, maxPort } = data; const { minPort, maxPort } = data;
@@ -47,7 +47,6 @@ export async function letsEncrypt({ domain, isCoolify = false, id = null }) {
} }
} }
} }
await forceSSLOffApplication(domain);
if (dualCerts) { if (dualCerts) {
await asyncExecShell( await asyncExecShell(
`DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:${randomPort} -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port ${randomPort} -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email ${ `DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:${randomPort} -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port ${randomPort} -d ${nakedDomain} -d ${wwwDomain} --expand --agree-tos --non-interactive --register-unsafely-without-email ${
@@ -71,9 +70,5 @@ export async function letsEncrypt({ domain, isCoolify = false, id = null }) {
if (error.code !== 0) { if (error.code !== 0) {
throw error; throw error;
} }
} finally {
if (!isCoolify) {
await forceSSLOnApplication(domain);
}
} }
} }

View File

@@ -4,12 +4,6 @@ import * as buildpacks from '../buildPacks';
import * as importers from '../importers'; import * as importers from '../importers';
import { dockerInstance } from '../docker'; import { dockerInstance } from '../docker';
import { asyncExecShell, createDirectories, getDomain, getEngine, saveBuildLog } from '../common'; import { asyncExecShell, createDirectories, getDomain, getEngine, saveBuildLog } from '../common';
import {
checkProxyConfigurations,
configureProxyForApplication,
reloadHaproxy,
setWwwRedirection
} from '../haproxy';
import * as db from '$lib/database'; import * as db from '$lib/database';
import { decrypt } from '$lib/crypto'; import { decrypt } from '$lib/crypto';
import { sentry } from '$lib/common'; import { sentry } from '$lib/common';
@@ -261,26 +255,27 @@ export default async function (job) {
sentry.captureException(error); sentry.captureException(error);
throw new Error(error); throw new Error(error);
} }
try { saveBuildLog({ line: 'Proxy will be configured shortly.', buildId, applicationId });
if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { // try {
saveBuildLog({ line: 'Proxy configuration started!', buildId, applicationId }); // if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) {
await checkProxyConfigurations(); // saveBuildLog({ line: 'Proxy configuration started!', buildId, applicationId });
await configureProxyForApplication({ domain, imageId, applicationId, port }); // await checkProxyConfigurations();
if (isHttps) await letsEncrypt({ domain, id: applicationId }); // await configureProxyForApplication(domain, imageId, port);
await setWwwRedirection(fqdn); // if (isHttps) await letsEncrypt({ domain, id: applicationId });
await reloadHaproxy(destinationDocker.engine); // await setWwwRedirection(fqdn);
saveBuildLog({ line: 'Proxy configuration successful!', buildId, applicationId }); // await reloadHaproxy(destinationDocker.engine);
} else { // saveBuildLog({ line: 'Proxy configuration successful!', buildId, applicationId });
saveBuildLog({ // } else {
line: 'Coolify Proxy is not configured for this destination. Nothing else to do.', // saveBuildLog({
buildId, // line: 'Coolify Proxy is not configured for this destination. Nothing else to do.',
applicationId // buildId,
}); // applicationId
} // });
} catch (error) { // }
saveBuildLog({ line: error.stdout || error, buildId, applicationId }); // } catch (error) {
sentry.captureException(error); // saveBuildLog({ line: error.stdout || error, buildId, applicationId });
throw new Error(error); // sentry.captureException(error);
} // throw new Error(error);
// }
} }
} }

View File

@@ -87,8 +87,8 @@ const cron = async () => {
await queue.proxy.add('proxy', {}, { repeat: { every: 10000 } }); await queue.proxy.add('proxy', {}, { repeat: { every: 10000 } });
// await queue.ssl.add('ssl', {}, { repeat: { every: 10000 } }); // await queue.ssl.add('ssl', {}, { repeat: { every: 10000 } });
await queue.cleanup.add('cleanup', {}, { repeat: { every: 600000 } }); // await queue.cleanup.add('cleanup', {}, { repeat: { every: 600000 } });
await queue.sslRenew.add('sslRenew', {}, { repeat: { every: 1800000 } }); // await queue.sslRenew.add('sslRenew', {}, { repeat: { every: 1800000 } });
const events = { const events = {
proxy: new QueueEvents('proxy', { ...connectionOptions }), proxy: new QueueEvents('proxy', { ...connectionOptions }),

View File

@@ -1,20 +1,15 @@
import * as db from '$lib/database';
import { getDomain } from '$lib/common'; import { getDomain } from '$lib/common';
import { getApplicationById, prisma, supportedServiceTypesAndVersions } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import { import {
checkContainer, checkContainer,
checkProxyConfigurations, checkProxyConfigurations,
configureCoolifyProxyOn, configureCoolifyProxyOn,
configureProxyForApplication, configureHAProxy,
configureSimpleServiceProxyOn,
forceSSLOnApplication, forceSSLOnApplication,
reloadHaproxy,
setWwwRedirection, setWwwRedirection,
startCoolifyProxy, startCoolifyProxy,
startHttpProxy startHttpProxy
} from '$lib/haproxy'; } from '$lib/haproxy';
import * as db from '$lib/database';
// import { generateRemoteEngine } from '$lib/components/common';
export default async function () { export default async function () {
try { try {
@@ -23,83 +18,55 @@ export default async function () {
console.log(error); console.log(error);
} }
try { try {
// Check destination containers and configure proxy if needed const applications = await db.prisma.application.findMany({
const destinationDockers = await prisma.destinationDocker.findMany({}); include: { destinationDocker: true }
for (const destination of destinationDockers) { });
if (destination.isCoolifyProxyUsed) {
// if (destination.remoteEngine) { for (const application of applications) {
// const engine = generateRemoteEngine(destination); const {
// } fqdn,
const docker = dockerInstance({ destinationDocker: destination }); id,
const containers = await docker.engine.listContainers(); port,
const configurations = containers.filter( destinationDocker: { engine }
(container) => container.Labels['coolify.managed'] } = application;
); const containerRunning = await checkContainer(engine, id);
for (const configuration of configurations) { await configureHAProxy(fqdn, id, port, containerRunning, engine);
if (configuration.Labels['coolify.configuration']) { }
const parsedConfiguration = JSON.parse(
Buffer.from(configuration.Labels['coolify.configuration'], 'base64').toString() const services = await db.prisma.service.findMany({
); include: {
if ( destinationDocker: true,
parsedConfiguration && minio: true,
configuration.Labels['coolify.type'] === 'standalone-application' plausibleAnalytics: true,
) { vscodeserver: true,
const { fqdn, applicationId, port, pullmergeRequestId } = parsedConfiguration; wordpress: true
if (fqdn) { }
const found = await getApplicationById({ id: applicationId }); });
if (found) {
const domain = getDomain(fqdn); for (const service of services) {
await configureProxyForApplication({ const {
domain, fqdn,
imageId: pullmergeRequestId id,
? `${applicationId}-${pullmergeRequestId}` type,
: applicationId, destinationDocker: { engine }
applicationId, } = service;
port const found = db.supportedServiceTypesAndVersions.find((a) => a.name === type);
}); if (found) {
const isHttps = fqdn.startsWith('https://'); const port = found.ports.main;
if (isHttps) await forceSSLOnApplication(domain); const publicPort = service[type]?.publicPort;
await setWwwRedirection(fqdn); const containerRunning = await checkContainer(engine, id);
} await configureHAProxy(fqdn, id, port, containerRunning, engine);
} if (publicPort) {
} const containerFound = await checkContainer(
} service.destinationDocker.engine,
} `haproxy-for-${publicPort}`
for (const container of containers) { );
const image = container.Image.split(':')[0]; if (!containerFound) {
const found = supportedServiceTypesAndVersions.find((a) => a.baseImage === image); await startHttpProxy(service.destinationDocker, id, publicPort, 9000);
if (found) {
const type = found.name;
const mainPort = found.ports.main;
const id = container.Names[0].replace('/', '');
const service = await db.prisma.service.findUnique({
where: { id },
include: {
destinationDocker: true,
minio: true,
plausibleAnalytics: true,
vscodeserver: true,
wordpress: true
}
});
const { fqdn } = service;
const domain = getDomain(fqdn);
await configureSimpleServiceProxyOn({ id, domain, port: mainPort });
const publicPort = service[type]?.publicPort;
if (publicPort) {
const containerFound = await checkContainer(
destination.engine,
`haproxy-for-${publicPort}`
);
if (!containerFound) {
await startHttpProxy(destination, id, publicPort, 9000);
}
}
} }
} }
} }
} }
const services = await prisma.service.findMany({});
// Check Coolify FQDN and configure proxy if needed // Check Coolify FQDN and configure proxy if needed
const { fqdn } = await db.listSettings(); const { fqdn } = await db.listSettings();
if (fqdn) { if (fqdn) {

View File

@@ -20,7 +20,7 @@ export const post: RequestHandler = async (event) => {
const docker = dockerInstance({ destinationDocker }); const docker = dockerInstance({ destinationDocker });
await docker.engine.getContainer(id).stop(); await docker.engine.getContainer(id).stop();
} }
await removeProxyConfiguration(fqdn); // await removeProxyConfiguration(fqdn);
return { return {
status: 200 status: 200
}; };

View File

@@ -24,7 +24,7 @@ export const post: RequestHandler = async (event) => {
const { id } = event.params; const { id } = event.params;
try { try {
await checkHAProxy(); // await checkHAProxy();
const service = await db.getService({ id, teamId }); const service = await db.getService({ id, teamId });
const { const {
type, type,
@@ -96,16 +96,16 @@ export const post: RequestHandler = async (event) => {
} }
try { try {
await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`); await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`);
await checkProxyConfigurations(); // await checkProxyConfigurations();
await configureSimpleServiceProxyOn({ id, domain, port: consolePort }); // await configureSimpleServiceProxyOn({ id, domain, port: consolePort });
await db.updateMinioService({ id, publicPort }); await db.updateMinioService({ id, publicPort });
await startHttpProxy(destinationDocker, id, publicPort, apiPort); await startHttpProxy(destinationDocker, id, publicPort, apiPort);
if (isHttps) { // if (isHttps) {
await letsEncrypt({ domain, id }); // await letsEncrypt({ domain, id });
} // }
await setWwwRedirection(fqdn); // await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine); // await reloadHaproxy(destinationDocker.engine);
return { return {
status: 200 status: 200
}; };

View File

@@ -35,7 +35,7 @@ export const post: RequestHandler = async (event) => {
} }
try { try {
await stopTcpHttpProxy(destinationDocker, publicPort); await stopTcpHttpProxy(destinationDocker, publicPort);
await configureSimpleServiceProxyOff(fqdn); // await configureSimpleServiceProxyOff(fqdn);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }

View File

@@ -56,14 +56,14 @@ export const post: RequestHandler = async (event) => {
try { try {
await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`); await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`);
await checkProxyConfigurations(); // await checkProxyConfigurations();
await configureSimpleServiceProxyOn({ id, domain, port: 8080 }); // await configureSimpleServiceProxyOn({ id, domain, port: 8080 });
if (isHttps) { // if (isHttps) {
await letsEncrypt({ domain, id }); // await letsEncrypt({ domain, id });
} // }
await setWwwRedirection(fqdn); // await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine); // await reloadHaproxy(destinationDocker.engine);
return { return {
status: 200 status: 200
}; };

View File

@@ -187,14 +187,14 @@ COPY ./init-db.sh /docker-entrypoint-initdb.d/init-db.sh`;
await asyncExecShell( await asyncExecShell(
`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up --build -d` `DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up --build -d`
); );
await checkProxyConfigurations(); // await checkProxyConfigurations();
await configureSimpleServiceProxyOn({ id, domain, port: 8000 }); // await configureSimpleServiceProxyOn({ id, domain, port: 8000 });
if (isHttps) { // if (isHttps) {
await letsEncrypt({ domain, id }); // await letsEncrypt({ domain, id });
} // }
await setWwwRedirection(fqdn); // await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine); // await reloadHaproxy(destinationDocker.engine);
return { return {
status: 200 status: 200
}; };

View File

@@ -74,14 +74,14 @@ export const post: RequestHandler = async (event) => {
} }
try { try {
await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`); await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`);
await checkProxyConfigurations(); // await checkProxyConfigurations();
await configureSimpleServiceProxyOn({ id, domain, port: 80 }); // await configureSimpleServiceProxyOn({ id, domain, port: 80 });
if (isHttps) { // if (isHttps) {
await letsEncrypt({ domain, id }); // await letsEncrypt({ domain, id });
} // }
await setWwwRedirection(fqdn); // await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine); // await reloadHaproxy(destinationDocker.engine);
return { return {
status: 200 status: 200
}; };

View File

@@ -84,14 +84,14 @@ export const post: RequestHandler = async (event) => {
try { try {
await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`); await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`);
await checkProxyConfigurations(); // await checkProxyConfigurations();
await configureSimpleServiceProxyOn({ id, domain, port: 8080 }); // await configureSimpleServiceProxyOn({ id, domain, port: 8080 });
if (isHttps) { // if (isHttps) {
await letsEncrypt({ domain, id }); // await letsEncrypt({ domain, id });
} // }
await setWwwRedirection(fqdn); // await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine); // await reloadHaproxy(destinationDocker.engine);
return { return {
status: 200 status: 200
}; };

View File

@@ -121,14 +121,14 @@ export const post: RequestHandler = async (event) => {
try { try {
await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`); await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`);
await checkProxyConfigurations(); // await checkProxyConfigurations();
await configureSimpleServiceProxyOn({ id, domain, port: 80 }); // await configureSimpleServiceProxyOn({ id, domain, port: 80 });
if (isHttps) { // if (isHttps) {
await letsEncrypt({ domain, id }); // await letsEncrypt({ domain, id });
} // }
await setWwwRedirection(fqdn); // await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine); // await reloadHaproxy(destinationDocker.engine);
return { return {
status: 200 status: 200
}; };