feat: Add n8n.io service
This commit is contained in:
24
src/lib/components/svg/services/N8n.svelte
Normal file
24
src/lib/components/svg/services/N8n.svelte
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let isAbsolute = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
class={isAbsolute ? 'w-12 h-12 absolute top-0 left-0 -m-5' : 'w-8 mx-auto'}
|
||||||
|
viewBox="0 0 220 105"
|
||||||
|
>
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
fill="#FF6D5A"
|
||||||
|
d="M183.9,0.2c-9.8,0-18,6.7-20.3,15.8h-29.2c-11.5,0-20.8,9.3-20.8,20.8c0,5.7-4.7,10.4-10.4,10.4H99
|
||||||
|
c-2.3-9.1-10.5-15.8-20.3-15.8c-9.8,0-18,6.7-20.3,15.8H41.7c-2.3-9.1-10.5-15.8-20.3-15.8c-11.6,0-21,9.4-21,21
|
||||||
|
c0,11.6,9.4,21,21,21c9.8,0,18-6.7,20.3-15.8h16.7c2.3,9.1,10.5,15.8,20.3,15.8c9.7,0,17.9-6.6,20.3-15.6h4.2
|
||||||
|
c5.7,0,10.4,4.7,10.4,10.4c0,11.5,9.3,20.8,20.8,20.8h6.8c2.3,9.1,10.5,15.8,20.3,15.8c11.6,0,21-9.4,21-21c0-11.6-9.4-21-21-21
|
||||||
|
c-9.8,0-18,6.7-20.3,15.8h-6.8c-5.7,0-10.4-4.7-10.4-10.4c0-6.3-2.8-11.9-7.2-15.7c4.4-3.8,7.2-9.4,7.2-15.7
|
||||||
|
c0-5.7,4.7-10.4,10.4-10.4h29.2c2.3,9.1,10.5,15.8,20.3,15.8c11.6,0,21-9.4,21-21C204.9,9.6,195.5,0.2,183.9,0.2z M21.4,63
|
||||||
|
c-5.8,0-10.6-4.8-10.6-10.6s4.8-10.6,10.6-10.6S32,46.6,32,52.4S27.3,63,21.4,63z M78.7,63c-5.8,0-10.6-4.8-10.6-10.6
|
||||||
|
s4.8-10.6,10.6-10.6s10.6,4.8,10.6,10.6S84.6,63,78.7,63z M161.5,73.2c5.8,0,10.6,4.8,10.6,10.6s-4.8,10.6-10.6,10.6
|
||||||
|
s-10.6-4.8-10.6-10.6C150.9,77.9,155.7,73.2,161.5,73.2z M183.9,31.8c-5.8,0-10.6-4.8-10.6-10.6s4.8-10.6,10.6-10.6
|
||||||
|
s10.6,4.8,10.6,10.6C194.5,27,189.8,31.8,183.9,31.8z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
@@ -165,6 +165,15 @@ export const supportedServiceTypesAndVersions = [
|
|||||||
ports: {
|
ports: {
|
||||||
main: 8010
|
main: 8010
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'n8n',
|
||||||
|
fancyName: 'n8n',
|
||||||
|
baseImage: 'n8nio/n8n',
|
||||||
|
versions: ['latest'],
|
||||||
|
ports: {
|
||||||
|
main: 5678
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@@ -119,6 +119,13 @@ export async function configureServiceType({ id, type }) {
|
|||||||
type
|
type
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (type === 'n8n') {
|
||||||
|
await prisma.service.update({
|
||||||
|
where: { id },
|
||||||
|
data: {
|
||||||
|
type
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export async function setServiceVersion({ id, version }) {
|
export async function setServiceVersion({ id, version }) {
|
||||||
@@ -139,7 +146,7 @@ export async function updatePlausibleAnalyticsService({ id, fqdn, email, usernam
|
|||||||
await prisma.plausibleAnalytics.update({ where: { serviceId: id }, data: { email, username } });
|
await prisma.plausibleAnalytics.update({ where: { serviceId: id }, data: { email, username } });
|
||||||
await prisma.service.update({ where: { id }, data: { name, fqdn } });
|
await prisma.service.update({ where: { id }, data: { name, fqdn } });
|
||||||
}
|
}
|
||||||
export async function updateNocoDbOrMinioService({ id, fqdn, name }) {
|
export async function updateService({ id, fqdn, name }) {
|
||||||
return await prisma.service.update({ where: { id }, data: { fqdn, name } });
|
return await prisma.service.update({ where: { id }, data: { fqdn, name } });
|
||||||
}
|
}
|
||||||
export async function updateLanguageToolService({ id, fqdn, name }) {
|
export async function updateLanguageToolService({ id, fqdn, name }) {
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
import { post } from '$lib/api';
|
import { post } from '$lib/api';
|
||||||
import VaultWarden from '$lib/components/svg/services/VaultWarden.svelte';
|
import VaultWarden from '$lib/components/svg/services/VaultWarden.svelte';
|
||||||
import LanguageTool from '$lib/components/svg/services/LanguageTool.svelte';
|
import LanguageTool from '$lib/components/svg/services/LanguageTool.svelte';
|
||||||
|
import N8n from '$lib/components/svg/services/N8n.svelte';
|
||||||
|
|
||||||
const { id } = $page.params;
|
const { id } = $page.params;
|
||||||
const from = $page.url.searchParams.get('from');
|
const from = $page.url.searchParams.get('from');
|
||||||
@@ -77,6 +78,8 @@
|
|||||||
<VaultWarden isAbsolute />
|
<VaultWarden isAbsolute />
|
||||||
{:else if type.name === 'languagetool'}
|
{:else if type.name === 'languagetool'}
|
||||||
<LanguageTool isAbsolute />
|
<LanguageTool isAbsolute />
|
||||||
|
{:else if type.name === 'n8n'}
|
||||||
|
<N8n isAbsolute />
|
||||||
{/if}{type.fancyName}
|
{/if}{type.fancyName}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
import cuid from 'cuid';
|
import cuid from 'cuid';
|
||||||
import { browser } from '$app/env';
|
import { browser } from '$app/env';
|
||||||
import LanguageTool from '$lib/components/svg/services/LanguageTool.svelte';
|
import LanguageTool from '$lib/components/svg/services/LanguageTool.svelte';
|
||||||
|
import N8n from '$lib/components/svg/services/N8n.svelte';
|
||||||
|
|
||||||
export let service;
|
export let service;
|
||||||
export let isRunning;
|
export let isRunning;
|
||||||
@@ -109,6 +110,10 @@
|
|||||||
<a href="https://languagetool.org/dev" target="_blank">
|
<a href="https://languagetool.org/dev" target="_blank">
|
||||||
<LanguageTool />
|
<LanguageTool />
|
||||||
</a>
|
</a>
|
||||||
|
{:else if service.type === 'n8n'}
|
||||||
|
<a href="https://n8n.io" target="_blank">
|
||||||
|
<N8n />
|
||||||
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -13,7 +13,7 @@ export const post: RequestHandler = async (event) => {
|
|||||||
if (fqdn) fqdn = fqdn.toLowerCase();
|
if (fqdn) fqdn = fqdn.toLowerCase();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await db.updateNocoDbOrMinioService({ id, fqdn, name });
|
await db.updateService({ id, fqdn, name });
|
||||||
return { status: 201 };
|
return { status: 201 };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return ErrorHandler(error);
|
return ErrorHandler(error);
|
||||||
|
20
src/routes/services/[id]/n8n/index.json.ts
Normal file
20
src/routes/services/[id]/n8n/index.json.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { getUserDetails } from '$lib/common';
|
||||||
|
import * as db from '$lib/database';
|
||||||
|
import { ErrorHandler } from '$lib/database';
|
||||||
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export const post: RequestHandler = async (event) => {
|
||||||
|
const { status, body } = await getUserDetails(event);
|
||||||
|
if (status === 401) return { status, body };
|
||||||
|
const { id } = event.params;
|
||||||
|
|
||||||
|
let { name, fqdn } = await event.request.json();
|
||||||
|
if (fqdn) fqdn = fqdn.toLowerCase();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await db.updateService({ id, fqdn, name });
|
||||||
|
return { status: 201 };
|
||||||
|
} catch (error) {
|
||||||
|
return ErrorHandler(error);
|
||||||
|
}
|
||||||
|
};
|
72
src/routes/services/[id]/n8n/start.json.ts
Normal file
72
src/routes/services/[id]/n8n/start.json.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import { asyncExecShell, createDirectories, getEngine, getUserDetails } from '$lib/common';
|
||||||
|
import * as db from '$lib/database';
|
||||||
|
import { promises as fs } from 'fs';
|
||||||
|
import yaml from 'js-yaml';
|
||||||
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
import { ErrorHandler, getServiceImage } from '$lib/database';
|
||||||
|
import { makeLabelForServices } from '$lib/buildPacks/common';
|
||||||
|
|
||||||
|
export const post: RequestHandler = async (event) => {
|
||||||
|
const { teamId, status, body } = await getUserDetails(event);
|
||||||
|
if (status === 401) return { status, body };
|
||||||
|
|
||||||
|
const { id } = event.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const service = await db.getService({ id, teamId });
|
||||||
|
const { type, version, destinationDockerId, destinationDocker, serviceSecret } = service;
|
||||||
|
const network = destinationDockerId && destinationDocker.network;
|
||||||
|
const host = getEngine(destinationDocker.engine);
|
||||||
|
|
||||||
|
const { workdir } = await createDirectories({ repository: type, buildId: id });
|
||||||
|
const image = getServiceImage(type);
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
image: `${image}:${version}`,
|
||||||
|
volume: `${id}-n8n:/root/.n8n`,
|
||||||
|
environmentVariables: {}
|
||||||
|
};
|
||||||
|
if (serviceSecret.length > 0) {
|
||||||
|
serviceSecret.forEach((secret) => {
|
||||||
|
config.environmentVariables[secret.name] = secret.value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const composeFile = {
|
||||||
|
version: '3.8',
|
||||||
|
services: {
|
||||||
|
[id]: {
|
||||||
|
container_name: id,
|
||||||
|
image: config.image,
|
||||||
|
networks: [network],
|
||||||
|
volumes: [config.volume],
|
||||||
|
environment: config.environmentVariables,
|
||||||
|
restart: 'always',
|
||||||
|
labels: makeLabelForServices('n8n')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
networks: {
|
||||||
|
[network]: {
|
||||||
|
external: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
volumes: {
|
||||||
|
[config.volume.split(':')[0]]: {
|
||||||
|
name: config.volume.split(':')[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const composeFileDestination = `${workdir}/docker-compose.yaml`;
|
||||||
|
await fs.writeFile(composeFileDestination, yaml.dump(composeFile));
|
||||||
|
|
||||||
|
try {
|
||||||
|
await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`);
|
||||||
|
return {
|
||||||
|
status: 200
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return ErrorHandler(error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return ErrorHandler(error);
|
||||||
|
}
|
||||||
|
};
|
35
src/routes/services/[id]/n8n/stop.json.ts
Normal file
35
src/routes/services/[id]/n8n/stop.json.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { getUserDetails, removeDestinationDocker } from '$lib/common';
|
||||||
|
import * as db from '$lib/database';
|
||||||
|
import { ErrorHandler } from '$lib/database';
|
||||||
|
import { checkContainer } from '$lib/haproxy';
|
||||||
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export const post: RequestHandler = async (event) => {
|
||||||
|
const { teamId, status, body } = await getUserDetails(event);
|
||||||
|
if (status === 401) return { status, body };
|
||||||
|
|
||||||
|
const { id } = event.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const service = await db.getService({ id, teamId });
|
||||||
|
const { destinationDockerId, destinationDocker, fqdn } = service;
|
||||||
|
if (destinationDockerId) {
|
||||||
|
const engine = destinationDocker.engine;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const found = await checkContainer(engine, id);
|
||||||
|
if (found) {
|
||||||
|
await removeDestinationDocker({ id, engine });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 200
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return ErrorHandler(error);
|
||||||
|
}
|
||||||
|
};
|
@@ -12,7 +12,7 @@ export const post: RequestHandler = async (event) => {
|
|||||||
if (fqdn) fqdn = fqdn.toLowerCase();
|
if (fqdn) fqdn = fqdn.toLowerCase();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await db.updateNocoDbOrMinioService({ id, fqdn, name });
|
await db.updateService({ id, fqdn, name });
|
||||||
return { status: 201 };
|
return { status: 201 };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return ErrorHandler(error);
|
return ErrorHandler(error);
|
||||||
|
Reference in New Issue
Block a user