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

@@ -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');
}
}