fix: Some nasty bug
fix: Automatic reconfiguration of all services and service proxies
This commit is contained in:
parent
3ae7624361
commit
531c712ea5
@ -74,26 +74,12 @@ export async function makeLabelForStandaloneDatabase({ id, image, volume }) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function makeLabelForPlausibleAnalytics({ id, images, volume }) {
|
export function makeLabelForServices(type) {
|
||||||
const service = await db.prisma.service.findFirst({
|
|
||||||
where: { id },
|
|
||||||
include: { plausibleAnalytics: true }
|
|
||||||
});
|
|
||||||
delete service.destinationDockerId;
|
|
||||||
delete service.createdAt;
|
|
||||||
delete service.updatedAt;
|
|
||||||
return [
|
return [
|
||||||
'coolify.managed=true',
|
'coolify.managed=true',
|
||||||
`coolify.version=${version}`,
|
`coolify.version=${version}`,
|
||||||
`coolify.type=service-plausibleanalytics`,
|
`coolify.type=service`,
|
||||||
`coolify.configuration=${base64Encode(
|
`coolify.service.type=${type}`
|
||||||
JSON.stringify({
|
|
||||||
version,
|
|
||||||
images,
|
|
||||||
volume,
|
|
||||||
...service
|
|
||||||
})
|
|
||||||
)}`
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,27 +114,55 @@ export const supportedServiceTypesAndVersions = [
|
|||||||
name: 'plausibleanalytics',
|
name: 'plausibleanalytics',
|
||||||
fancyName: 'Plausible Analytics',
|
fancyName: 'Plausible Analytics',
|
||||||
baseImage: 'plausible/analytics',
|
baseImage: 'plausible/analytics',
|
||||||
versions: ['latest']
|
versions: ['latest'],
|
||||||
|
ports: {
|
||||||
|
main: 8000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'nocodb',
|
||||||
|
fancyName: 'NocoDB',
|
||||||
|
baseImage: 'nocodb/nocodb',
|
||||||
|
versions: ['latest'],
|
||||||
|
ports: {
|
||||||
|
main: 8080
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'minio',
|
||||||
|
fancyName: 'MinIO',
|
||||||
|
baseImage: 'minio/minio',
|
||||||
|
versions: ['latest'],
|
||||||
|
ports: {
|
||||||
|
main: 9001
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ name: 'nocodb', fancyName: 'NocoDB', baseImage: 'nocodb/nocodb', versions: ['latest'] },
|
|
||||||
{ name: 'minio', fancyName: 'MinIO', baseImage: 'minio/minio', versions: ['latest'] },
|
|
||||||
{
|
{
|
||||||
name: 'vscodeserver',
|
name: 'vscodeserver',
|
||||||
fancyName: 'VSCode Server',
|
fancyName: 'VSCode Server',
|
||||||
baseImage: 'codercom/code-server',
|
baseImage: 'codercom/code-server',
|
||||||
versions: ['latest']
|
versions: ['latest'],
|
||||||
|
ports: {
|
||||||
|
main: 8080
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'wordpress',
|
name: 'wordpress',
|
||||||
fancyName: 'Wordpress',
|
fancyName: 'Wordpress',
|
||||||
baseImage: 'wordpress',
|
baseImage: 'wordpress',
|
||||||
versions: ['latest', 'php8.1', 'php8.0', 'php7.4', 'php7.3']
|
versions: ['latest', 'php8.1', 'php8.0', 'php7.4', 'php7.3'],
|
||||||
|
ports: {
|
||||||
|
main: 80
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'vaultwarden',
|
name: 'vaultwarden',
|
||||||
fancyName: 'Vaultwarden',
|
fancyName: 'Vaultwarden',
|
||||||
baseImage: 'vaultwarden/server',
|
baseImage: 'vaultwarden/server',
|
||||||
versions: ['latest']
|
versions: ['latest'],
|
||||||
|
ports: {
|
||||||
|
main: 80
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -509,46 +509,60 @@ export async function configureNetworkCoolifyProxy(engine) {
|
|||||||
export async function configureSimpleServiceProxyOn({ id, domain, port }) {
|
export async function configureSimpleServiceProxyOn({ id, domain, port }) {
|
||||||
const haproxy = await haproxyInstance();
|
const haproxy = await haproxyInstance();
|
||||||
await checkHAProxy(haproxy);
|
await checkHAProxy(haproxy);
|
||||||
|
let serverConfigured = false;
|
||||||
|
let backendAvailable: any = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await haproxy.get(`v2/services/haproxy/configuration/backends/${domain}`).json();
|
backendAvailable = await haproxy
|
||||||
const transactionId = await getNextTransactionId();
|
.get(`v2/services/haproxy/configuration/backends/${domain}`)
|
||||||
await haproxy
|
.json();
|
||||||
.delete(`v2/services/haproxy/configuration/backends/${domain}`, {
|
const server: any = await haproxy
|
||||||
|
.get(`v2/services/haproxy/configuration/servers/${id}`, {
|
||||||
searchParams: {
|
searchParams: {
|
||||||
transaction_id: transactionId
|
backend: domain
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.json();
|
.json();
|
||||||
await completeTransaction(transactionId);
|
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) {}
|
} catch (error) {}
|
||||||
try {
|
if (serverConfigured) return;
|
||||||
const transactionId = await getNextTransactionId();
|
const transactionId = await getNextTransactionId();
|
||||||
await haproxy.post('v2/services/haproxy/configuration/backends', {
|
await haproxy.post('v2/services/haproxy/configuration/backends', {
|
||||||
searchParams: {
|
searchParams: {
|
||||||
transaction_id: transactionId
|
transaction_id: transactionId
|
||||||
},
|
},
|
||||||
json: {
|
json: {
|
||||||
'init-addr': 'last,libc,none',
|
'init-addr': 'last,libc,none',
|
||||||
forwardfor: { enabled: 'enabled' },
|
forwardfor: { enabled: 'enabled' },
|
||||||
name: domain
|
name: domain
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await haproxy.post('v2/services/haproxy/configuration/servers', {
|
await haproxy.post('v2/services/haproxy/configuration/servers', {
|
||||||
searchParams: {
|
searchParams: {
|
||||||
transaction_id: transactionId,
|
transaction_id: transactionId,
|
||||||
backend: domain
|
backend: domain
|
||||||
},
|
},
|
||||||
json: {
|
json: {
|
||||||
address: id,
|
address: id,
|
||||||
check: 'enabled',
|
check: 'enabled',
|
||||||
name: id,
|
name: id,
|
||||||
port: port
|
port: port
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await completeTransaction(transactionId);
|
await completeTransaction(transactionId);
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function configureSimpleServiceProxyOff({ domain }) {
|
export async function configureSimpleServiceProxyOff({ domain }) {
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { getDomain } from '$lib/common';
|
import { getDomain } from '$lib/common';
|
||||||
import { getApplicationById, prisma } from '$lib/database';
|
import { getApplicationById, prisma, supportedServiceTypesAndVersions } from '$lib/database';
|
||||||
import { dockerInstance } from '$lib/docker';
|
import { dockerInstance } from '$lib/docker';
|
||||||
import {
|
import {
|
||||||
checkContainer,
|
checkContainer,
|
||||||
configureCoolifyProxyOn,
|
configureCoolifyProxyOn,
|
||||||
configureProxyForApplication,
|
configureProxyForApplication,
|
||||||
|
configureSimpleServiceProxyOn,
|
||||||
forceSSLOnApplication,
|
forceSSLOnApplication,
|
||||||
reloadHaproxy,
|
reloadHaproxy,
|
||||||
setWwwRedirection,
|
setWwwRedirection,
|
||||||
startCoolifyProxy
|
startCoolifyProxy,
|
||||||
|
startHttpProxy
|
||||||
} from '$lib/haproxy';
|
} from '$lib/haproxy';
|
||||||
import * as db from '$lib/database';
|
import * as db from '$lib/database';
|
||||||
|
|
||||||
@ -24,35 +26,70 @@ export default async function () {
|
|||||||
(container) => container.Labels['coolify.managed']
|
(container) => container.Labels['coolify.managed']
|
||||||
);
|
);
|
||||||
for (const configuration of configurations) {
|
for (const configuration of configurations) {
|
||||||
const parsedConfiguration = JSON.parse(
|
if (configuration.Labels['coolify.configuration']) {
|
||||||
Buffer.from(configuration.Labels['coolify.configuration'], 'base64').toString()
|
const parsedConfiguration = JSON.parse(
|
||||||
);
|
Buffer.from(configuration.Labels['coolify.configuration'], 'base64').toString()
|
||||||
if (
|
);
|
||||||
parsedConfiguration &&
|
if (
|
||||||
configuration.Labels['coolify.type'] === 'standalone-application'
|
parsedConfiguration &&
|
||||||
) {
|
configuration.Labels['coolify.type'] === 'standalone-application'
|
||||||
const { fqdn, applicationId, port, pullmergeRequestId } = parsedConfiguration;
|
) {
|
||||||
if (fqdn) {
|
const { fqdn, applicationId, port, pullmergeRequestId } = parsedConfiguration;
|
||||||
const found = await getApplicationById({ id: applicationId });
|
if (fqdn) {
|
||||||
if (found) {
|
const found = await getApplicationById({ id: applicationId });
|
||||||
const domain = getDomain(fqdn);
|
if (found) {
|
||||||
await configureProxyForApplication({
|
const domain = getDomain(fqdn);
|
||||||
domain,
|
await configureProxyForApplication({
|
||||||
imageId: pullmergeRequestId
|
domain,
|
||||||
? `${applicationId}-${pullmergeRequestId}`
|
imageId: pullmergeRequestId
|
||||||
: applicationId,
|
? `${applicationId}-${pullmergeRequestId}`
|
||||||
applicationId,
|
: applicationId,
|
||||||
port
|
applicationId,
|
||||||
});
|
port
|
||||||
const isHttps = fqdn.startsWith('https://');
|
});
|
||||||
if (isHttps) await forceSSLOnApplication({ domain });
|
const isHttps = fqdn.startsWith('https://');
|
||||||
await setWwwRedirection(fqdn);
|
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
|
// Check Coolify FQDN and configure proxy if needed
|
||||||
const { fqdn } = await db.listSettings();
|
const { fqdn } = await db.listSettings();
|
||||||
if (fqdn) {
|
if (fqdn) {
|
||||||
|
@ -102,17 +102,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function forceRestartProxy() {
|
async function forceRestartProxy() {
|
||||||
try {
|
const sure = confirm(
|
||||||
restarting = true;
|
'Are you sure you want to restart the proxy? Everyting will be reconfigured in ~10 sec.'
|
||||||
toast.push('Coolify Proxy restarting...');
|
);
|
||||||
await post(`/destinations/${id}/restart.json`, {
|
if (sure) {
|
||||||
engine: destination.engine,
|
try {
|
||||||
fqdn: settings.fqdn
|
restarting = true;
|
||||||
});
|
toast.push('Coolify Proxy restarting...');
|
||||||
} catch ({ error }) {
|
await post(`/destinations/${id}/restart.json`, {
|
||||||
setTimeout(() => {
|
engine: destination.engine,
|
||||||
window.location.reload();
|
fqdn: settings.fqdn
|
||||||
}, 5000);
|
});
|
||||||
|
} catch ({ error }) {
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.reload();
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
import getPort from 'get-port';
|
import getPort 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';
|
||||||
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
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);
|
||||||
@ -63,7 +64,8 @@ export const post: RequestHandler = async (event) => {
|
|||||||
environment: config.environmentVariables,
|
environment: config.environmentVariables,
|
||||||
networks: [network],
|
networks: [network],
|
||||||
volumes: [config.volume],
|
volumes: [config.volume],
|
||||||
restart: 'always'
|
restart: 'always',
|
||||||
|
labels: makeLabelForServices('minio')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
networks: {
|
networks: {
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
} from '$lib/haproxy';
|
} from '$lib/haproxy';
|
||||||
import { getDomain } from '$lib/components/common';
|
import { getDomain } from '$lib/components/common';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
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);
|
||||||
@ -39,7 +40,8 @@ export const post: RequestHandler = async (event) => {
|
|||||||
container_name: id,
|
container_name: id,
|
||||||
image: `nocodb/nocodb:${version}`,
|
image: `nocodb/nocodb:${version}`,
|
||||||
networks: [network],
|
networks: [network],
|
||||||
restart: 'always'
|
restart: 'always',
|
||||||
|
labels: makeLabelForServices('nocodb')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
networks: {
|
networks: {
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
} from '$lib/haproxy';
|
} from '$lib/haproxy';
|
||||||
import { getDomain } from '$lib/components/common';
|
import { getDomain } from '$lib/components/common';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
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);
|
||||||
@ -82,7 +83,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 engine = destinationDocker.engine;
|
||||||
// const labels = await makeLabelForPlausibleAnalytics({ id, })
|
|
||||||
|
|
||||||
const { workdir } = await createDirectories({ repository: type, buildId: id });
|
const { workdir } = await createDirectories({ repository: type, buildId: id });
|
||||||
|
|
||||||
@ -138,7 +138,8 @@ COPY ./init-db.sh /docker-entrypoint-initdb.d/init-db.sh`;
|
|||||||
environment: config.plausibleAnalytics.environmentVariables,
|
environment: config.plausibleAnalytics.environmentVariables,
|
||||||
volumes: [config.postgresql.volume],
|
volumes: [config.postgresql.volume],
|
||||||
restart: 'always',
|
restart: 'always',
|
||||||
depends_on: [`${id}-postgresql`, `${id}-clickhouse`]
|
depends_on: [`${id}-postgresql`, `${id}-clickhouse`],
|
||||||
|
labels: makeLabelForServices('plausibleAnalytics')
|
||||||
},
|
},
|
||||||
[`${id}-postgresql`]: {
|
[`${id}-postgresql`]: {
|
||||||
container_name: `${id}-postgresql`,
|
container_name: `${id}-postgresql`,
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
} from '$lib/haproxy';
|
} from '$lib/haproxy';
|
||||||
import { getDomain } from '$lib/components/common';
|
import { getDomain } from '$lib/components/common';
|
||||||
import { getServiceImage, ErrorHandler } from '$lib/database';
|
import { getServiceImage, ErrorHandler } from '$lib/database';
|
||||||
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
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);
|
||||||
@ -46,7 +47,8 @@ export const post: RequestHandler = async (event) => {
|
|||||||
image: config.image,
|
image: config.image,
|
||||||
networks: [network],
|
networks: [network],
|
||||||
volumes: [config.volume],
|
volumes: [config.volume],
|
||||||
restart: 'always'
|
restart: 'always',
|
||||||
|
labels: makeLabelForServices('vaultWarden')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
networks: {
|
networks: {
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
} from '$lib/haproxy';
|
} from '$lib/haproxy';
|
||||||
import { getDomain } from '$lib/components/common';
|
import { getDomain } from '$lib/components/common';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
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);
|
||||||
@ -54,7 +55,8 @@ export const post: RequestHandler = async (event) => {
|
|||||||
environment: config.environmentVariables,
|
environment: config.environmentVariables,
|
||||||
networks: [network],
|
networks: [network],
|
||||||
volumes: [config.volume],
|
volumes: [config.volume],
|
||||||
restart: 'always'
|
restart: 'always',
|
||||||
|
labels: makeLabelForServices('vscodeServer')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
networks: {
|
networks: {
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
} from '$lib/haproxy';
|
} from '$lib/haproxy';
|
||||||
import { getDomain } from '$lib/components/common';
|
import { getDomain } from '$lib/components/common';
|
||||||
import { ErrorHandler } from '$lib/database';
|
import { ErrorHandler } from '$lib/database';
|
||||||
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
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);
|
||||||
@ -78,7 +79,8 @@ export const post: RequestHandler = async (event) => {
|
|||||||
environment: config.wordpress.environmentVariables,
|
environment: config.wordpress.environmentVariables,
|
||||||
networks: [network],
|
networks: [network],
|
||||||
restart: 'always',
|
restart: 'always',
|
||||||
depends_on: [`${id}-mysql`]
|
depends_on: [`${id}-mysql`],
|
||||||
|
labels: makeLabelForServices('wordpress')
|
||||||
},
|
},
|
||||||
[`${id}-mysql`]: {
|
[`${id}-mysql`]: {
|
||||||
container_name: `${id}-mysql`,
|
container_name: `${id}-mysql`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user