commit
ac19ea5407
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "coolify",
|
"name": "coolify",
|
||||||
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
|
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
|
||||||
"version": "2.0.23",
|
"version": "2.0.24",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "docker-compose -f docker-compose-dev.yaml up -d && NODE_ENV=development svelte-kit dev --host 0.0.0.0",
|
"dev": "docker-compose -f docker-compose-dev.yaml up -d && NODE_ENV=development svelte-kit dev --host 0.0.0.0",
|
||||||
@ -74,6 +74,7 @@
|
|||||||
"js-cookie": "3.0.1",
|
"js-cookie": "3.0.1",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"jsonwebtoken": "8.5.1",
|
"jsonwebtoken": "8.5.1",
|
||||||
|
"mustache": "^4.2.0",
|
||||||
"node-forge": "1.2.1",
|
"node-forge": "1.2.1",
|
||||||
"svelte-kit-cookie-session": "2.1.2",
|
"svelte-kit-cookie-session": "2.1.2",
|
||||||
"tailwindcss-scrollbar": "^0.1.0",
|
"tailwindcss-scrollbar": "^0.1.0",
|
||||||
|
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@ -35,6 +35,7 @@ specifiers:
|
|||||||
js-yaml: 4.1.0
|
js-yaml: 4.1.0
|
||||||
jsonwebtoken: 8.5.1
|
jsonwebtoken: 8.5.1
|
||||||
lint-staged: 12.3.4
|
lint-staged: 12.3.4
|
||||||
|
mustache: ^4.2.0
|
||||||
node-forge: 1.2.1
|
node-forge: 1.2.1
|
||||||
postcss: 8.4.6
|
postcss: 8.4.6
|
||||||
prettier: 2.5.1
|
prettier: 2.5.1
|
||||||
@ -70,6 +71,7 @@ dependencies:
|
|||||||
js-cookie: 3.0.1
|
js-cookie: 3.0.1
|
||||||
js-yaml: 4.1.0
|
js-yaml: 4.1.0
|
||||||
jsonwebtoken: 8.5.1
|
jsonwebtoken: 8.5.1
|
||||||
|
mustache: 4.2.0
|
||||||
node-forge: 1.2.1
|
node-forge: 1.2.1
|
||||||
svelte-kit-cookie-session: 2.1.2
|
svelte-kit-cookie-session: 2.1.2
|
||||||
tailwindcss-scrollbar: 0.1.0_tailwindcss@3.0.23
|
tailwindcss-scrollbar: 0.1.0_tailwindcss@3.0.23
|
||||||
@ -4091,6 +4093,14 @@ packages:
|
|||||||
msgpackr-extract: 1.0.15
|
msgpackr-extract: 1.0.15
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/mustache/4.2.0:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==
|
||||||
|
}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/nan/2.15.0:
|
/nan/2.15.0:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
2
prisma/migrations/20220301101928_proxyhash/migration.sql
Normal file
2
prisma/migrations/20220301101928_proxyhash/migration.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Setting" ADD COLUMN "proxyHash" TEXT;
|
@ -16,6 +16,7 @@ model Setting {
|
|||||||
maxPort Int @default(9100)
|
maxPort Int @default(9100)
|
||||||
proxyPassword String
|
proxyPassword String
|
||||||
proxyUser String
|
proxyUser String
|
||||||
|
proxyHash String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,15 @@ async function main() {
|
|||||||
proxyUser: cuid()
|
proxyUser: cuid()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
await prisma.setting.update({
|
||||||
|
where: {
|
||||||
|
id: settingsFound.id
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
proxyHash: null
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const localDocker = await prisma.destinationDocker.findFirst({
|
const localDocker = await prisma.destinationDocker.findFirst({
|
||||||
where: { engine: '/var/run/docker.sock' }
|
where: { engine: '/var/run/docker.sock' }
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { decrypt, encrypt } from '$lib/crypto';
|
import { decrypt, encrypt } from '$lib/crypto';
|
||||||
import { removeProxyConfiguration } from '$lib/haproxy';
|
|
||||||
import { asyncExecShell, getEngine } from '$lib/common';
|
import { asyncExecShell, getEngine } from '$lib/common';
|
||||||
|
|
||||||
import { getDomain, removeDestinationDocker } from '$lib/common';
|
import { getDomain, removeDestinationDocker } from '$lib/common';
|
||||||
@ -136,13 +135,13 @@ export async function getApplication({ id, teamId }) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (body.gitSource?.githubApp?.clientSecret) {
|
if (body?.gitSource?.githubApp?.clientSecret) {
|
||||||
body.gitSource.githubApp.clientSecret = decrypt(body.gitSource.githubApp.clientSecret);
|
body.gitSource.githubApp.clientSecret = decrypt(body.gitSource.githubApp.clientSecret);
|
||||||
}
|
}
|
||||||
if (body.gitSource?.githubApp?.webhookSecret) {
|
if (body?.gitSource?.githubApp?.webhookSecret) {
|
||||||
body.gitSource.githubApp.webhookSecret = decrypt(body.gitSource.githubApp.webhookSecret);
|
body.gitSource.githubApp.webhookSecret = decrypt(body.gitSource.githubApp.webhookSecret);
|
||||||
}
|
}
|
||||||
if (body.gitSource?.githubApp?.privateKey) {
|
if (body?.gitSource?.githubApp?.privateKey) {
|
||||||
body.gitSource.githubApp.privateKey = decrypt(body.gitSource.githubApp.privateKey);
|
body.gitSource.githubApp.privateKey = decrypt(body.gitSource.githubApp.privateKey);
|
||||||
}
|
}
|
||||||
if (body?.gitSource?.gitlabApp?.appSecret) {
|
if (body?.gitSource?.gitlabApp?.appSecret) {
|
||||||
|
259
src/lib/haproxy/configuration.ts
Normal file
259
src/lib/haproxy/configuration.ts
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
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 { asyncExecShell, getDomain, getEngine } from '$lib/common';
|
||||||
|
|
||||||
|
const url = dev ? 'http://localhost:5555' : 'http://coolify-haproxy:5555';
|
||||||
|
|
||||||
|
let template = `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}}
|
||||||
|
{{#services}}
|
||||||
|
{{#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}} }
|
||||||
|
{{/services}}
|
||||||
|
{{#coolify}}
|
||||||
|
{{#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}} }
|
||||||
|
{{/coolify}}
|
||||||
|
use_backend backend-certbot if is_certbot
|
||||||
|
use_backend %[req.hdr(host),lower]
|
||||||
|
|
||||||
|
frontend stats
|
||||||
|
bind *:8404
|
||||||
|
stats enable
|
||||||
|
stats uri /
|
||||||
|
stats admin if TRUE
|
||||||
|
stats auth "\${HAPROXY_USERNAME}:\${HAPROXY_PASSWORD}"
|
||||||
|
|
||||||
|
backend backend-certbot
|
||||||
|
mode http
|
||||||
|
server certbot host.docker.internal:9080
|
||||||
|
|
||||||
|
{{#applications}}
|
||||||
|
{{#isRunning}}
|
||||||
|
# updatedAt={{updatedAt}}
|
||||||
|
backend {{domain}}
|
||||||
|
option forwardfor
|
||||||
|
server {{id}} {{id}}:{{port}} check
|
||||||
|
{{/isRunning}}
|
||||||
|
{{/applications}}
|
||||||
|
|
||||||
|
{{#services}}
|
||||||
|
{{#isRunning}}
|
||||||
|
# updatedAt={{updatedAt}}
|
||||||
|
backend {{domain}}
|
||||||
|
option forwardfor
|
||||||
|
server {{id}} {{id}}:{{port}} check
|
||||||
|
{{/isRunning}}
|
||||||
|
{{/services}}
|
||||||
|
|
||||||
|
{{#coolify}}
|
||||||
|
backend {{domain}}
|
||||||
|
option forwardfor
|
||||||
|
option httpchk GET /undead.json
|
||||||
|
server {{id}} {{id}}:{{port}} check fall 10
|
||||||
|
{{/coolify}}
|
||||||
|
`;
|
||||||
|
export async function haproxyInstance() {
|
||||||
|
const { proxyPassword } = await db.listSettings();
|
||||||
|
return got.extend({
|
||||||
|
prefixUrl: url,
|
||||||
|
username: 'admin',
|
||||||
|
password: proxyPassword
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function configureHAProxy() {
|
||||||
|
try {
|
||||||
|
const haproxy = await haproxyInstance();
|
||||||
|
await checkHAProxy(haproxy);
|
||||||
|
const data = {
|
||||||
|
applications: [],
|
||||||
|
services: [],
|
||||||
|
coolify: []
|
||||||
|
};
|
||||||
|
const applications = await db.prisma.application.findMany({
|
||||||
|
include: { destinationDocker: true, settings: true }
|
||||||
|
});
|
||||||
|
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 : '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) {
|
||||||
|
let previewDomain = `${container.split('-')[1]}.${domain}`;
|
||||||
|
data.applications.push({
|
||||||
|
id: container,
|
||||||
|
port: port || 3000,
|
||||||
|
domain: previewDomain,
|
||||||
|
isRunning,
|
||||||
|
isHttps,
|
||||||
|
redirectValue,
|
||||||
|
redirectTo: isWWW ? previewDomain : 'www.' + previewDomain,
|
||||||
|
updatedAt: updatedAt.getTime()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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, 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 : '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 : '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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import { dev } from '$app/env';
|
import { dev } from '$app/env';
|
||||||
import { asyncExecShell, getDomain, getEngine } from '$lib/common';
|
import { asyncExecShell, getEngine } from '$lib/common';
|
||||||
import got from 'got';
|
import got from 'got';
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
|
|
||||||
@ -47,113 +47,6 @@ export async function completeTransaction(transactionId) {
|
|||||||
const haproxy = await haproxyInstance();
|
const haproxy = await haproxyInstance();
|
||||||
return await haproxy.put(`v2/services/haproxy/transactions/${transactionId}`);
|
return await haproxy.put(`v2/services/haproxy/transactions/${transactionId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function removeProxyConfiguration(fqdn) {
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
const backendFound = await haproxy
|
|
||||||
.get(`v2/services/haproxy/configuration/backends/${domain}`)
|
|
||||||
.json();
|
|
||||||
if (backendFound) {
|
|
||||||
const transactionId = await getNextTransactionId();
|
|
||||||
await haproxy
|
|
||||||
.delete(`v2/services/haproxy/configuration/backends/${domain}`, {
|
|
||||||
searchParams: {
|
|
||||||
transaction_id: transactionId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.json();
|
|
||||||
await completeTransaction(transactionId);
|
|
||||||
}
|
|
||||||
await forceSSLOffApplication(domain);
|
|
||||||
await removeWwwRedirection(fqdn);
|
|
||||||
}
|
|
||||||
export async function forceSSLOffApplication(domain) {
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
await checkHAProxy(haproxy);
|
|
||||||
let transactionId;
|
|
||||||
try {
|
|
||||||
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.cond_test.includes(`{ hdr(host) -i ${domain} } !{ ssl_fc }`)
|
|
||||||
);
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
} finally {
|
|
||||||
if (transactionId) await completeTransaction(transactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export async function forceSSLOnApplication(domain) {
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
await checkHAProxy(haproxy);
|
|
||||||
let transactionId;
|
|
||||||
try {
|
|
||||||
const rules: any = 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;
|
|
||||||
}
|
|
||||||
transactionId = await getNextTransactionId();
|
|
||||||
|
|
||||||
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();
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
if (transactionId) await completeTransaction(transactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteProxy({ id }) {
|
export async function deleteProxy({ id }) {
|
||||||
const haproxy = await haproxyInstance();
|
const haproxy = await haproxyInstance();
|
||||||
await checkHAProxy(haproxy);
|
await checkHAProxy(haproxy);
|
||||||
@ -177,7 +70,7 @@ export async function deleteProxy({ id }) {
|
|||||||
})
|
})
|
||||||
.json();
|
.json();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error.response.body);
|
console.log(error.response?.body || error);
|
||||||
} finally {
|
} finally {
|
||||||
if (transactionId) await completeTransaction(transactionId);
|
if (transactionId) await completeTransaction(transactionId);
|
||||||
}
|
}
|
||||||
@ -187,169 +80,6 @@ export async function reloadHaproxy(engine) {
|
|||||||
const host = getEngine(engine);
|
const host = getEngine(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() {
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
await checkHAProxy(haproxy);
|
|
||||||
try {
|
|
||||||
const stats: any = await haproxy.get(`v2/services/haproxy/stats/native`).json();
|
|
||||||
for (const stat of stats[0].stats) {
|
|
||||||
if (stat.stats.status === 'DOWN' && stat.type === 'server') {
|
|
||||||
const {
|
|
||||||
name,
|
|
||||||
backend_name: backendName,
|
|
||||||
stats: { lastchg }
|
|
||||||
} = stat;
|
|
||||||
const { fqdn } = await db.listSettings();
|
|
||||||
if (fqdn) {
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
if (backendName === domain) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const application = await db.getApplicationById(name);
|
|
||||||
if (!application) {
|
|
||||||
const transactionId = await getNextTransactionId();
|
|
||||||
await haproxy
|
|
||||||
.delete(`v2/services/haproxy/configuration/backends/${backendName}`, {
|
|
||||||
searchParams: {
|
|
||||||
transaction_id: transactionId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.json();
|
|
||||||
return await completeTransaction(transactionId);
|
|
||||||
}
|
|
||||||
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 (lastchg > 120) {
|
|
||||||
const transactionId = await getNextTransactionId();
|
|
||||||
await haproxy
|
|
||||||
.delete(`v2/services/haproxy/configuration/backends/${backendName}`, {
|
|
||||||
searchParams: {
|
|
||||||
transaction_id: transactionId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.json();
|
|
||||||
await completeTransaction(transactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export async function configureProxyForApplication({ domain, imageId, applicationId, port }) {
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
await checkHAProxy(haproxy);
|
|
||||||
|
|
||||||
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/${imageId}`, {
|
|
||||||
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 === 'enabled') {
|
|
||||||
if (server.data.address === imageId) {
|
|
||||||
if (server.data.port === port) {
|
|
||||||
serverConfigured = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
//console.log('error getting backend or server', error?.response?.body);
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverConfigured) return;
|
|
||||||
const transactionId = await getNextTransactionId();
|
|
||||||
if (backendAvailable) {
|
|
||||||
await haproxy
|
|
||||||
.delete(`v2/services/haproxy/configuration/backends/${domain}`, {
|
|
||||||
searchParams: {
|
|
||||||
transaction_id: transactionId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.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', {
|
|
||||||
searchParams: {
|
|
||||||
transaction_id: transactionId,
|
|
||||||
backend: domain
|
|
||||||
},
|
|
||||||
json: {
|
|
||||||
address: imageId,
|
|
||||||
check: 'enabled',
|
|
||||||
name: imageId,
|
|
||||||
port: port
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
throw error?.response?.body || error;
|
|
||||||
} finally {
|
|
||||||
await completeTransaction(transactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function configureCoolifyProxyOff(fqdn) {
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
await checkHAProxy(haproxy);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await haproxy.get(`v2/services/haproxy/configuration/backends/${domain}`).json();
|
|
||||||
const transactionId = await getNextTransactionId();
|
|
||||||
await haproxy
|
|
||||||
.delete(`v2/services/haproxy/configuration/backends/${domain}`, {
|
|
||||||
searchParams: {
|
|
||||||
transaction_id: transactionId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.json();
|
|
||||||
await completeTransaction(transactionId);
|
|
||||||
if (isHttps) await forceSSLOffApplication(domain);
|
|
||||||
await removeWwwRedirection(fqdn);
|
|
||||||
} catch (error) {
|
|
||||||
throw error?.response?.body || error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export async function checkHAProxy(haproxy?: any) {
|
export async function checkHAProxy(haproxy?: any) {
|
||||||
if (!haproxy) haproxy = await haproxyInstance();
|
if (!haproxy) haproxy = await haproxyInstance();
|
||||||
try {
|
try {
|
||||||
@ -361,76 +91,6 @@ export async function checkHAProxy(haproxy?: any) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export async function configureCoolifyProxyOn(fqdn) {
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
await checkHAProxy(haproxy);
|
|
||||||
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/coolify`, {
|
|
||||||
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 === 'enabled') {
|
|
||||||
if (server.data.address === dev ? 'host.docker.internal' : 'coolify') {
|
|
||||||
if (server.data.port === 3000) {
|
|
||||||
serverConfigured = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {}
|
|
||||||
if (serverConfigured) return;
|
|
||||||
const transactionId = await getNextTransactionId();
|
|
||||||
try {
|
|
||||||
await haproxy.post('v2/services/haproxy/configuration/backends', {
|
|
||||||
searchParams: {
|
|
||||||
transaction_id: transactionId
|
|
||||||
},
|
|
||||||
json: {
|
|
||||||
adv_check: 'httpchk',
|
|
||||||
httpchk_params: {
|
|
||||||
method: 'GET',
|
|
||||||
uri: '/undead.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: dev ? 'host.docker.internal' : 'coolify',
|
|
||||||
check: 'enabled',
|
|
||||||
fall: 10,
|
|
||||||
name: 'coolify',
|
|
||||||
port: 3000
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
await completeTransaction(transactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function stopTcpHttpProxy(destinationDocker, publicPort) {
|
export async function stopTcpHttpProxy(destinationDocker, publicPort) {
|
||||||
const { engine } = destinationDocker;
|
const { engine } = destinationDocker;
|
||||||
@ -494,7 +154,7 @@ export async function startHttpProxy(destinationDocker, id, publicPort, privateP
|
|||||||
export async function startCoolifyProxy(engine) {
|
export async function startCoolifyProxy(engine) {
|
||||||
const host = getEngine(engine);
|
const host = getEngine(engine);
|
||||||
const found = await checkContainer(engine, 'coolify-haproxy');
|
const found = await checkContainer(engine, 'coolify-haproxy');
|
||||||
const { proxyPassword, proxyUser } = await db.listSettings();
|
const { proxyPassword, proxyUser, id } = await db.listSettings();
|
||||||
if (!found) {
|
if (!found) {
|
||||||
const { stdout: Config } = await asyncExecShell(
|
const { stdout: Config } = await asyncExecShell(
|
||||||
`DOCKER_HOST="${host}" docker network inspect bridge --format '{{json .IPAM.Config }}'`
|
`DOCKER_HOST="${host}" docker network inspect bridge --format '{{json .IPAM.Config }}'`
|
||||||
@ -503,6 +163,7 @@ export async function startCoolifyProxy(engine) {
|
|||||||
await asyncExecShell(
|
await asyncExecShell(
|
||||||
`DOCKER_HOST="${host}" docker run -e HAPROXY_USERNAME=${proxyUser} -e HAPROXY_PASSWORD=${proxyPassword} --restart always --add-host 'host.docker.internal:host-gateway' --add-host 'host.docker.internal:${ip}' -v coolify-ssl-certs:/usr/local/etc/haproxy/ssl --network coolify-infra -p "80:80" -p "443:443" -p "8404:8404" -p "5555:5555" -p "5000:5000" --name coolify-haproxy -d coollabsio/${defaultProxyImage}`
|
`DOCKER_HOST="${host}" docker run -e HAPROXY_USERNAME=${proxyUser} -e HAPROXY_PASSWORD=${proxyPassword} --restart always --add-host 'host.docker.internal:host-gateway' --add-host 'host.docker.internal:${ip}' -v coolify-ssl-certs:/usr/local/etc/haproxy/ssl --network coolify-infra -p "80:80" -p "443:443" -p "8404:8404" -p "5555:5555" -p "5000:5000" --name coolify-haproxy -d coollabsio/${defaultProxyImage}`
|
||||||
);
|
);
|
||||||
|
await db.prisma.setting.update({ where: { id }, data: { proxyHash: null } });
|
||||||
}
|
}
|
||||||
await configureNetworkCoolifyProxy(engine);
|
await configureNetworkCoolifyProxy(engine);
|
||||||
}
|
}
|
||||||
@ -535,6 +196,8 @@ export async function stopCoolifyProxy(engine) {
|
|||||||
const host = getEngine(engine);
|
const host = getEngine(engine);
|
||||||
const found = await checkContainer(engine, 'coolify-haproxy');
|
const found = await checkContainer(engine, 'coolify-haproxy');
|
||||||
await db.setDestinationSettings({ engine, isCoolifyProxyUsed: false });
|
await db.setDestinationSettings({ engine, isCoolifyProxyUsed: false });
|
||||||
|
const { id } = await db.prisma.setting.findFirst({});
|
||||||
|
await db.prisma.setting.update({ where: { id }, data: { proxyHash: null } });
|
||||||
try {
|
try {
|
||||||
if (found) {
|
if (found) {
|
||||||
await asyncExecShell(
|
await asyncExecShell(
|
||||||
@ -559,171 +222,3 @@ export async function configureNetworkCoolifyProxy(engine) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function configureSimpleServiceProxyOn({ id, domain, port }) {
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
await checkHAProxy(haproxy);
|
|
||||||
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 === 'enabled') {
|
|
||||||
if (server.data.address === id) {
|
|
||||||
if (server.data.port === port) {
|
|
||||||
serverConfigured = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {}
|
|
||||||
if (serverConfigured) return;
|
|
||||||
const 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: 'enabled',
|
|
||||||
name: id,
|
|
||||||
port: port
|
|
||||||
}
|
|
||||||
});
|
|
||||||
await completeTransaction(transactionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function configureSimpleServiceProxyOff(fqdn) {
|
|
||||||
if (!fqdn) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
await checkHAProxy(haproxy);
|
|
||||||
try {
|
|
||||||
await haproxy.get(`v2/services/haproxy/configuration/backends/${domain}`).json();
|
|
||||||
const transactionId = await getNextTransactionId();
|
|
||||||
await haproxy
|
|
||||||
.delete(`v2/services/haproxy/configuration/backends/${domain}`, {
|
|
||||||
searchParams: {
|
|
||||||
transaction_id: transactionId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.json();
|
|
||||||
await completeTransaction(transactionId);
|
|
||||||
} catch (error) {}
|
|
||||||
await forceSSLOffApplication(domain);
|
|
||||||
await removeWwwRedirection(fqdn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function removeWwwRedirection(fqdn) {
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`;
|
|
||||||
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
await checkHAProxy();
|
|
||||||
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) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export async function setWwwRedirection(fqdn) {
|
|
||||||
const haproxy = await haproxyInstance();
|
|
||||||
await checkHAProxy(haproxy);
|
|
||||||
let transactionId;
|
|
||||||
|
|
||||||
try {
|
|
||||||
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}`} }`;
|
|
||||||
const rules: any = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
transactionId = await getNextTransactionId();
|
|
||||||
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;
|
|
||||||
} finally {
|
|
||||||
if (transactionId) await completeTransaction(transactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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, '');
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { dev } from '$app/env';
|
import { asyncExecShell, getDomain, getEngine } from '$lib/common';
|
||||||
import { forceSSLOffApplication, forceSSLOnApplication } from '$lib/haproxy';
|
import { checkContainer } from '$lib/haproxy';
|
||||||
import { asyncExecShell, getEngine } from './common';
|
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
|
import { dev } from '$app/env';
|
||||||
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,85 @@ 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);
|
|
||||||
|
export async function generateSSLCerts() {
|
||||||
|
const ssls = [];
|
||||||
|
const applications = await db.prisma.application.findMany({
|
||||||
|
include: { destinationDocker: true, settings: true }
|
||||||
|
});
|
||||||
|
for (const application of applications) {
|
||||||
|
const {
|
||||||
|
fqdn,
|
||||||
|
id,
|
||||||
|
destinationDocker: { engine, network },
|
||||||
|
settings: { previews }
|
||||||
|
} = application;
|
||||||
|
const isRunning = await checkContainer(engine, id);
|
||||||
|
const domain = getDomain(fqdn);
|
||||||
|
const isHttps = fqdn.startsWith('https://');
|
||||||
|
if (isRunning) {
|
||||||
|
if (isHttps) ssls.push({ domain, id, isCoolify: false });
|
||||||
|
}
|
||||||
|
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}`;
|
||||||
|
if (isHttps) ssls.push({ domain: previewDomain, id, isCoolify: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
const found = db.supportedServiceTypesAndVersions.find((a) => a.name === type);
|
||||||
|
if (found) {
|
||||||
|
const domain = getDomain(fqdn);
|
||||||
|
const isHttps = fqdn.startsWith('https://');
|
||||||
|
const isRunning = await checkContainer(engine, id);
|
||||||
|
if (isRunning) {
|
||||||
|
if (isHttps) ssls.push({ domain, id, isCoolify: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const { fqdn } = await db.prisma.setting.findFirst();
|
||||||
|
if (fqdn) {
|
||||||
|
const domain = getDomain(fqdn);
|
||||||
|
const isHttps = fqdn.startsWith('https://');
|
||||||
|
if (isHttps) ssls.push({ domain, id: 'coolify', isCoolify: true });
|
||||||
|
}
|
||||||
|
if (ssls.length > 0) {
|
||||||
|
for (const ssl of ssls) {
|
||||||
|
if (!dev) {
|
||||||
|
await letsEncrypt(ssl.domain, ssl.id, ssl.isCoolify);
|
||||||
|
} else {
|
||||||
|
console.log('Generate ssl for', ssl.domain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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,6 @@ 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 updated shortly.', buildId, applicationId });
|
||||||
if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) {
|
|
||||||
saveBuildLog({ line: 'Proxy configuration started!', buildId, applicationId });
|
|
||||||
await checkProxyConfigurations();
|
|
||||||
await configureProxyForApplication({ domain, imageId, applicationId, port });
|
|
||||||
if (isHttps) await letsEncrypt({ domain, id: applicationId });
|
|
||||||
await setWwwRedirection(fqdn);
|
|
||||||
await reloadHaproxy(destinationDocker.engine);
|
|
||||||
saveBuildLog({ line: 'Proxy configuration successful!', buildId, applicationId });
|
|
||||||
} else {
|
|
||||||
saveBuildLog({
|
|
||||||
line: 'Coolify Proxy is not configured for this destination. Nothing else to do.',
|
|
||||||
buildId,
|
|
||||||
applicationId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
saveBuildLog({ line: error.stdout || error, buildId, applicationId });
|
|
||||||
sentry.captureException(error);
|
|
||||||
throw new Error(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,48 +8,53 @@ export default async function () {
|
|||||||
for (const destinationDocker of destinationDockers) {
|
for (const destinationDocker of destinationDockers) {
|
||||||
const host = getEngine(destinationDocker.engine);
|
const host = getEngine(destinationDocker.engine);
|
||||||
// Tagging images with labels
|
// Tagging images with labels
|
||||||
try {
|
// try {
|
||||||
const images = [
|
// const images = [
|
||||||
`coollabsio/${defaultProxyImageTcp}`,
|
// `coollabsio/${defaultProxyImageTcp}`,
|
||||||
`coollabsio/${defaultProxyImageHttp}`,
|
// `coollabsio/${defaultProxyImageHttp}`,
|
||||||
'certbot/certbot:latest',
|
// 'certbot/certbot:latest',
|
||||||
'node:16.14.0-alpine',
|
// 'node:16.14.0-alpine',
|
||||||
'alpine:latest',
|
// 'alpine:latest',
|
||||||
'nginx:stable-alpine',
|
// 'nginx:stable-alpine',
|
||||||
'node:lts',
|
// 'node:lts',
|
||||||
'php:apache',
|
// 'php:apache',
|
||||||
'rust:latest'
|
// 'rust:latest'
|
||||||
];
|
// ];
|
||||||
for (const image of images) {
|
// for (const image of images) {
|
||||||
try {
|
// try {
|
||||||
await asyncExecShell(`DOCKER_HOST=${host} docker image inspect ${image}`);
|
// await asyncExecShell(`DOCKER_HOST=${host} docker image inspect ${image}`);
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
await asyncExecShell(
|
// await asyncExecShell(
|
||||||
`DOCKER_HOST=${host} docker pull ${image} && echo "FROM ${image}" | docker build --label coolify.image="true" -t "${image}" -`
|
// `DOCKER_HOST=${host} docker pull ${image} && echo "FROM ${image}" | docker build --label coolify.image="true" -t "${image}" -`
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} catch (error) {}
|
// } catch (error) {}
|
||||||
try {
|
try {
|
||||||
await asyncExecShell(`DOCKER_HOST=${host} docker container prune -f`);
|
await asyncExecShell(`DOCKER_HOST=${host} docker container prune -f`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
if (!dev) {
|
|
||||||
// Cleanup images that are not managed by coolify
|
|
||||||
try {
|
try {
|
||||||
await asyncExecShell(
|
await asyncExecShell(`DOCKER_HOST=${host} docker image prune -f`);
|
||||||
`DOCKER_HOST=${host} docker image prune --filter 'label!=coolify.image=true' -a -f`
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
// Cleanup old images >3 days
|
// if (!dev) {
|
||||||
try {
|
// // Cleanup images that are not managed by coolify
|
||||||
await asyncExecShell(`DOCKER_HOST=${host} docker image prune --filter "until=72h" -a -f`);
|
// try {
|
||||||
} catch (error) {
|
// await asyncExecShell(
|
||||||
console.log(error);
|
// `DOCKER_HOST=${host} docker image prune --filter 'label!=coolify.image=true' -a -f`
|
||||||
}
|
// );
|
||||||
}
|
// } catch (error) {
|
||||||
|
// console.log(error);
|
||||||
|
// }
|
||||||
|
// // Cleanup old images >3 days
|
||||||
|
// try {
|
||||||
|
// await asyncExecShell(`DOCKER_HOST=${host} docker image prune --filter "until=72h" -a -f`);
|
||||||
|
// } catch (error) {
|
||||||
|
// console.log(error);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ 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: 60000 } });
|
||||||
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 } });
|
||||||
|
|
||||||
|
@ -1,116 +1,12 @@
|
|||||||
import { getDomain } from '$lib/common';
|
import { dev } from '$app/env';
|
||||||
import { getApplicationById, prisma, supportedServiceTypesAndVersions } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { dockerInstance } from '$lib/docker';
|
import { configureHAProxy } from '$lib/haproxy/configuration';
|
||||||
import {
|
|
||||||
checkContainer,
|
|
||||||
checkProxyConfigurations,
|
|
||||||
configureCoolifyProxyOn,
|
|
||||||
configureProxyForApplication,
|
|
||||||
configureSimpleServiceProxyOn,
|
|
||||||
forceSSLOnApplication,
|
|
||||||
reloadHaproxy,
|
|
||||||
setWwwRedirection,
|
|
||||||
startCoolifyProxy,
|
|
||||||
startHttpProxy
|
|
||||||
} 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 {
|
||||||
await checkProxyConfigurations();
|
return await configureHAProxy();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error.response?.body || error);
|
||||||
}
|
return ErrorHandler(error.response?.body || error);
|
||||||
try {
|
|
||||||
// Check destination containers and configure proxy if needed
|
|
||||||
const destinationDockers = await prisma.destinationDocker.findMany({});
|
|
||||||
for (const destination of destinationDockers) {
|
|
||||||
if (destination.isCoolifyProxyUsed) {
|
|
||||||
// if (destination.remoteEngine) {
|
|
||||||
// const engine = generateRemoteEngine(destination);
|
|
||||||
// }
|
|
||||||
const docker = dockerInstance({ destinationDocker: destination });
|
|
||||||
const containers = await docker.engine.listContainers();
|
|
||||||
const configurations = containers.filter(
|
|
||||||
(container) => container.Labels['coolify.managed']
|
|
||||||
);
|
|
||||||
for (const configuration of configurations) {
|
|
||||||
if (configuration.Labels['coolify.configuration']) {
|
|
||||||
const parsedConfiguration = JSON.parse(
|
|
||||||
Buffer.from(configuration.Labels['coolify.configuration'], 'base64').toString()
|
|
||||||
);
|
|
||||||
if (
|
|
||||||
parsedConfiguration &&
|
|
||||||
configuration.Labels['coolify.type'] === 'standalone-application'
|
|
||||||
) {
|
|
||||||
const { fqdn, applicationId, port, pullmergeRequestId } = parsedConfiguration;
|
|
||||||
if (fqdn) {
|
|
||||||
const found = await getApplicationById({ id: applicationId });
|
|
||||||
if (found) {
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
await configureProxyForApplication({
|
|
||||||
domain,
|
|
||||||
imageId: pullmergeRequestId
|
|
||||||
? `${applicationId}-${pullmergeRequestId}`
|
|
||||||
: applicationId,
|
|
||||||
applicationId,
|
|
||||||
port
|
|
||||||
});
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
if (isHttps) await forceSSLOnApplication(domain);
|
|
||||||
await setWwwRedirection(fqdn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const container of containers) {
|
|
||||||
const image = container.Image.split(':')[0];
|
|
||||||
const found = supportedServiceTypesAndVersions.find((a) => a.baseImage === image);
|
|
||||||
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
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,76 +1,9 @@
|
|||||||
import { asyncExecShell, getDomain, getEngine } from '$lib/common';
|
import { generateSSLCerts } from '$lib/letsencrypt';
|
||||||
import { prisma } from '$lib/database';
|
|
||||||
import { dockerInstance } from '$lib/docker';
|
|
||||||
import { forceSSLOnApplication } from '$lib/haproxy';
|
|
||||||
import * as db from '$lib/database';
|
|
||||||
import { dev } from '$app/env';
|
|
||||||
import getPort, { portNumbers } from 'get-port';
|
|
||||||
import cuid from 'cuid';
|
|
||||||
|
|
||||||
export default async function () {
|
export default async function () {
|
||||||
try {
|
try {
|
||||||
const data = await db.prisma.setting.findFirst();
|
return await generateSSLCerts();
|
||||||
const { minPort, maxPort } = data;
|
|
||||||
|
|
||||||
const publicPort = await getPort({ port: portNumbers(minPort, maxPort) });
|
|
||||||
const randomCuid = cuid();
|
|
||||||
const destinationDockers = await prisma.destinationDocker.findMany({});
|
|
||||||
for (const destination of destinationDockers) {
|
|
||||||
if (destination.isCoolifyProxyUsed) {
|
|
||||||
const docker = dockerInstance({ destinationDocker: destination });
|
|
||||||
const containers = await docker.engine.listContainers();
|
|
||||||
const configurations = containers.filter(
|
|
||||||
(container) => container.Labels['coolify.managed']
|
|
||||||
);
|
|
||||||
for (const configuration of configurations) {
|
|
||||||
const parsedConfiguration = JSON.parse(
|
|
||||||
Buffer.from(configuration.Labels['coolify.configuration'], 'base64').toString()
|
|
||||||
);
|
|
||||||
if (configuration.Labels['coolify.type'] === 'standalone-application') {
|
|
||||||
const { fqdn } = parsedConfiguration;
|
|
||||||
if (fqdn) {
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
if (isHttps) {
|
|
||||||
if (dev) {
|
|
||||||
console.log('DEV MODE: SSL is enabled');
|
|
||||||
} else {
|
|
||||||
const host = getEngine(destination.engine);
|
|
||||||
await asyncExecShell(
|
|
||||||
`DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:${publicPort} -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 ${publicPort} -d ${domain} --agree-tos --non-interactive --register-unsafely-without-email`
|
|
||||||
);
|
|
||||||
const { stderr } = await asyncExecShell(
|
|
||||||
`DOCKER_HOST=${host} docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > /app/ssl/${domain}.pem`
|
|
||||||
);
|
|
||||||
if (stderr) throw new Error(stderr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { fqdn } = await db.listSettings();
|
|
||||||
if (fqdn) {
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
if (isHttps) {
|
|
||||||
if (dev) {
|
|
||||||
console.log('DEV MODE: SSL is enabled');
|
|
||||||
} else {
|
|
||||||
await asyncExecShell(
|
|
||||||
`docker run --rm --name certbot-${randomCuid} -p 9080:${publicPort} -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 ${publicPort} -d ${domain} --agree-tos --non-interactive --register-unsafely-without-email`
|
|
||||||
);
|
|
||||||
|
|
||||||
const { stderr } = await asyncExecShell(
|
|
||||||
`docker run --rm -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > /app/ssl/${domain}.pem`
|
|
||||||
);
|
|
||||||
if (stderr) throw new Error(stderr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,13 @@
|
|||||||
import { errorNotification } from '$lib/form';
|
import { errorNotification } from '$lib/form';
|
||||||
import { asyncSleep } from '$lib/components/common';
|
import { asyncSleep } from '$lib/components/common';
|
||||||
import { del, get, post } from '$lib/api';
|
import { del, get, post } from '$lib/api';
|
||||||
import { browser } from '$app/env';
|
import { browser, dev } from '$app/env';
|
||||||
import { fade } from 'svelte/transition';
|
|
||||||
|
|
||||||
let isUpdateAvailable = false;
|
let isUpdateAvailable = false;
|
||||||
|
|
||||||
let updateStatus = {
|
let updateStatus = {
|
||||||
|
found: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
checking: false,
|
|
||||||
success: null
|
success: null
|
||||||
};
|
};
|
||||||
let latestVersion = 'latest';
|
let latestVersion = 'latest';
|
||||||
@ -60,16 +60,19 @@
|
|||||||
}
|
}
|
||||||
if ($session.teamId === '0') {
|
if ($session.teamId === '0') {
|
||||||
try {
|
try {
|
||||||
updateStatus.checking = true;
|
|
||||||
const data = await get(`/update.json`);
|
const data = await get(`/update.json`);
|
||||||
if (overrideVersion || data?.isUpdateAvailable) {
|
if (overrideVersion || data?.isUpdateAvailable) {
|
||||||
latestVersion = overrideVersion || data.latestVersion;
|
latestVersion = overrideVersion || data.latestVersion;
|
||||||
isUpdateAvailable = overrideVersion ? true : data?.isUpdateAvailable;
|
console.log('checking update');
|
||||||
await post(`/update.json`, { type: 'pull', latestVersion });
|
const { exists } = await post(`/update.json`, {
|
||||||
|
type: 'check',
|
||||||
|
latestVersion,
|
||||||
|
overrideVersion
|
||||||
|
});
|
||||||
|
isUpdateAvailable = exists;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
} finally {
|
} finally {
|
||||||
updateStatus.checking = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,6 +100,11 @@
|
|||||||
async function update() {
|
async function update() {
|
||||||
updateStatus.loading = true;
|
updateStatus.loading = true;
|
||||||
try {
|
try {
|
||||||
|
if (dev) {
|
||||||
|
console.log(`updating to ${latestVersion}`);
|
||||||
|
await asyncSleep(4000);
|
||||||
|
return window.location.reload();
|
||||||
|
} else {
|
||||||
await post(`/update.json`, { type: 'update', latestVersion });
|
await post(`/update.json`, { type: 'update', latestVersion });
|
||||||
toast.push('Update completed.<br><br>Waiting for the new version to start...');
|
toast.push('Update completed.<br><br>Waiting for the new version to start...');
|
||||||
let reachable = false;
|
let reachable = false;
|
||||||
@ -117,6 +125,7 @@
|
|||||||
updateStatus.success = true;
|
updateStatus.success = true;
|
||||||
await asyncSleep(3000);
|
await asyncSleep(3000);
|
||||||
return window.location.reload();
|
return window.location.reload();
|
||||||
|
}
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
updateStatus.success = false;
|
updateStatus.success = false;
|
||||||
updateStatus.loading = false;
|
updateStatus.loading = false;
|
||||||
@ -311,35 +320,10 @@
|
|||||||
|
|
||||||
<div class="flex flex-col space-y-4 py-2">
|
<div class="flex flex-col space-y-4 py-2">
|
||||||
{#if $session.teamId === '0'}
|
{#if $session.teamId === '0'}
|
||||||
{#if updateStatus.checking}
|
{#if isUpdateAvailable}
|
||||||
<button
|
|
||||||
disabled
|
|
||||||
in:fade={{ duration: 150 }}
|
|
||||||
class="icons tooltip-right bg-gradient-to-r from-purple-500 via-pink-500 to-red-500 text-white duration-75 hover:scale-105"
|
|
||||||
data-tooltip="Checking for updates..."
|
|
||||||
><svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
class="h-9 w-8 animate-spin"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
fill="none"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
||||||
<path d="M9 4.55a8 8 0 0 1 6 14.9m0 -4.45v5h5" />
|
|
||||||
<line x1="5.63" y1="7.16" x2="5.63" y2="7.17" />
|
|
||||||
<line x1="4.06" y1="11" x2="4.06" y2="11.01" />
|
|
||||||
<line x1="4.63" y1="15.1" x2="4.63" y2="15.11" />
|
|
||||||
<line x1="7.16" y1="18.37" x2="7.16" y2="18.38" />
|
|
||||||
<line x1="11" y1="19.94" x2="11" y2="19.95" />
|
|
||||||
</svg></button
|
|
||||||
>
|
|
||||||
{:else if isUpdateAvailable}
|
|
||||||
<button
|
<button
|
||||||
disabled={updateStatus.success === false}
|
disabled={updateStatus.success === false}
|
||||||
data-tooltip="Update available"
|
title="Update available"
|
||||||
on:click={update}
|
on:click={update}
|
||||||
class="icons tooltip-right bg-gradient-to-r from-purple-500 via-pink-500 to-red-500 text-white duration-75 hover:scale-105"
|
class="icons tooltip-right bg-gradient-to-r from-purple-500 via-pink-500 to-red-500 text-white duration-75 hover:scale-105"
|
||||||
>
|
>
|
||||||
|
@ -86,7 +86,7 @@
|
|||||||
async function handleDeploySubmit() {
|
async function handleDeploySubmit() {
|
||||||
try {
|
try {
|
||||||
const { buildId } = await post(`/applications/${id}/deploy.json`, { ...application });
|
const { buildId } = await post(`/applications/${id}/deploy.json`, { ...application });
|
||||||
return await goto(`/applications/${id}/logs/build?buildId=${buildId}`);
|
return window.location.assign(`/applications/${id}/logs/build?buildId=${buildId}`);
|
||||||
} catch ({ error }) {
|
} catch ({ error }) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ export const post: RequestHandler = async (event) => {
|
|||||||
.digest('hex');
|
.digest('hex');
|
||||||
await db.prisma.application.update({ where: { id }, data: { configHash } });
|
await db.prisma.application.update({ where: { id }, data: { configHash } });
|
||||||
}
|
}
|
||||||
|
await db.prisma.application.update({ where: { id }, data: { updatedAt: new Date() } });
|
||||||
await buildQueue.add(buildId, { build_id: buildId, type: 'manual', ...applicationFound });
|
await buildQueue.add(buildId, { build_id: buildId, type: 'manual', ...applicationFound });
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
|
@ -51,7 +51,6 @@
|
|||||||
build.took = data.builds[0].took;
|
build.took = data.builds[0].took;
|
||||||
build.since = data.builds[0].since;
|
build.since = data.builds[0].since;
|
||||||
}
|
}
|
||||||
window.location.reload();
|
|
||||||
return build;
|
return build;
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -43,34 +43,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mx-auto max-w-6xl rounded-xl px-6 pt-4">
|
{#if applicationSecrets.length !== 0}
|
||||||
<table class="mx-auto">
|
<div class="mx-auto max-w-6xl rounded-xl px-6 pt-4">
|
||||||
<thead class=" rounded-xl border-b border-coolgray-500">
|
<table class="mx-auto border-separate text-left">
|
||||||
<tr>
|
<thead>
|
||||||
<th
|
<tr class="h-12">
|
||||||
scope="col"
|
<th scope="col">Name</th>
|
||||||
class="px-6 py-3 text-left text-xs font-bold uppercase tracking-wider text-white">Name</th
|
<th scope="col">Value</th>
|
||||||
>
|
<th scope="col" class="w-64 text-center">Need during buildtime?</th>
|
||||||
<th
|
<th scope="col" class="w-96 text-center">Action</th>
|
||||||
scope="col"
|
|
||||||
class="px-6 py-3 text-left text-xs font-bold uppercase tracking-wider text-white"
|
|
||||||
>Value</th
|
|
||||||
>
|
|
||||||
<th
|
|
||||||
scope="col"
|
|
||||||
class="px-6 py-3 text-left text-xs font-bold uppercase tracking-wider text-white"
|
|
||||||
>Need during buildtime?</th
|
|
||||||
>
|
|
||||||
<th
|
|
||||||
scope="col"
|
|
||||||
class="px-6 py-3 text-left text-xs font-bold uppercase tracking-wider text-white"
|
|
||||||
/>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="">
|
<tbody>
|
||||||
{#each applicationSecrets as secret}
|
{#each applicationSecrets as secret}
|
||||||
{#key secret.id}
|
{#key secret.id}
|
||||||
<tr class="h-20 transition duration-100 hover:bg-coolgray-400">
|
<tr>
|
||||||
<Secret
|
<Secret
|
||||||
PRMRSecret={PRMRSecrets.find((s) => s.name === secret.name)}
|
PRMRSecret={PRMRSecrets.find((s) => s.name === secret.name)}
|
||||||
isPRMRSecret
|
isPRMRSecret
|
||||||
@ -84,12 +71,13 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
<div class="flex justify-center py-4 text-center">
|
<div class="flex justify-center py-4 text-center">
|
||||||
<Explainer
|
<Explainer
|
||||||
customClass="w-full"
|
customClass="w-full"
|
||||||
text={applicationSecrets.length === 0
|
text={applicationSecrets.length === 0
|
||||||
? "<span class='font-bold text-white text-xl'>Please add secrets to the application first.</span> <br><br>These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-green-500 font-bold'>staging</span> environments."
|
? "You can add secrets to PR/MR deployments. Please add secrets to the application first. <br>Useful for creating <span class='text-green-500 font-bold'>staging</span> environments."
|
||||||
: "These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-green-500 font-bold'>staging</span> environments."}
|
: "These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-green-500 font-bold'>staging</span> environments."}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { getDomain, getUserDetails } from '$lib/common';
|
import { asyncExecShell, getEngine, getUserDetails, removeDestinationDocker } from '$lib/common';
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { dockerInstance } from '$lib/docker';
|
import { checkContainer } from '$lib/haproxy';
|
||||||
import { removeProxyConfiguration } from '$lib/haproxy';
|
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const post: RequestHandler = async (event) => {
|
export const post: RequestHandler = async (event) => {
|
||||||
@ -17,10 +16,12 @@ export const post: RequestHandler = async (event) => {
|
|||||||
teamId
|
teamId
|
||||||
});
|
});
|
||||||
if (destinationDockerId) {
|
if (destinationDockerId) {
|
||||||
const docker = dockerInstance({ destinationDocker });
|
const { engine } = destinationDocker;
|
||||||
await docker.engine.getContainer(id).stop();
|
const found = await checkContainer(engine, id);
|
||||||
|
if (found) {
|
||||||
|
await removeDestinationDocker({ id, engine });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
await removeProxyConfiguration(fqdn);
|
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
};
|
};
|
||||||
|
@ -117,6 +117,8 @@
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
} finally {
|
||||||
|
restarting = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,19 @@
|
|||||||
import { getDomain, getUserDetails } from '$lib/common';
|
import { getUserDetails } from '$lib/common';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import {
|
import { startCoolifyProxy, stopCoolifyProxy } from '$lib/haproxy';
|
||||||
configureCoolifyProxyOn,
|
|
||||||
forceSSLOnApplication,
|
|
||||||
setWwwRedirection,
|
|
||||||
startCoolifyProxy,
|
|
||||||
stopCoolifyProxy
|
|
||||||
} from '$lib/haproxy';
|
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const post: RequestHandler = async (event) => {
|
export const post: RequestHandler = async (event) => {
|
||||||
const { teamId, status, body } = await getUserDetails(event);
|
const { teamId, status, body } = await getUserDetails(event);
|
||||||
if (status === 401) return { status, body };
|
if (status === 401) return { status, body };
|
||||||
|
|
||||||
const { engine, fqdn } = await event.request.json();
|
const { engine } = await event.request.json();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
await stopCoolifyProxy(engine);
|
await stopCoolifyProxy(engine);
|
||||||
await startCoolifyProxy(engine);
|
await startCoolifyProxy(engine);
|
||||||
await db.setDestinationSettings({ engine, isCoolifyProxyUsed: true });
|
await db.setDestinationSettings({ engine, isCoolifyProxyUsed: true });
|
||||||
await configureCoolifyProxyOn(fqdn);
|
|
||||||
await setWwwRedirection(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
if (isHttps) await forceSSLOnApplication(domain);
|
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
};
|
};
|
||||||
|
@ -3,15 +3,7 @@ import * as db from '$lib/database';
|
|||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import { letsEncrypt } from '$lib/letsencrypt';
|
import { startHttpProxy } from '$lib/haproxy';
|
||||||
import {
|
|
||||||
checkHAProxy,
|
|
||||||
checkProxyConfigurations,
|
|
||||||
configureSimpleServiceProxyOn,
|
|
||||||
reloadHaproxy,
|
|
||||||
setWwwRedirection,
|
|
||||||
startHttpProxy
|
|
||||||
} from '$lib/haproxy';
|
|
||||||
import getPort, { portNumbers } from 'get-port';
|
import getPort, { portNumbers } from 'get-port';
|
||||||
import { getDomain } from '$lib/components/common';
|
import { getDomain } from '$lib/components/common';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
@ -24,7 +16,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
const { id } = event.params;
|
const { id } = event.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await checkHAProxy();
|
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const {
|
const {
|
||||||
type,
|
type,
|
||||||
@ -38,9 +29,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
const data = await db.prisma.setting.findFirst();
|
const data = await db.prisma.setting.findFirst();
|
||||||
const { minPort, maxPort } = data;
|
const { minPort, maxPort } = data;
|
||||||
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
|
|
||||||
const network = destinationDockerId && destinationDocker.network;
|
const network = destinationDockerId && destinationDocker.network;
|
||||||
const host = getEngine(destinationDocker.engine);
|
const host = getEngine(destinationDocker.engine);
|
||||||
|
|
||||||
@ -96,16 +84,8 @@ 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 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) {
|
|
||||||
await letsEncrypt({ domain, id });
|
|
||||||
}
|
|
||||||
await setWwwRedirection(fqdn);
|
|
||||||
await reloadHaproxy(destinationDocker.engine);
|
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { getEngine, getUserDetails, removeDestinationDocker } from '$lib/common';
|
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { dockerInstance } from '$lib/docker';
|
import { checkContainer, stopTcpHttpProxy } from '$lib/haproxy';
|
||||||
import { checkContainer, configureSimpleServiceProxyOff, stopTcpHttpProxy } from '$lib/haproxy';
|
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const post: RequestHandler = async (event) => {
|
export const post: RequestHandler = async (event) => {
|
||||||
@ -21,7 +19,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
minio: { publicPort }
|
minio: { publicPort }
|
||||||
} = service;
|
} = service;
|
||||||
await db.updateMinioService({ id, publicPort: null });
|
await db.updateMinioService({ id, publicPort: null });
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
if (destinationDockerId) {
|
if (destinationDockerId) {
|
||||||
const engine = destinationDocker.engine;
|
const engine = destinationDocker.engine;
|
||||||
|
|
||||||
@ -35,7 +32,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await stopTcpHttpProxy(destinationDocker, publicPort);
|
await stopTcpHttpProxy(destinationDocker, publicPort);
|
||||||
await configureSimpleServiceProxyOff(fqdn);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,6 @@ import * as db from '$lib/database';
|
|||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import { letsEncrypt } from '$lib/letsencrypt';
|
|
||||||
import {
|
|
||||||
checkHAProxy,
|
|
||||||
checkProxyConfigurations,
|
|
||||||
configureSimpleServiceProxyOn,
|
|
||||||
reloadHaproxy,
|
|
||||||
setWwwRedirection
|
|
||||||
} from '$lib/haproxy';
|
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { makeLabelForServices } from '$lib/buildPacks/common';
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
@ -22,13 +13,8 @@ export const post: RequestHandler = async (event) => {
|
|||||||
const { id } = event.params;
|
const { id } = event.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await checkHAProxy();
|
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const { type, version, fqdn, destinationDockerId, destinationDocker } = service;
|
const { type, version, destinationDockerId, destinationDocker } = service;
|
||||||
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
|
|
||||||
const network = destinationDockerId && destinationDocker.network;
|
const network = destinationDockerId && destinationDocker.network;
|
||||||
const host = getEngine(destinationDocker.engine);
|
const host = getEngine(destinationDocker.engine);
|
||||||
|
|
||||||
@ -56,14 +42,6 @@ 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 configureSimpleServiceProxyOn({ id, domain, port: 8080 });
|
|
||||||
|
|
||||||
if (isHttps) {
|
|
||||||
await letsEncrypt({ domain, id });
|
|
||||||
}
|
|
||||||
await setWwwRedirection(fqdn);
|
|
||||||
await reloadHaproxy(destinationDocker.engine);
|
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { dockerInstance } from '$lib/docker';
|
import { checkContainer } from '$lib/haproxy';
|
||||||
import { checkContainer, configureSimpleServiceProxyOff } from '$lib/haproxy';
|
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const post: RequestHandler = async (event) => {
|
export const post: RequestHandler = async (event) => {
|
||||||
@ -15,7 +13,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
try {
|
try {
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const { destinationDockerId, destinationDocker, fqdn } = service;
|
const { destinationDockerId, destinationDocker, fqdn } = service;
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
if (destinationDockerId) {
|
if (destinationDockerId) {
|
||||||
const engine = destinationDocker.engine;
|
const engine = destinationDocker.engine;
|
||||||
|
|
||||||
@ -27,11 +24,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
await configureSimpleServiceProxyOff(fqdn);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -3,15 +3,6 @@ import * as db from '$lib/database';
|
|||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import { letsEncrypt } from '$lib/letsencrypt';
|
|
||||||
import {
|
|
||||||
checkHAProxy,
|
|
||||||
checkProxyConfigurations,
|
|
||||||
configureSimpleServiceProxyOn,
|
|
||||||
reloadHaproxy,
|
|
||||||
setWwwRedirection
|
|
||||||
} from '$lib/haproxy';
|
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { makeLabelForServices } from '$lib/buildPacks/common';
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
@ -22,7 +13,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
const { id } = event.params;
|
const { id } = event.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await checkHAProxy();
|
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const {
|
const {
|
||||||
type,
|
type,
|
||||||
@ -42,9 +32,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
}
|
}
|
||||||
} = service;
|
} = service;
|
||||||
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
plausibleAnalytics: {
|
plausibleAnalytics: {
|
||||||
image: `plausible/analytics:${version}`,
|
image: `plausible/analytics:${version}`,
|
||||||
@ -83,7 +70,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
};
|
};
|
||||||
const network = destinationDockerId && destinationDocker.network;
|
const network = destinationDockerId && destinationDocker.network;
|
||||||
const host = getEngine(destinationDocker.engine);
|
const host = getEngine(destinationDocker.engine);
|
||||||
const engine = destinationDocker.engine;
|
|
||||||
|
|
||||||
const { workdir } = await createDirectories({ repository: type, buildId: id });
|
const { workdir } = await createDirectories({ repository: type, buildId: id });
|
||||||
|
|
||||||
@ -187,14 +173,7 @@ 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 configureSimpleServiceProxyOn({ id, domain, port: 8000 });
|
|
||||||
|
|
||||||
if (isHttps) {
|
|
||||||
await letsEncrypt({ domain, id });
|
|
||||||
}
|
|
||||||
await setWwwRedirection(fqdn);
|
|
||||||
await reloadHaproxy(destinationDocker.engine);
|
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { dockerInstance } from '$lib/docker';
|
import { checkContainer } from '$lib/haproxy';
|
||||||
import { checkContainer, configureSimpleServiceProxyOff } from '$lib/haproxy';
|
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const post: RequestHandler = async (event) => {
|
export const post: RequestHandler = async (event) => {
|
||||||
@ -15,7 +13,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
try {
|
try {
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const { destinationDockerId, destinationDocker, fqdn } = service;
|
const { destinationDockerId, destinationDocker, fqdn } = service;
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
|
|
||||||
if (destinationDockerId) {
|
if (destinationDockerId) {
|
||||||
const engine = destinationDocker.engine;
|
const engine = destinationDocker.engine;
|
||||||
@ -36,12 +33,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
await configureSimpleServiceProxyOff(fqdn);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -3,15 +3,6 @@ import * as db from '$lib/database';
|
|||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import { letsEncrypt } from '$lib/letsencrypt';
|
|
||||||
import {
|
|
||||||
checkHAProxy,
|
|
||||||
checkProxyConfigurations,
|
|
||||||
configureSimpleServiceProxyOn,
|
|
||||||
reloadHaproxy,
|
|
||||||
setWwwRedirection
|
|
||||||
} from '$lib/haproxy';
|
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import { getServiceImage, ErrorHandler } from '$lib/database';
|
import { getServiceImage, ErrorHandler } from '$lib/database';
|
||||||
import { makeLabelForServices } from '$lib/buildPacks/common';
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
@ -22,12 +13,8 @@ export const post: RequestHandler = async (event) => {
|
|||||||
const { id } = event.params;
|
const { id } = event.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await checkHAProxy();
|
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const { type, version, fqdn, destinationDockerId, destinationDocker } = service;
|
const { type, version, destinationDockerId, destinationDocker } = service;
|
||||||
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
|
|
||||||
const network = destinationDockerId && destinationDocker.network;
|
const network = destinationDockerId && destinationDocker.network;
|
||||||
const host = getEngine(destinationDocker.engine);
|
const host = getEngine(destinationDocker.engine);
|
||||||
@ -74,14 +61,6 @@ 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 configureSimpleServiceProxyOn({ id, domain, port: 80 });
|
|
||||||
|
|
||||||
if (isHttps) {
|
|
||||||
await letsEncrypt({ domain, id });
|
|
||||||
}
|
|
||||||
await setWwwRedirection(fqdn);
|
|
||||||
await reloadHaproxy(destinationDocker.engine);
|
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { dockerInstance } from '$lib/docker';
|
import { checkContainer } from '$lib/haproxy';
|
||||||
import { checkContainer, configureSimpleServiceProxyOff } from '$lib/haproxy';
|
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const post: RequestHandler = async (event) => {
|
export const post: RequestHandler = async (event) => {
|
||||||
@ -15,7 +13,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
try {
|
try {
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const { destinationDockerId, destinationDocker, fqdn } = service;
|
const { destinationDockerId, destinationDocker, fqdn } = service;
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
if (destinationDockerId) {
|
if (destinationDockerId) {
|
||||||
const engine = destinationDocker.engine;
|
const engine = destinationDocker.engine;
|
||||||
|
|
||||||
@ -27,13 +24,7 @@ export const post: RequestHandler = async (event) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
await configureSimpleServiceProxyOff(fqdn);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
};
|
};
|
||||||
|
@ -3,15 +3,6 @@ import * as db from '$lib/database';
|
|||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import { letsEncrypt } from '$lib/letsencrypt';
|
|
||||||
import {
|
|
||||||
checkHAProxy,
|
|
||||||
checkProxyConfigurations,
|
|
||||||
configureSimpleServiceProxyOn,
|
|
||||||
reloadHaproxy,
|
|
||||||
setWwwRedirection
|
|
||||||
} from '$lib/haproxy';
|
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { makeLabelForServices } from '$lib/buildPacks/common';
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
@ -22,20 +13,15 @@ export const post: RequestHandler = async (event) => {
|
|||||||
const { id } = event.params;
|
const { id } = event.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await checkHAProxy();
|
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const {
|
const {
|
||||||
type,
|
type,
|
||||||
version,
|
version,
|
||||||
fqdn,
|
|
||||||
destinationDockerId,
|
destinationDockerId,
|
||||||
destinationDocker,
|
destinationDocker,
|
||||||
vscodeserver: { password }
|
vscodeserver: { password }
|
||||||
} = service;
|
} = service;
|
||||||
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
|
|
||||||
const network = destinationDockerId && destinationDocker.network;
|
const network = destinationDockerId && destinationDocker.network;
|
||||||
const host = getEngine(destinationDocker.engine);
|
const host = getEngine(destinationDocker.engine);
|
||||||
|
|
||||||
@ -84,14 +70,6 @@ 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 configureSimpleServiceProxyOn({ id, domain, port: 8080 });
|
|
||||||
|
|
||||||
if (isHttps) {
|
|
||||||
await letsEncrypt({ domain, id });
|
|
||||||
}
|
|
||||||
await setWwwRedirection(fqdn);
|
|
||||||
await reloadHaproxy(destinationDocker.engine);
|
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { dockerInstance } from '$lib/docker';
|
import { checkContainer } from '$lib/haproxy';
|
||||||
import { checkContainer, configureSimpleServiceProxyOff } from '$lib/haproxy';
|
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const post: RequestHandler = async (event) => {
|
export const post: RequestHandler = async (event) => {
|
||||||
@ -15,7 +13,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
try {
|
try {
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const { destinationDockerId, destinationDocker, fqdn } = service;
|
const { destinationDockerId, destinationDocker, fqdn } = service;
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
if (destinationDockerId) {
|
if (destinationDockerId) {
|
||||||
const engine = destinationDocker.engine;
|
const engine = destinationDocker.engine;
|
||||||
|
|
||||||
@ -27,11 +24,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
await configureSimpleServiceProxyOff(fqdn);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
|
@ -3,15 +3,6 @@ import * as db from '$lib/database';
|
|||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import { letsEncrypt } from '$lib/letsencrypt';
|
|
||||||
import {
|
|
||||||
checkHAProxy,
|
|
||||||
checkProxyConfigurations,
|
|
||||||
configureSimpleServiceProxyOn,
|
|
||||||
reloadHaproxy,
|
|
||||||
setWwwRedirection
|
|
||||||
} from '$lib/haproxy';
|
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { makeLabelForServices } from '$lib/buildPacks/common';
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
@ -22,7 +13,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
const { id } = event.params;
|
const { id } = event.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await checkHAProxy();
|
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const {
|
const {
|
||||||
type,
|
type,
|
||||||
@ -40,9 +30,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
}
|
}
|
||||||
} = service;
|
} = service;
|
||||||
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
|
|
||||||
const network = destinationDockerId && destinationDocker.network;
|
const network = destinationDockerId && destinationDocker.network;
|
||||||
const host = getEngine(destinationDocker.engine);
|
const host = getEngine(destinationDocker.engine);
|
||||||
|
|
||||||
@ -121,14 +108,6 @@ 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 configureSimpleServiceProxyOn({ id, domain, port: 80 });
|
|
||||||
|
|
||||||
if (isHttps) {
|
|
||||||
await letsEncrypt({ domain, id });
|
|
||||||
}
|
|
||||||
await setWwwRedirection(fqdn);
|
|
||||||
await reloadHaproxy(destinationDocker.engine);
|
|
||||||
return {
|
return {
|
||||||
status: 200
|
status: 200
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
||||||
import { getDomain } from '$lib/components/common';
|
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
import { dockerInstance } from '$lib/docker';
|
import { checkContainer } from '$lib/haproxy';
|
||||||
import { checkContainer, configureSimpleServiceProxyOff } from '$lib/haproxy';
|
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
export const post: RequestHandler = async (event) => {
|
export const post: RequestHandler = async (event) => {
|
||||||
@ -15,7 +13,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
try {
|
try {
|
||||||
const service = await db.getService({ id, teamId });
|
const service = await db.getService({ id, teamId });
|
||||||
const { destinationDockerId, destinationDocker, fqdn } = service;
|
const { destinationDockerId, destinationDocker, fqdn } = service;
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
if (destinationDockerId) {
|
if (destinationDockerId) {
|
||||||
const engine = destinationDocker.engine;
|
const engine = destinationDocker.engine;
|
||||||
try {
|
try {
|
||||||
@ -30,11 +27,6 @@ export const post: RequestHandler = async (event) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
await configureSimpleServiceProxyOff(fqdn);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,18 +1,6 @@
|
|||||||
import { dev } from '$app/env';
|
import { getUserDetails } from '$lib/common';
|
||||||
import { getDomain, getUserDetails } from '$lib/common';
|
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import { listSettings, ErrorHandler } from '$lib/database';
|
import { listSettings, ErrorHandler } from '$lib/database';
|
||||||
import {
|
|
||||||
checkProxyConfigurations,
|
|
||||||
configureCoolifyProxyOff,
|
|
||||||
configureCoolifyProxyOn,
|
|
||||||
forceSSLOnApplication,
|
|
||||||
reloadHaproxy,
|
|
||||||
removeWwwRedirection,
|
|
||||||
setWwwRedirection,
|
|
||||||
startCoolifyProxy
|
|
||||||
} from '$lib/haproxy';
|
|
||||||
import { letsEncrypt } from '$lib/letsencrypt';
|
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import { promises as dns } from 'dns';
|
import { promises as dns } from 'dns';
|
||||||
|
|
||||||
@ -52,10 +40,7 @@ export const del: RequestHandler = async (event) => {
|
|||||||
// Do not care.
|
// Do not care.
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
await db.prisma.setting.update({ where: { fqdn }, data: { fqdn: null } });
|
await db.prisma.setting.update({ where: { fqdn }, data: { fqdn: null } });
|
||||||
await configureCoolifyProxyOff(fqdn);
|
|
||||||
await removeWwwRedirection(domain);
|
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: {
|
body: {
|
||||||
@ -80,50 +65,19 @@ export const post: RequestHandler = async (event) => {
|
|||||||
|
|
||||||
const { fqdn, isRegistrationEnabled, dualCerts, minPort, maxPort } = await event.request.json();
|
const { fqdn, isRegistrationEnabled, dualCerts, minPort, maxPort } = await event.request.json();
|
||||||
try {
|
try {
|
||||||
await checkProxyConfigurations();
|
const { id } = await db.listSettings();
|
||||||
const {
|
if (isRegistrationEnabled) {
|
||||||
id,
|
|
||||||
fqdn: oldFqdn,
|
|
||||||
isRegistrationEnabled: oldIsRegistrationEnabled,
|
|
||||||
dualCerts: oldDualCerts
|
|
||||||
} = await db.listSettings();
|
|
||||||
if (oldIsRegistrationEnabled !== isRegistrationEnabled) {
|
|
||||||
await db.prisma.setting.update({ where: { id }, data: { isRegistrationEnabled } });
|
await db.prisma.setting.update({ where: { id }, data: { isRegistrationEnabled } });
|
||||||
}
|
}
|
||||||
if (oldDualCerts !== dualCerts) {
|
|
||||||
await db.prisma.setting.update({ where: { id }, data: { dualCerts } });
|
|
||||||
}
|
|
||||||
if (oldFqdn && oldFqdn !== fqdn) {
|
|
||||||
if (oldFqdn) {
|
|
||||||
const oldDomain = getDomain(oldFqdn);
|
|
||||||
await configureCoolifyProxyOff(oldFqdn);
|
|
||||||
await removeWwwRedirection(oldDomain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fqdn) {
|
if (fqdn) {
|
||||||
await startCoolifyProxy('/var/run/docker.sock');
|
|
||||||
const domain = getDomain(fqdn);
|
|
||||||
const isHttps = fqdn.startsWith('https://');
|
|
||||||
if (domain) {
|
|
||||||
await configureCoolifyProxyOn(fqdn);
|
|
||||||
await setWwwRedirection(fqdn);
|
|
||||||
if (isHttps) {
|
|
||||||
await letsEncrypt({ domain, isCoolify: true });
|
|
||||||
await forceSSLOnApplication(domain);
|
|
||||||
await reloadHaproxy('/var/run/docker.sock');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await db.prisma.setting.update({ where: { id }, data: { fqdn } });
|
await db.prisma.setting.update({ where: { id }, data: { fqdn } });
|
||||||
await db.prisma.destinationDocker.updateMany({
|
}
|
||||||
where: { engine: '/var/run/docker.sock' },
|
if (dualCerts) {
|
||||||
data: { isCoolifyProxyUsed: true }
|
await db.prisma.setting.update({ where: { id }, data: { dualCerts } });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (minPort && maxPort) {
|
if (minPort && maxPort) {
|
||||||
await db.prisma.setting.update({ where: { id }, data: { minPort, maxPort } });
|
await db.prisma.setting.update({ where: { id }, data: { minPort, maxPort } });
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 201
|
status: 201
|
||||||
};
|
};
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
if (fqdn !== settings.fqdn) {
|
if (fqdn !== settings.fqdn) {
|
||||||
await post(`/settings/check.json`, { fqdn });
|
await post(`/settings/check.json`, { fqdn });
|
||||||
await post(`/settings.json`, { fqdn });
|
await post(`/settings.json`, { fqdn });
|
||||||
|
return window.location.reload();
|
||||||
}
|
}
|
||||||
if (minPort !== settings.minPort || maxPort !== settings.maxPort) {
|
if (minPort !== settings.minPort || maxPort !== settings.maxPort) {
|
||||||
await post(`/settings.json`, { minPort, maxPort });
|
await post(`/settings.json`, { minPort, maxPort });
|
||||||
@ -98,7 +99,7 @@
|
|||||||
{#if $session.teamId === '0'}
|
{#if $session.teamId === '0'}
|
||||||
<div class="mx-auto max-w-4xl px-6">
|
<div class="mx-auto max-w-4xl px-6">
|
||||||
<form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4">
|
<form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4">
|
||||||
<div class="flex space-x-1 py-6">
|
<div class="flex space-x-1 pb-6">
|
||||||
<div class="title font-bold">Global Settings</div>
|
<div class="title font-bold">Global Settings</div>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
@ -12,7 +12,7 @@ export const get: RequestHandler = async () => {
|
|||||||
const versions = await got
|
const versions = await got
|
||||||
.get(`https://get.coollabs.io/versions.json?appId=${process.env['COOLIFY_APP_ID']}`)
|
.get(`https://get.coollabs.io/versions.json?appId=${process.env['COOLIFY_APP_ID']}`)
|
||||||
.json();
|
.json();
|
||||||
const latestVersion = dev ? '10.0.0' : versions['coolify'].main.version;
|
const latestVersion = versions['coolify'].main.version;
|
||||||
const isUpdateAvailable = compare(latestVersion, currentVersion);
|
const isUpdateAvailable = compare(latestVersion, currentVersion);
|
||||||
return {
|
return {
|
||||||
body: {
|
body: {
|
||||||
@ -26,27 +26,11 @@ export const get: RequestHandler = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const post: RequestHandler = async (event) => {
|
export const post: RequestHandler = async (event) => {
|
||||||
const { type, latestVersion } = await event.request.json();
|
const { type, latestVersion, overrideVersion } = await event.request.json();
|
||||||
if (type === 'pull') {
|
if (type === 'update') {
|
||||||
try {
|
try {
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
await asyncExecShell(`docker pull coollabsio/coolify:${latestVersion}`);
|
await asyncExecShell(`docker pull coollabsio/coolify:${latestVersion}`);
|
||||||
return {
|
|
||||||
status: 200,
|
|
||||||
body: {}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
status: 200,
|
|
||||||
body: {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
return ErrorHandler(error);
|
|
||||||
}
|
|
||||||
} else if (type === 'update') {
|
|
||||||
try {
|
|
||||||
if (!dev) {
|
|
||||||
await asyncExecShell(`env | grep COOLIFY > .env`);
|
await asyncExecShell(`env | grep COOLIFY > .env`);
|
||||||
await asyncExecShell(
|
await asyncExecShell(
|
||||||
`docker run --rm -tid --env-file .env -v /var/run/docker.sock:/var/run/docker.sock -v coolify-db coollabsio/coolify:${latestVersion} /bin/sh -c "env | grep COOLIFY > .env && echo 'TAG=${latestVersion}' >> .env && docker stop -t 0 coolify coolify-redis && docker rm coolify coolify-redis && docker compose up -d --force-recreate"`
|
`docker run --rm -tid --env-file .env -v /var/run/docker.sock:/var/run/docker.sock -v coolify-db coollabsio/coolify:${latestVersion} /bin/sh -c "env | grep COOLIFY > .env && echo 'TAG=${latestVersion}' >> .env && docker stop -t 0 coolify coolify-redis && docker rm coolify coolify-redis && docker compose up -d --force-recreate"`
|
||||||
@ -66,6 +50,31 @@ export const post: RequestHandler = async (event) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
return ErrorHandler(error);
|
return ErrorHandler(error);
|
||||||
}
|
}
|
||||||
|
} else if (type === 'check') {
|
||||||
|
try {
|
||||||
|
if (overrideVersion) {
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
exists: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
await asyncExecShell(`docker image inspect coollabsio/coolify:${latestVersion}`);
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
exists: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
exists: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
status: 500
|
status: 500
|
||||||
|
@ -4,7 +4,7 @@ import type { RequestHandler } from '@sveltejs/kit';
|
|||||||
import cuid from 'cuid';
|
import cuid from 'cuid';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import { buildQueue } from '$lib/queues';
|
import { buildQueue } from '$lib/queues';
|
||||||
import { checkContainer, removeProxyConfiguration } from '$lib/haproxy';
|
import { checkContainer } from '$lib/haproxy';
|
||||||
import { dev } from '$app/env';
|
import { dev } from '$app/env';
|
||||||
|
|
||||||
export const options: RequestHandler = async () => {
|
export const options: RequestHandler = async () => {
|
||||||
@ -84,6 +84,10 @@ export const post: RequestHandler = async (event) => {
|
|||||||
data: { configHash }
|
data: { configHash }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
await db.prisma.application.update({
|
||||||
|
where: { id: applicationFound.id },
|
||||||
|
data: { updatedAt: new Date() }
|
||||||
|
});
|
||||||
await buildQueue.add(buildId, {
|
await buildQueue.add(buildId, {
|
||||||
build_id: buildId,
|
build_id: buildId,
|
||||||
type: 'webhook_commit',
|
type: 'webhook_commit',
|
||||||
@ -128,6 +132,10 @@ export const post: RequestHandler = async (event) => {
|
|||||||
pullmergeRequestAction === 'reopened' ||
|
pullmergeRequestAction === 'reopened' ||
|
||||||
pullmergeRequestAction === 'synchronize'
|
pullmergeRequestAction === 'synchronize'
|
||||||
) {
|
) {
|
||||||
|
await db.prisma.application.update({
|
||||||
|
where: { id: applicationFound.id },
|
||||||
|
data: { updatedAt: new Date() }
|
||||||
|
});
|
||||||
await buildQueue.add(buildId, {
|
await buildQueue.add(buildId, {
|
||||||
build_id: buildId,
|
build_id: buildId,
|
||||||
type: 'webhook_pr',
|
type: 'webhook_pr',
|
||||||
@ -143,18 +151,9 @@ export const post: RequestHandler = async (event) => {
|
|||||||
};
|
};
|
||||||
} else if (pullmergeRequestAction === 'closed') {
|
} else if (pullmergeRequestAction === 'closed') {
|
||||||
if (applicationFound.destinationDockerId) {
|
if (applicationFound.destinationDockerId) {
|
||||||
const domain = getDomain(applicationFound.fqdn);
|
|
||||||
const isHttps = applicationFound.fqdn.startsWith('https://');
|
|
||||||
const isWWW = applicationFound.fqdn.includes('www.');
|
|
||||||
const fqdn = `${isHttps ? 'https://' : 'http://'}${
|
|
||||||
isWWW ? 'www.' : ''
|
|
||||||
}${pullmergeRequestId}.${domain}`;
|
|
||||||
|
|
||||||
const id = `${applicationFound.id}-${pullmergeRequestId}`;
|
const id = `${applicationFound.id}-${pullmergeRequestId}`;
|
||||||
const engine = applicationFound.destinationDocker.engine;
|
const engine = applicationFound.destinationDocker.engine;
|
||||||
|
|
||||||
await removeDestinationDocker({ id, engine });
|
await removeDestinationDocker({ id, engine });
|
||||||
await removeProxyConfiguration(fqdn);
|
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { getTeam, getUserDetails, getDomain, removeDestinationDocker } from '$lib/common';
|
import { getTeam, getUserDetails, getDomain, removeDestinationDocker } from '$lib/common';
|
||||||
import { checkContainer, removeProxyConfiguration } from '$lib/haproxy';
|
import { checkContainer } from '$lib/haproxy';
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import cuid from 'cuid';
|
import cuid from 'cuid';
|
||||||
@ -48,6 +48,10 @@ export const post: RequestHandler = async (event) => {
|
|||||||
data: { configHash }
|
data: { configHash }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
await db.prisma.application.update({
|
||||||
|
where: { id: applicationFound.id },
|
||||||
|
data: { updatedAt: new Date() }
|
||||||
|
});
|
||||||
await buildQueue.add(buildId, {
|
await buildQueue.add(buildId, {
|
||||||
build_id: buildId,
|
build_id: buildId,
|
||||||
type: 'webhook_commit',
|
type: 'webhook_commit',
|
||||||
@ -125,6 +129,10 @@ export const post: RequestHandler = async (event) => {
|
|||||||
action === 'open' ||
|
action === 'open' ||
|
||||||
action === 'update'
|
action === 'update'
|
||||||
) {
|
) {
|
||||||
|
await db.prisma.application.update({
|
||||||
|
where: { id: applicationFound.id },
|
||||||
|
data: { updatedAt: new Date() }
|
||||||
|
});
|
||||||
await buildQueue.add(buildId, {
|
await buildQueue.add(buildId, {
|
||||||
build_id: buildId,
|
build_id: buildId,
|
||||||
type: 'webhook_mr',
|
type: 'webhook_mr',
|
||||||
@ -140,18 +148,9 @@ export const post: RequestHandler = async (event) => {
|
|||||||
};
|
};
|
||||||
} else if (action === 'close') {
|
} else if (action === 'close') {
|
||||||
if (applicationFound.destinationDockerId) {
|
if (applicationFound.destinationDockerId) {
|
||||||
const domain = getDomain(applicationFound.fqdn);
|
|
||||||
const isHttps = applicationFound.fqdn.startsWith('https://');
|
|
||||||
const isWWW = applicationFound.fqdn.includes('www.');
|
|
||||||
const fqdn = `${isHttps ? 'https://' : 'http://'}${
|
|
||||||
isWWW ? 'www.' : ''
|
|
||||||
}${pullmergeRequestId}.${domain}`;
|
|
||||||
|
|
||||||
const id = `${applicationFound.id}-${pullmergeRequestId}`;
|
const id = `${applicationFound.id}-${pullmergeRequestId}`;
|
||||||
const engine = applicationFound.destinationDocker.engine;
|
const engine = applicationFound.destinationDocker.engine;
|
||||||
|
|
||||||
await removeDestinationDocker({ id, engine });
|
await removeDestinationDocker({ id, engine });
|
||||||
await removeProxyConfiguration(fqdn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user