test ws
This commit is contained in:
@@ -6,6 +6,8 @@ import cookie from '@fastify/cookie';
|
||||
import multipart from '@fastify/multipart';
|
||||
import path, { join } from 'path';
|
||||
import autoLoad from '@fastify/autoload';
|
||||
import websocket from '@fastify/websocket';
|
||||
|
||||
import { asyncExecShell, cleanupDockerStorage, createRemoteEngineConfiguration, decrypt, encrypt, executeDockerCmd, executeSSHCmd, generateDatabaseConfiguration, getDomain, isDev, listSettings, prisma, startTraefikProxy, startTraefikTCPProxy, version } from './lib/common';
|
||||
import { scheduler } from './lib/scheduler';
|
||||
import { compareVersions } from 'compare-versions';
|
||||
@@ -16,6 +18,8 @@ import { verifyRemoteDockerEngineFn } from './routes/api/v1/destinations/handler
|
||||
import { checkContainer } from './lib/docker';
|
||||
import { migrateServicesToNewTemplate } from './lib';
|
||||
import { refreshTags, refreshTemplates } from './routes/api/v1/handlers';
|
||||
import { realtime } from './routes/realtime';
|
||||
import cuid from 'cuid';
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
config: {
|
||||
@@ -105,6 +109,23 @@ const host = '0.0.0.0';
|
||||
});
|
||||
fastify.register(cookie)
|
||||
fastify.register(cors);
|
||||
fastify.register(websocket, {
|
||||
options: {
|
||||
clientTracking: true,
|
||||
verifyClient: async (info, next) => {
|
||||
try {
|
||||
const token = info.req.headers?.cookie.split('; ').find((cookie) => cookie.startsWith('token')).split('=')[1];
|
||||
if (!token) {
|
||||
return next(false)
|
||||
}
|
||||
fastify.jwt.verify(token)
|
||||
} catch (error) {
|
||||
return next(false)
|
||||
}
|
||||
next(true)
|
||||
}
|
||||
}
|
||||
})
|
||||
// To detect allowed origins
|
||||
// fastify.addHook('onRequest', async (request, reply) => {
|
||||
// let allowedList = ['coolify:3000'];
|
||||
@@ -127,6 +148,19 @@ const host = '0.0.0.0';
|
||||
|
||||
|
||||
try {
|
||||
fastify.decorate('wssend', function (data: any) {
|
||||
fastify.websocketServer.clients.forEach((client) => {
|
||||
client.send(JSON.stringify(data));
|
||||
})
|
||||
})
|
||||
fastify.register(async function (fastify) {
|
||||
fastify.get('/realtime', { websocket: true }, (connection) => {
|
||||
// connection.socket.on('message', message => {
|
||||
// realtime(fastify, connection, message)
|
||||
// })
|
||||
})
|
||||
})
|
||||
|
||||
await fastify.listen({ port, host })
|
||||
console.log(`Coolify's API is listening on ${host}:${port}`);
|
||||
|
||||
|
@@ -293,28 +293,47 @@ async function ghost(service: any, template: any) {
|
||||
async function wordpress(service: any, template: any) {
|
||||
const { extraConfig, tablePrefix, ownMysql, mysqlHost, mysqlPort, mysqlUser, mysqlPassword, mysqlRootUser, mysqlRootUserPassword, mysqlDatabase, ftpEnabled, ftpUser, ftpPassword, ftpPublicPort, ftpHostKey, ftpHostKeyPrivate } = service.wordpress
|
||||
|
||||
const secrets = [
|
||||
`MYSQL_ROOT_PASSWORD@@@${mysqlRootUserPassword}`,
|
||||
`MYSQL_PASSWORD@@@${mysqlPassword}`,
|
||||
ftpPassword && `COOLIFY_FTP_PASSWORD@@@${ftpPassword}`,
|
||||
ftpHostKeyPrivate && `COOLIFY_FTP_HOST_KEY_PRIVATE@@@${ftpHostKeyPrivate}`,
|
||||
ftpHostKey && `COOLIFY_FTP_HOST_KEY@@@${ftpHostKey}`,
|
||||
]
|
||||
const settings = [
|
||||
`MYSQL_ROOT_USER@@@${mysqlRootUser}`,
|
||||
`MYSQL_USER@@@${mysqlUser}`,
|
||||
`MYSQL_DATABASE@@@${mysqlDatabase}`,
|
||||
`MYSQL_HOST@@@${ownMysql ? mysqlHost : `${service.id}-mysql`}`,
|
||||
`MYSQL_PORT@@@${mysqlPort}`,
|
||||
`WORDPRESS_CONFIG_EXTRA@@@${extraConfig}`,
|
||||
`WORDPRESS_TABLE_PREFIX@@@${tablePrefix}`,
|
||||
`WORDPRESS_DB_HOST@@@${ownMysql ? mysqlHost : `${service.id}-mysql`}`,
|
||||
`COOLIFY_OWN_DB@@@${ownMysql}`,
|
||||
`COOLIFY_FTP_ENABLED@@@${ftpEnabled}`,
|
||||
`COOLIFY_FTP_USER@@@${ftpUser}`,
|
||||
`COOLIFY_FTP_PUBLIC_PORT@@@${ftpPublicPort}`,
|
||||
|
||||
]
|
||||
let settings = []
|
||||
let secrets = []
|
||||
if (ownMysql) {
|
||||
secrets = [
|
||||
`WORDPRESS_DB_PASSWORD@@@${mysqlPassword}`,
|
||||
ftpPassword && `COOLIFY_FTP_PASSWORD@@@${ftpPassword}`,
|
||||
ftpHostKeyPrivate && `COOLIFY_FTP_HOST_KEY_PRIVATE@@@${ftpHostKeyPrivate}`,
|
||||
ftpHostKey && `COOLIFY_FTP_HOST_KEY@@@${ftpHostKey}`,
|
||||
]
|
||||
settings = [
|
||||
`WORDPRESS_CONFIG_EXTRA@@@${extraConfig}`,
|
||||
`WORDPRESS_DB_HOST@@@${mysqlHost}`,
|
||||
`WORDPRESS_DB_PORT@@@${mysqlPort}`,
|
||||
`WORDPRESS_DB_USER@@@${mysqlUser}`,
|
||||
`WORDPRESS_DB_NAME@@@${mysqlDatabase}`,
|
||||
]
|
||||
} else {
|
||||
secrets = [
|
||||
`MYSQL_ROOT_PASSWORD@@@${mysqlRootUserPassword}`,
|
||||
`MYSQL_PASSWORD@@@${mysqlPassword}`,
|
||||
ftpPassword && `COOLIFY_FTP_PASSWORD@@@${ftpPassword}`,
|
||||
ftpHostKeyPrivate && `COOLIFY_FTP_HOST_KEY_PRIVATE@@@${ftpHostKeyPrivate}`,
|
||||
ftpHostKey && `COOLIFY_FTP_HOST_KEY@@@${ftpHostKey}`,
|
||||
]
|
||||
settings = [
|
||||
`MYSQL_ROOT_USER@@@${mysqlRootUser}`,
|
||||
`MYSQL_USER@@@${mysqlUser}`,
|
||||
`MYSQL_DATABASE@@@${mysqlDatabase}`,
|
||||
`MYSQL_HOST@@@${service.id}-mysql`,
|
||||
`MYSQL_PORT@@@${mysqlPort}`,
|
||||
`WORDPRESS_CONFIG_EXTRA@@@${extraConfig}`,
|
||||
`WORDPRESS_TABLE_PREFIX@@@${tablePrefix}`,
|
||||
`WORDPRESS_DB_HOST@@@${service.id}-mysql`,
|
||||
`COOLIFY_OWN_DB@@@${ownMysql}`,
|
||||
`COOLIFY_FTP_ENABLED@@@${ftpEnabled}`,
|
||||
`COOLIFY_FTP_USER@@@${ftpUser}`,
|
||||
`COOLIFY_FTP_PUBLIC_PORT@@@${ftpPublicPort}`,
|
||||
]
|
||||
}
|
||||
|
||||
await migrateSettings(settings, service, template);
|
||||
await migrateSecrets(secrets, service);
|
||||
if (ownMysql) {
|
||||
|
@@ -29,7 +29,7 @@ export async function stopService(request: FastifyRequest<ServiceStartStop>) {
|
||||
return errorHandler({ status, message })
|
||||
}
|
||||
}
|
||||
export async function startService(request: FastifyRequest<ServiceStartStop>) {
|
||||
export async function startService(request: FastifyRequest<ServiceStartStop>, fastify: any) {
|
||||
try {
|
||||
const { id } = request.params;
|
||||
const teamId = request.user.teamId;
|
||||
@@ -42,12 +42,7 @@ export async function startService(request: FastifyRequest<ServiceStartStop>) {
|
||||
const template: any = await parseAndFindServiceTemplates(service, workdir, true)
|
||||
const network = destinationDockerId && destinationDocker.network;
|
||||
const config = {};
|
||||
const isWordpress = type === 'wordpress';
|
||||
for (const s in template.services) {
|
||||
if (isWordpress && service.wordpress.ownMysql && s.name === 'MySQL') {
|
||||
console.log('skipping predefined mysql')
|
||||
continue;
|
||||
}
|
||||
let newEnvironments = []
|
||||
if (arm) {
|
||||
if (template.services[s]?.environmentArm?.length > 0) {
|
||||
@@ -90,23 +85,7 @@ export async function startService(request: FastifyRequest<ServiceStartStop>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isWordpress) {
|
||||
const { wordpress: { mysqlHost, mysqlPort, mysqlUser, mysqlPassword, mysqlDatabase, ownMysql } } = service
|
||||
console.log({ mysqlHost, mysqlPort, mysqlUser, mysqlPassword, mysqlDatabase, ownMysql })
|
||||
if (ownMysql) {
|
||||
let envsToRemove = ['WORDPRESS_DB_HOST', 'WORDPRESS_DB_USER', 'WORDPRESS_DB_PASSWORD', 'WORDPRESS_DB_NAME']
|
||||
for (const env of newEnvironments) {
|
||||
if (envsToRemove.includes(env.split('=')[0])) {
|
||||
console.log('removing', env)
|
||||
newEnvironments = newEnvironments.filter(e => e !== env)
|
||||
}
|
||||
}
|
||||
newEnvironments.push(`WORDPRESS_DB_HOST=${mysqlHost}:${mysqlPort}`)
|
||||
newEnvironments.push(`WORDPRESS_DB_USER=${mysqlUser}`)
|
||||
newEnvironments.push(`WORDPRESS_DB_PASSWORD=${mysqlPassword}`)
|
||||
newEnvironments.push(`WORDPRESS_DB_NAME=${mysqlDatabase}`)
|
||||
}
|
||||
}
|
||||
|
||||
config[s] = {
|
||||
container_name: s,
|
||||
build: template.services[s].build || undefined,
|
||||
@@ -141,7 +120,7 @@ export async function startService(request: FastifyRequest<ServiceStartStop>) {
|
||||
Dockerfile += `
|
||||
COPY ./${path.basename(source)} ${destination}`
|
||||
}
|
||||
await fs.writeFile(`${workdir}/Dockerfile.${servsice}`, Dockerfile);
|
||||
await fs.writeFile(`${workdir}/Dockerfile.${service}`, Dockerfile);
|
||||
}
|
||||
}
|
||||
const { volumeMounts } = persistentVolumes(id, persistentStorage, config)
|
||||
@@ -157,21 +136,26 @@ export async function startService(request: FastifyRequest<ServiceStartStop>) {
|
||||
}
|
||||
const composeFileDestination = `${workdir}/docker-compose.yaml`;
|
||||
await fs.writeFile(composeFileDestination, yaml.dump(composeFile));
|
||||
await startServiceContainers(destinationDocker.id, composeFileDestination)
|
||||
await startServiceContainers(fastify, id, teamId, destinationDocker.id, composeFileDestination)
|
||||
return {}
|
||||
} catch ({ status, message }) {
|
||||
return errorHandler({ status, message })
|
||||
}
|
||||
}
|
||||
async function startServiceContainers(dockerId, composeFileDestination) {
|
||||
async function startServiceContainers(fastify, id, teamId, dockerId, composeFileDestination) {
|
||||
try {
|
||||
fastify.wssend({ teamId, type: 'service', id, message: 'Pulling images...' })
|
||||
await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} pull` })
|
||||
} catch (error) { }
|
||||
fastify.wssend({ teamId, type: 'service', id, message: 'Building...' })
|
||||
await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} build --no-cache` })
|
||||
fastify.wssend({ teamId, type: 'service', id, message: 'Creating containers...' })
|
||||
await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} create` })
|
||||
fastify.wssend({ teamId, type: 'service', id, message: 'Starting containers...' })
|
||||
await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} start` })
|
||||
await asyncSleep(1000);
|
||||
await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} up -d` })
|
||||
fastify.wssend({ teamId, type: 'service', id, message: 'ending' })
|
||||
}
|
||||
export async function migrateAppwriteDB(request: FastifyRequest<OnlyId>, reply: FastifyReply) {
|
||||
try {
|
||||
|
@@ -1,9 +1,6 @@
|
||||
import { FastifyPluginAsync } from 'fastify';
|
||||
import { checkUpdate, login, showDashboard, update, resetQueue, getCurrentUser, cleanupManually, restartCoolify, refreshTemplates } from './handlers';
|
||||
import { GetCurrentUser } from './types';
|
||||
import pump from 'pump'
|
||||
import fs from 'fs'
|
||||
import { asyncExecShell, encrypt, errorHandler, prisma } from '../../../lib/common';
|
||||
|
||||
export interface Update {
|
||||
Body: { latestVersion: string }
|
||||
|
@@ -70,7 +70,7 @@ const root: FastifyPluginAsync = async (fastify): Promise<void> => {
|
||||
fastify.get<OnlyId>('/:id/usage', async (request) => await getServiceUsage(request));
|
||||
fastify.get<GetServiceLogs>('/:id/logs/:containerId', async (request) => await getServiceLogs(request));
|
||||
|
||||
fastify.post<ServiceStartStop>('/:id/start', async (request) => await startService(request));
|
||||
fastify.post<ServiceStartStop>('/:id/start', async (request) => await startService(request, fastify));
|
||||
fastify.post<ServiceStartStop>('/:id/stop', async (request) => await stopService(request));
|
||||
fastify.post<ServiceStartStop & SetWordpressSettings & SetGlitchTipSettings>('/:id/:type/settings', async (request, reply) => await setSettingsService(request, reply));
|
||||
|
||||
|
7
apps/api/src/routes/realtime/index.ts
Normal file
7
apps/api/src/routes/realtime/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export function realtime(fastify, connection, message) {
|
||||
const { socket } = connection
|
||||
const data = JSON.parse(message);
|
||||
if (data.type === 'subscribe') {
|
||||
socket.send(JSON.stringify({ type: 'subscribe', message: 'pong' }))
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user