167 lines
4.0 KiB
TypeScript
167 lines
4.0 KiB
TypeScript
import Fastify from 'fastify';
|
|
import cors from '@fastify/cors';
|
|
import serve from '@fastify/static';
|
|
import env from '@fastify/env';
|
|
import cookie from '@fastify/cookie';
|
|
import path, { join } from 'path';
|
|
import autoLoad from '@fastify/autoload';
|
|
import { asyncExecShell, isDev, listSettings, prisma } from './lib/common';
|
|
import { scheduler } from './lib/scheduler';
|
|
|
|
declare module 'fastify' {
|
|
interface FastifyInstance {
|
|
config: {
|
|
COOLIFY_APP_ID: string,
|
|
COOLIFY_SECRET_KEY: string,
|
|
COOLIFY_DATABASE_URL: string,
|
|
COOLIFY_SENTRY_DSN: string,
|
|
COOLIFY_IS_ON: string,
|
|
COOLIFY_WHITE_LABELED: string,
|
|
COOLIFY_WHITE_LABELED_ICON: string | null,
|
|
COOLIFY_AUTO_UPDATE: string,
|
|
};
|
|
}
|
|
}
|
|
|
|
const port = isDev ? 3001 : 3000;
|
|
const host = '0.0.0.0';
|
|
const fastify = Fastify({
|
|
logger: false,
|
|
trustProxy: true
|
|
});
|
|
const schema = {
|
|
type: 'object',
|
|
required: ['COOLIFY_SECRET_KEY', 'COOLIFY_DATABASE_URL', 'COOLIFY_IS_ON'],
|
|
properties: {
|
|
COOLIFY_APP_ID: {
|
|
type: 'string',
|
|
},
|
|
COOLIFY_SECRET_KEY: {
|
|
type: 'string',
|
|
},
|
|
COOLIFY_DATABASE_URL: {
|
|
type: 'string',
|
|
default: 'file:../db/dev.db'
|
|
},
|
|
COOLIFY_SENTRY_DSN: {
|
|
type: 'string',
|
|
default: null
|
|
},
|
|
COOLIFY_IS_ON: {
|
|
type: 'string',
|
|
default: 'docker'
|
|
},
|
|
COOLIFY_WHITE_LABELED: {
|
|
type: 'string',
|
|
default: 'false'
|
|
},
|
|
COOLIFY_WHITE_LABELED_ICON: {
|
|
type: 'string',
|
|
default: null
|
|
},
|
|
COOLIFY_AUTO_UPDATE: {
|
|
type: 'string',
|
|
default: 'false'
|
|
},
|
|
|
|
}
|
|
};
|
|
|
|
const options = {
|
|
schema,
|
|
dotenv: true
|
|
};
|
|
fastify.register(env, options);
|
|
if (!isDev) {
|
|
fastify.register(serve, {
|
|
root: path.join(__dirname, './public'),
|
|
preCompressed: true
|
|
});
|
|
fastify.setNotFoundHandler(async function (request, reply) {
|
|
if (request.raw.url && request.raw.url.startsWith('/api')) {
|
|
return reply.status(404).send({
|
|
success: false
|
|
});
|
|
}
|
|
return reply.status(200).sendFile('index.html');
|
|
});
|
|
}
|
|
fastify.register(autoLoad, {
|
|
dir: join(__dirname, 'plugins')
|
|
});
|
|
fastify.register(autoLoad, {
|
|
dir: join(__dirname, 'routes')
|
|
});
|
|
|
|
fastify.register(cookie)
|
|
fastify.register(cors);
|
|
fastify.listen({ port, host }, async (err: any, address: any) => {
|
|
if (err) {
|
|
console.error(err);
|
|
process.exit(1);
|
|
}
|
|
console.log(`Coolify's API is listening on ${host}:${port}`);
|
|
await initServer();
|
|
await scheduler.start('deployApplication');
|
|
await scheduler.start('cleanupStorage');
|
|
await scheduler.start('checkProxies');
|
|
|
|
// Check if no build is running
|
|
|
|
// Check for update
|
|
setInterval(async () => {
|
|
const { isAutoUpdateEnabled } = await prisma.setting.findFirst();
|
|
if (isAutoUpdateEnabled) {
|
|
if (scheduler.workers.has('deployApplication')) {
|
|
scheduler.workers.get('deployApplication').postMessage("status:autoUpdater");
|
|
}
|
|
}
|
|
}, 60000 * 15)
|
|
|
|
// Cleanup storage
|
|
setInterval(async () => {
|
|
if (scheduler.workers.has('deployApplication')) {
|
|
scheduler.workers.get('deployApplication').postMessage("status:cleanupStorage");
|
|
}
|
|
}, 60000 * 10)
|
|
|
|
scheduler.on('worker deleted', async (name) => {
|
|
if (name === 'autoUpdater' || name === 'cleanupStorage') {
|
|
if (!scheduler.workers.has('deployApplication')) await scheduler.start('deployApplication');
|
|
}
|
|
});
|
|
await getArch();
|
|
await getIPAddress();
|
|
});
|
|
async function getIPAddress() {
|
|
const { publicIpv4, publicIpv6 } = await import('public-ip')
|
|
try {
|
|
const settings = await listSettings();
|
|
if (!settings.ipv4) {
|
|
const ipv4 = await publicIpv4({ timeout: 2000 })
|
|
await prisma.setting.update({ where: { id: settings.id }, data: { ipv4 } })
|
|
}
|
|
|
|
if (!settings.ipv6) {
|
|
const ipv6 = await publicIpv6({ timeout: 2000 })
|
|
await prisma.setting.update({ where: { id: settings.id }, data: { ipv6 } })
|
|
}
|
|
|
|
} catch (error) { }
|
|
}
|
|
async function initServer() {
|
|
try {
|
|
await asyncExecShell(`docker network create --attachable coolify`);
|
|
} catch (error) { }
|
|
}
|
|
async function getArch() {
|
|
try {
|
|
const settings = await prisma.setting.findFirst({})
|
|
if (settings && !settings.arch) {
|
|
await prisma.setting.update({ where: { id: settings.id }, data: { arch: process.arch } })
|
|
}
|
|
} catch (error) { }
|
|
}
|
|
|
|
|