diff --git a/apps/api/devTemplates.yaml b/apps/api/devTemplates.yaml
index 505abfb60..d590e7cf5 100644
--- a/apps/api/devTemplates.yaml
+++ b/apps/api/devTemplates.yaml
@@ -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
+
diff --git a/apps/api/scripts/convert.mjs b/apps/api/scripts/convert.mjs
index ae4f96180..ca18ae41d 100644
--- a/apps/api/scripts/convert.mjs
+++ b/apps/api/scripts/convert.mjs
@@ -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)
diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts
index 054b7237e..99c33d36b 100644
--- a/apps/api/src/index.ts
+++ b/apps/api/src/index.ts
@@ -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 () => {
diff --git a/apps/api/src/routes/api/v1/services/handlers.ts b/apps/api/src/routes/api/v1/services/handlers.ts
index 7a4083836..ec5e82b23 100644
--- a/apps/api/src/routes/api/v1/services/handlers.ts
+++ b/apps/api/src/routes/api/v1/services/handlers.ts
@@ -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) {
diff --git a/apps/api/src/routes/webhooks/traefik/handlers.ts b/apps/api/src/routes/webhooks/traefik/handlers.ts
index 58e45e416..15fc93224 100644
--- a/apps/api/src/routes/webhooks/traefik/handlers.ts
+++ b/apps/api/src/routes/webhooks/traefik/handlers.ts
@@ -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
}
diff --git a/apps/ui/src/lib/components/svg/services/ServiceIcons.svelte b/apps/ui/src/lib/components/svg/services/ServiceIcons.svelte
index 96cd81cf9..450f859d5 100644
--- a/apps/ui/src/lib/components/svg/services/ServiceIcons.svelte
+++ b/apps/ui/src/lib/components/svg/services/ServiceIcons.svelte
@@ -5,4 +5,4 @@
const name: any = type && type[0].toUpperCase() + type.substring(1).toLowerCase();
-