This commit is contained in:
Andras Bacsai 2022-10-26 09:27:43 +02:00
parent 111bd29cc8
commit 4bcd034b3d
9 changed files with 148 additions and 33 deletions

View File

@ -101,7 +101,6 @@
image: appwrite/appwrite:$$core_version
environment:
- _APP_ENV=$$config__app_env
- _APP_VERSION=$$config__app_version
- _APP_FUNCTIONS_TIMEOUT=$$config__app_functions_timeout
- _APP_FUNCTIONS_BUILD_TIMEOUT=$$config__app_functions_build_timeout
- _APP_FUNCTIONS_CONTAINERS=$$config__app_functions_containers
@ -997,11 +996,6 @@
defaultValue: ''
description: Phone number used for sending out messages. Must start with a leading
'+' and maximum of 15 digits without spaces (+123456789).
- id: "$$config__app_version"
name: _APP_VERSION
label: Version Tag
defaultValue: 1.0.3
description: Check out their valid tags at https://hub.docker.com/r/appwrite/appwrite/tags
- id: "$$config__app_functions_inactive_threshold"
name: _APP_FUNCTIONS_INACTIVE_THRESHOLD
label: Functions | _APP_FUNCTIONS_INACTIVE_THRESHOLD
@ -2061,8 +2055,14 @@
description: ''
- templateVersion: 1.0.0
defaultVersion: stable
name: PlausibleAnalytics
name: Plausible Analytics
description: Plausible is a lightweight and open-source website analytics tool.
labels:
- analytics
- plausible
- gdpr
- no-cookie
- privacy
services:
$$id:
name: Plausible Analytics
@ -2199,3 +2199,78 @@
label: Custom Script Name
defaultValue: plausible.js
description: This is the default script name.
- templateVersion: 1.0.0
defaultVersion: 0.98.1
name: NocoDB
description: >-
The Open Source Airtable Alternative - Turns any MySQL, PostgreSQL, SQL
Server, SQLite & MariaDB into a smart-spreadsheet.
services:
$$id:
image: nocodb/nocodb:$$core_version
environment:
- PORT=$$config_port
- NC_DB=$$config_nc_db
- DATABASE_URL=$$secret_database_url
- NC_PUBLIC_URL=$$config_public_url
- NC_AUTH_JWT_SECRET=$$secret_auth_jwt_secret
- NC_SENTRY_DSN=$$secret_sentry_dsn
- >-
NC_CONNECT_TO_EXTERNAL_DB_DISABLED=$$config_connect_to_external_db_disabled
- NC_DISABLE_TELE=$$config_disable_tele
volumes:
- $$id-data:/usr/app/data
ports:
- '8080'
variables:
- id: $$config_nc_db
name: NC_DB
label: Database
defaultValue: ''
description: >-
MySQL, PostgreSQL and MSSQL connection urls supported. If absent: A
local SQLite will be created in root folder.
- id: $$config_port
name: PORT
label: Port
defaultValue: '8080'
description: >-
For setting app running port.
- id: $$secret_database_url
name: DATABASE_URL
label: Database URL
defaultValue: ''
description: >-
JDBC URL Format. Can be used instead of NC_DB. Used in 1-Click Heroku
deployment.
- id: $$config_public_url
name: NC_PUBLIC_URL
label: Public URL
defaultValue: ''
description: >-
Used for sending Email invitations. If absent: Best guess from http
request params.
- id: $$secret_auth_jwt_secret
name: NC_AUTH_JWT_SECRET
label: Auth JWT Secret
defaultValue: $$generate_hex(64)
description: >-
JWT secret used for auth and storing other secrets. If absent: A Random
secret will be generated.
- id: $$secret_sentry_dsn
name: NC_SENTRY_DSN
label: Sentry DSN
defaultValue: ''
description: For Sentry monitoring.
- id: $$config_connect_to_external_db_disabled
name: NC_CONNECT_TO_EXTERNAL_DB_DISABLED
label: Disable External Database
defaultValue: '0'
description: Disable Project creation with external database. (Enter "1" to disable).
- id: $$config_disable_tele
name: NC_DISABLE_TELE
label: NocoDB Disable Telemetry
defaultValue: '1'
description: Disable telemetry (Enter "1" to disable).
documentation: See https://github.com/nocodb/nocodb

View File

@ -2,7 +2,7 @@
import fs from 'fs/promises';
import yaml from 'js-yaml';
const templateYml = await fs.readFile('./caprover.yml', 'utf8')
const templateYml = await fs.readFile('./convert.yaml', 'utf8')
const template = yaml.load(templateYml)
const newTemplate = {
@ -15,7 +15,8 @@ const newTemplate = {
},
"variables": []
}
const version = template.caproverOneClickApp.variables.find(v => v.id === '$$cap_APP_VERSION').defaultValue || 'latest'
console.log(template.caproverOneClickApp.variables)
const version = template.caproverOneClickApp.variables.find(v => v.id === '$$cap_APP_VERSION' || v.id === '$$cap_version').defaultValue || 'latest'
newTemplate.name = template.caproverOneClickApp.displayName
newTemplate.documentation = template.caproverOneClickApp.documentation
@ -36,9 +37,9 @@ for (const service of Object.keys(template.services)) {
}
const FROM = serviceTemplate.caproverExtra?.dockerfileLines?.find((line) => line.startsWith('FROM'))
if (serviceTemplate.image) {
newService.image = serviceTemplate.image.replaceAll('cap_APP_VERSION', 'core_version')
newService.image = serviceTemplate.image.replaceAll('cap_APP_VERSION', 'core_version').replaceAll('cap_version', 'core_version')
} else if (FROM) {
newService.image = FROM.split(' ')[1].replaceAll('cap_APP_VERSION', 'core_version')
newService.image = FROM.split(' ')[1].replaceAll('cap_APP_VERSION', 'core_version').replaceAll('cap_version', 'core_version')
}
const CMD = serviceTemplate.caproverExtra?.dockerfileLines?.find((line) => line.startsWith('CMD'))
@ -69,9 +70,9 @@ for (const service of Object.keys(template.services)) {
if (serviceTemplate.environment[env].startsWith('srv-captain--$$cap_appname')) {
value = `$$config_${env}`.toLowerCase()
defaultValue = serviceTemplate.environment[env].replaceAll('srv-captain--$$cap_appname', '$$$id').replace('$$cap', '').replaceAll('captain-overlay-network', `$$$config_${env}`).toLowerCase()
defaultValue = serviceTemplate.environment[env].replaceAll('srv-captain--$$cap_appname', '$$$id').replace('$$cap_', '').replaceAll('captain-overlay-network', `$$$config_${env}`).toLowerCase()
} else {
value = '$$config_' + serviceTemplate.environment[env].replaceAll('srv-captain--$$cap_appname', '$$$id').replace('$$cap', '').replaceAll('captain-overlay-network', `$$$config_${env}`).toLowerCase()
value = '$$config_' + serviceTemplate.environment[env].replaceAll('srv-captain--$$cap_appname', '$$$id').replace('$$cap_', '').replaceAll('captain-overlay-network', `$$$config_${env}`).toLowerCase()
}
newService.environment.push(`${env}=${value}`)
const foundVariable = varSet.has(env)

View File

@ -173,7 +173,13 @@ const host = '0.0.0.0';
setInterval(async () => {
await checkProxies();
await checkFluentBit();
}, 10000)
// Refresh and check templates
setInterval(async () => {
await refreshTemplates()
await migrateServicesToNewTemplate()
}, 10000)
setInterval(async () => {

View File

@ -146,7 +146,6 @@ export async function parseAndFindServiceTemplates(service: any, workdir?: strin
}
}
}
// TODO: seconday domains are not working - kinda working
if (value?.proxy && value.proxy.length > 0) {
for (const proxyValue of value.proxy) {
if (proxyValue.domain) {

View File

@ -386,12 +386,16 @@ export async function traefikConfiguration(request, reply) {
const isProxyConfiguration = found.services[oneService].proxy;
if (isProxyConfiguration) {
const { proxy } = found.services[oneService];
for (const configuration of proxy) {
for (let configuration of proxy) {
const publicPort = service[type]?.publicPort;
if (configuration.domain) {
const setting = serviceSetting.find((a) => a.variableName === configuration.domain);
configuration.domain = configuration.domain.replace(configuration.domain, setting.value);
}
const foundPortVariable = serviceSetting.find((a) => a.name.toLowerCase() === 'port')
if (foundPortVariable) {
configuration.port = foundPortVariable.value
}
if (fqdn) {
data.services.push({
id: oneService,
@ -402,14 +406,35 @@ export async function traefikConfiguration(request, reply) {
});
}
}
} else {
let port = found.services[oneService].ports[0]
const foundPortVariable = serviceSetting.find((a) => a.name.toLowerCase() === 'port')
if (foundPortVariable) {
port = foundPortVariable.value
}
if (fqdn) {
data.services.push({
id: oneService,
configuration: {
port
},
fqdn,
dualCerts,
});
}
}
}
}
}
}
for (const service of data.services) {
let { id, fqdn, dualCerts, configuration: { port, pathPrefix, domain: customDomain }, isCustomSSL = false } = service
let { id, fqdn, dualCerts, configuration, isCustomSSL = false } = service
let port, pathPrefix, customDomain;
if (configuration) {
port = configuration?.port;
pathPrefix = configuration?.pathPrefix;
customDomain = configuration?.domain;
}
if (customDomain) {
fqdn = customDomain
}

View File

@ -5,4 +5,4 @@
const name: any = type && type[0].toUpperCase() + type.substring(1).toLowerCase();
</script>
<svelte:component this={Icons[name]} {isAbsolute} />
<svelte:component this={Icons[name.replace('.','').replaceAll(' ','')]} {isAbsolute} />

View File

@ -6,7 +6,7 @@ export { default as Vscodeserver } from './VSCodeServer.svelte';
export { default as Wordpress } from './Wordpress.svelte';
export { default as Vaultwarden } from './VaultWarden.svelte';
export { default as Languagetool } from './LanguageTool.svelte';
export { default as N8n } from './N8n.svelte';
export { default as N8nio } from './N8n.svelte';
export { default as Uptimekuma } from './UptimeKuma.svelte';
export { default as Ghost } from './Ghost.svelte';
export { default as Meilisearch } from './MeiliSearch.svelte';

View File

@ -34,6 +34,7 @@
import { goto } from '$app/navigation';
import { get, post } from '$lib/api';
import { errorNotification } from '$lib/common';
import ServiceIcons from '$lib/components/svg/services/ServiceIcons.svelte';
const { id } = $page.params;
const from = $page.url.searchParams.get('from');
@ -48,9 +49,9 @@
}
function doSearch() {
filteredServices = services.filter(
(type: any) =>
type.name.toLowerCase().includes(search.toLowerCase()) ||
type.labels.some((label: string) => label.toLowerCase().includes(search.toLowerCase()))
(service: any) =>
service.name.toLowerCase().includes(search.toLowerCase()) ||
service.labels?.some((label: string) => label.toLowerCase().includes(search.toLowerCase()))
);
}
function cleanupSearch() {
@ -93,7 +94,7 @@
<div class="p-2">
<form on:submit|preventDefault={() => handleSubmit(service)}>
<button type="submit" class="box-selection relative text-xl font-bold hover:bg-primary">
<!-- <ServiceIcons type={service.name} /> -->
<ServiceIcons type={service.name} />
{service.name}
</button>
</form>

View File

@ -389,9 +389,13 @@
<div>
{#each Object.keys(template) as oneService}
<div
class="flex flex-row my-6 space-x-2"
class:border-b={template[oneService].environment.length > 0}
class:border-coolgray-500={template[oneService].environment.length > 0}
class="flex flex-row my-2 space-x-2"
class:my-6={template[oneService].environment.length > 0 &&
template[oneService].environment.find((env) => env.main === oneService)}
class:border-b={template[oneService].environment.length > 0 &&
template[oneService].environment.find((env) => env.main === oneService)}
class:border-coolgray-500={template[oneService].environment.length > 0 &&
template[oneService].environment.find((env) => env.main === oneService)}
>
<div class="title font-bold pb-3 capitalize">
{template[oneService].name ||
@ -405,10 +409,15 @@
{#each template[oneService].environment as variable}
{#if variable.main === oneService}
<div class="grid grid-cols-2 items-center gap-2">
<label class="h-10" for={variable.name}>{variable.label || variable.name}</label>
<label class="h-10" for={variable.name}
>{variable.label || variable.name}
{#if variable.description}
<Explainer explanation={variable.description} />
{/if}</label
>
{#if variable.defaultValue === '$$generate_fqdn'}
<input
class="w-full"
<CopyPasswordField
disabled
readonly
name={variable.name}
@ -416,8 +425,7 @@
value={service.fqdn}
/>
{:else if variable.defaultValue === '$$generate_domain'}
<input
class="w-full"
<CopyPasswordField
disabled
readonly
name={variable.name}
@ -425,8 +433,7 @@
value={getDomain(service.fqdn) || ''}
/>
{:else if variable.defaultValue === '$$generate_network'}
<input
class="w-full"
<CopyPasswordField
disabled
readonly
name={variable.name}
@ -472,6 +479,7 @@
/>
{:else}
<CopyPasswordField
placeholder={variable.defaultValue || 'optional'}
required={variable?.required}
readonly={isDisabled}
disabled={isDisabled}