From 826cc4a3b2aade877a078c1b20ef5364253a823d Mon Sep 17 00:00:00 2001 From: Purvang V Date: Tue, 9 Jun 2026 13:17:43 +0530 Subject: [PATCH 1/5] fix: add migration on service-template entity and updated template seed parsing logic --- ...000000-service-templates-category-array.ts | 51 +++++++ ...30000000-service-templates-descriptions.ts | 53 +++++++ .../seeders/templates.seed.ts | 6 +- .../dto/template-marketplace.dto.ts | 6 +- .../entities/service-template.entity.ts | 9 +- .../services/service-template.service.ts | 19 ++- .../templates/build-template-records.util.ts | 133 ++++++++++++------ apps/control-panel-app/templates/README.md | 14 +- .../templates/n8n/docker-compose.yml | 3 +- .../templates/postgresV2/docker-compose.yml | 3 +- .../templates/postgresql/docker-compose.yml | 6 +- .../templates/redis/docker-compose.yml | 3 +- .../svgs/postgresql-logo-svgrepo-com.svg | 2 + .../deploy-service-summary-card.tsx | 4 +- .../components/marketplace-template-card.tsx | 4 +- .../src/features/templates/types/index.ts | 3 +- console-app/src/pages/deploy-logs-page.tsx | 2 +- .../image-data-uri.util.spec.ts | 44 ++++++ .../src/image-data-uri/image-data-uri.util.ts | 56 ++++++++ libs/common/src/index.ts | 1 + .../template-variables.util.spec.ts | 56 +++++++- .../template-variables.util.ts | 44 +++++- 22 files changed, 456 insertions(+), 66 deletions(-) create mode 100644 apps/control-panel-app/migrations/1779720000000-service-templates-category-array.ts create mode 100644 apps/control-panel-app/migrations/1779730000000-service-templates-descriptions.ts create mode 100644 apps/control-panel-app/templates/svgs/postgresql-logo-svgrepo-com.svg create mode 100644 libs/common/src/image-data-uri/image-data-uri.util.spec.ts create mode 100644 libs/common/src/image-data-uri/image-data-uri.util.ts diff --git a/apps/control-panel-app/migrations/1779720000000-service-templates-category-array.ts b/apps/control-panel-app/migrations/1779720000000-service-templates-category-array.ts new file mode 100644 index 0000000..ab8297b --- /dev/null +++ b/apps/control-panel-app/migrations/1779720000000-service-templates-category-array.ts @@ -0,0 +1,51 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class ServiceTemplatesCategoryArray1779720000000 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DROP INDEX IF EXISTS "IDX_serviceTemplates_category" + `); + + await queryRunner.query(` + ALTER TABLE "serviceTemplates" + ALTER COLUMN "category" TYPE text[] + USING ( + CASE + WHEN "category" IS NULL THEN NULL + WHEN trim("category"::text) = '' THEN NULL + ELSE ARRAY[trim("category"::text)] + END + ) + `); + + await queryRunner.query(` + CREATE INDEX "IDX_serviceTemplates_category" + ON "serviceTemplates" USING GIN ("category") + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DROP INDEX IF EXISTS "IDX_serviceTemplates_category" + `); + + await queryRunner.query(` + ALTER TABLE "serviceTemplates" + ALTER COLUMN "category" TYPE varchar(100) + USING ( + CASE + WHEN "category" IS NULL THEN NULL + WHEN array_length("category", 1) IS NULL THEN NULL + ELSE left("category"[1], 100) + END + ) + `); + + await queryRunner.query(` + CREATE INDEX "IDX_serviceTemplates_category" + ON "serviceTemplates" ("category") + `); + } +} diff --git a/apps/control-panel-app/migrations/1779730000000-service-templates-descriptions.ts b/apps/control-panel-app/migrations/1779730000000-service-templates-descriptions.ts new file mode 100644 index 0000000..751e9c3 --- /dev/null +++ b/apps/control-panel-app/migrations/1779730000000-service-templates-descriptions.ts @@ -0,0 +1,53 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class ServiceTemplatesDescriptions1779730000000 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE "serviceTemplates" + ADD COLUMN "shortDescription" text + `); + + await queryRunner.query(` + ALTER TABLE "serviceTemplates" + ADD COLUMN "longDescription" text + `); + + await queryRunner.query(` + UPDATE "serviceTemplates" + SET "shortDescription" = "description" + WHERE "description" IS NOT NULL + AND trim("description") <> '' + `); + + await queryRunner.query(` + ALTER TABLE "serviceTemplates" + DROP COLUMN "description" + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE "serviceTemplates" + ADD COLUMN "description" text + `); + + await queryRunner.query(` + UPDATE "serviceTemplates" + SET "description" = "shortDescription" + WHERE "shortDescription" IS NOT NULL + AND trim("shortDescription") <> '' + `); + + await queryRunner.query(` + ALTER TABLE "serviceTemplates" + DROP COLUMN "shortDescription" + `); + + await queryRunner.query(` + ALTER TABLE "serviceTemplates" + DROP COLUMN "longDescription" + `); + } +} diff --git a/apps/control-panel-app/seeders/templates.seed.ts b/apps/control-panel-app/seeders/templates.seed.ts index 7a7e018..70a0ee0 100644 --- a/apps/control-panel-app/seeders/templates.seed.ts +++ b/apps/control-panel-app/seeders/templates.seed.ts @@ -245,8 +245,10 @@ async function seedFromTemplates(configService: ConfigService): Promise { const payload = { slug: templateRecord.slug, name: templateRecord.name, - description: templateRecord.description || null, - category: templateRecord.category || null, + shortDescription: templateRecord.shortDescription || null, + longDescription: templateRecord.longDescription || null, + category: + templateRecord.category.length > 0 ? templateRecord.category : null, tags: templateRecord.tags.length > 0 ? templateRecord.tags : null, documentation: templateRecord.documentation || null, logo: templateRecord.logo || null, diff --git a/apps/control-panel-app/src/modules/service-template/dto/template-marketplace.dto.ts b/apps/control-panel-app/src/modules/service-template/dto/template-marketplace.dto.ts index d44c578..d6e7c42 100644 --- a/apps/control-panel-app/src/modules/service-template/dto/template-marketplace.dto.ts +++ b/apps/control-panel-app/src/modules/service-template/dto/template-marketplace.dto.ts @@ -1,9 +1,11 @@ export interface TemplateListItemDto { slug: string; name: string; - description: string; - category: string; + shortDescription: string; + longDescription: string | null; + category: string[]; tags: string[]; + logo: string | null; port: number; } diff --git a/apps/control-panel-app/src/modules/service-template/entities/service-template.entity.ts b/apps/control-panel-app/src/modules/service-template/entities/service-template.entity.ts index e0cb386..f983097 100644 --- a/apps/control-panel-app/src/modules/service-template/entities/service-template.entity.ts +++ b/apps/control-panel-app/src/modules/service-template/entities/service-template.entity.ts @@ -10,10 +10,13 @@ export class ServiceTemplateEntity extends BaseEntity { name!: string; @Column({ type: "text", nullable: true }) - description!: string | null; + shortDescription!: string | null; - @Column({ type: "varchar", length: 100, nullable: true }) - category!: string | null; + @Column({ type: "text", nullable: true }) + longDescription!: string | null; + + @Column("text", { array: true, nullable: true }) + category!: string[] | null; @Column("text", { array: true, nullable: true }) tags!: string[] | null; diff --git a/apps/control-panel-app/src/modules/service-template/services/service-template.service.ts b/apps/control-panel-app/src/modules/service-template/services/service-template.service.ts index d4c9b4c..666403b 100644 --- a/apps/control-panel-app/src/modules/service-template/services/service-template.service.ts +++ b/apps/control-panel-app/src/modules/service-template/services/service-template.service.ts @@ -7,6 +7,8 @@ import { import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; import { + getTemplateDescriptionFromComments, + getTemplateLongDescriptionFromComments, parseTemplateCommentMetadata, parseTemplateVariables, TemplatePayloadService, @@ -165,14 +167,25 @@ export class ServiceTemplateService { return { slug: template.slug, name: template.name, - description: - template.description?.trim() || commentMetadata?.slogan?.trim() || "", + shortDescription: + template.shortDescription?.trim() || + (commentMetadata + ? getTemplateDescriptionFromComments(commentMetadata) + : ""), + longDescription: + template.longDescription?.trim() || + (commentMetadata + ? getTemplateLongDescriptionFromComments(commentMetadata) || null + : null), category: - template.category?.trim() || commentMetadata?.category?.trim() || "", + template.category && template.category.length > 0 + ? template.category + : (commentMetadata?.category ?? []), tags: template.tags && template.tags.length > 0 ? template.tags : (commentMetadata?.tags ?? []), + logo: template.logo?.trim() || null, port: template.port ?? commentMetadata?.port ?? 0, }; } diff --git a/apps/control-panel-app/src/templates/build-template-records.util.ts b/apps/control-panel-app/src/templates/build-template-records.util.ts index d8835cd..eb2f117 100644 --- a/apps/control-panel-app/src/templates/build-template-records.util.ts +++ b/apps/control-panel-app/src/templates/build-template-records.util.ts @@ -8,6 +8,12 @@ * Compose YAML is parsed to JSON, stripped of the top-level `version` field, * then stored as base64 in the `compose` column expected by the database. */ +import { + encodeLogoReferenceToDataUri, + getTemplateDescriptionFromComments, + getTemplateLongDescriptionFromComments, + parseTemplateCommentMetadata, +} from "@shared/common"; import * as fs from "fs"; import * as path from "path"; @@ -18,8 +24,9 @@ import * as yaml from "js-yaml"; */ export interface TemplateMetadata { name: string; - description: string; - category: string; + shortDescription: string; + longDescription: string; + category: string[]; tags: string[]; documentation: string; logo: string; @@ -33,8 +40,9 @@ export interface TemplateMetadata { export interface ServiceTemplateRecord { slug: string; name: string; - description: string; - category: string; + shortDescription: string; + longDescription: string; + category: string[]; tags: string[]; documentation: string; logo: string; @@ -47,49 +55,25 @@ export interface ServiceTemplateRecord { } /** - * Static metadata overrides for templates that need richer catalog details - * than the slug-derived defaults provide. + * Optional per-slug overrides for fields not present in compose comment headers + * (e.g. display name, logo, image version). Compose comments are the primary + * source for documentation, short/long descriptions, category, tags, logo path, and port. */ -const metadataBySlug: Record = { +const metadataBySlug: Partial>> = { postgresql: { name: "PostgreSQL", - description: "World's most advanced database", - category: "database", - tags: ["database", "sql", "relational"], - documentation: "https://www.postgresql.org", - logo: "svgs/postgresql.svg", - port: 5432, version: "16", }, postgresV2: { name: "PostgreSQL V2", - description: - "PostgreSQL with compose-parser magic vars and DB-backed deployment env (without template.config.json)", - category: "database", - tags: ["database", "sql", "relational", "v2"], - documentation: "https://www.postgresql.org", - logo: "svgs/postgresql.svg", - port: 5432, version: "16", }, redis: { name: "Redis", - description: "In-memory data structure store", - category: "cache", - tags: ["cache", "redis", "key-value"], - documentation: "https://redis.io/docs", - logo: "svgs/redis.svg", - port: 6379, version: "7", }, n8n: { name: "n8n", - description: "Workflow automation tool", - category: "automation", - tags: ["n8n", "workflow", "automation", "no-code"], - documentation: "https://n8n.io", - logo: "svgs/n8n.png", - port: 5678, version: "2.10.2", }, }; @@ -114,8 +98,9 @@ function defaultMetadata(slug: string): TemplateMetadata { .split("-") .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) .join(" "), - description: "", - category: "", + shortDescription: "", + longDescription: "", + category: [], tags: [], documentation: "", logo: "", @@ -124,6 +109,65 @@ function defaultMetadata(slug: string): TemplateMetadata { }; } +const LONG_DESCRIPTION_FILE = "long-description.html"; + +function resolveLongDescription( + templateDir: string | undefined, + overrides: Partial, + commentMetadata: ReturnType, +): string { + if (overrides.longDescription?.trim()) { + return overrides.longDescription.trim(); + } + + if (templateDir) { + const htmlPath = path.join(templateDir, LONG_DESCRIPTION_FILE); + if (fs.existsSync(htmlPath)) { + return fs.readFileSync(htmlPath, "utf8").trim(); + } + } + + return getTemplateLongDescriptionFromComments(commentMetadata); +} + +/** + * Merges compose comment metadata with optional slug overrides and slug defaults. + */ +function resolveTemplateMetadata( + slug: string, + yamlContent: string, + templateDir?: string, +): TemplateMetadata { + const commentMetadata = parseTemplateCommentMetadata(yamlContent); + const overrides = metadataBySlug[slug] ?? {}; + const defaults = defaultMetadata(slug); + + return { + name: overrides.name ?? defaults.name, + shortDescription: + overrides.shortDescription ?? + getTemplateDescriptionFromComments(commentMetadata), + longDescription: resolveLongDescription( + templateDir, + overrides, + commentMetadata, + ), + category: + overrides.category && overrides.category.length > 0 + ? overrides.category + : (commentMetadata.category ?? []), + tags: + overrides.tags && overrides.tags.length > 0 + ? overrides.tags + : (commentMetadata.tags ?? []), + documentation: + overrides.documentation ?? commentMetadata.documentation?.trim() ?? "", + logo: overrides.logo ?? commentMetadata.logo?.trim() ?? defaults.logo, + port: overrides.port ?? commentMetadata.port ?? defaults.port, + version: overrides.version ?? defaults.version, + }; +} + /** * Serializes parsed compose JSON into the base64 format stored in the database. * @param composeJson Parsed docker-compose object. @@ -153,7 +197,6 @@ function parseComposeYaml( ): Record { try { const parsed = yaml.load(yamlContent); - if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { throw new Error("Compose YAML must resolve to an object"); } @@ -214,6 +257,8 @@ export function buildServiceTemplateRecords( const stat = fs.statSync(filePath); let slug = file; + let templateDir: string | undefined; + let yamlContent: string | undefined; let jsonData: Record | undefined; let configData: Record | undefined; @@ -223,6 +268,7 @@ export function buildServiceTemplateRecords( * Optional schema overrides live in template.config.json beside compose. */ slug = file; + templateDir = filePath; const dockerComposePath = path.join(filePath, "docker-compose.yml"); if (!fs.existsSync(dockerComposePath)) { @@ -230,7 +276,7 @@ export function buildServiceTemplateRecords( } try { - const yamlContent = fs.readFileSync(dockerComposePath, "utf8"); + yamlContent = fs.readFileSync(dockerComposePath, "utf8"); jsonData = parseComposeYaml(yamlContent, slug, dockerComposePath); } catch (error: unknown) { throw new Error( @@ -253,6 +299,7 @@ export function buildServiceTemplateRecords( } slug = file.replace(".yml", ""); + templateDir = path.dirname(filePath); const potentialDir = path.join(templatesDir, slug); @@ -264,7 +311,7 @@ export function buildServiceTemplateRecords( } try { - const yamlContent = fs.readFileSync(filePath, "utf8"); + yamlContent = fs.readFileSync(filePath, "utf8"); jsonData = parseComposeYaml(yamlContent, slug, filePath); } catch (error: unknown) { throw new Error( @@ -273,7 +320,7 @@ export function buildServiceTemplateRecords( } } - if (!jsonData) { + if (!jsonData || !yamlContent) { continue; } @@ -283,17 +330,21 @@ export function buildServiceTemplateRecords( */ delete jsonData.version; - const metadata = metadataBySlug[slug] ?? defaultMetadata(slug); + const metadata = resolveTemplateMetadata(slug, yamlContent, templateDir); const composeBase64 = encodeComposeToBase64(jsonData); + const logo = metadata.logo + ? encodeLogoReferenceToDataUri(templatesDir, metadata.logo) + : ""; const record: ServiceTemplateRecord = { slug, name: metadata.name, - description: metadata.description, + shortDescription: metadata.shortDescription, + longDescription: metadata.longDescription, category: metadata.category, tags: metadata.tags, documentation: metadata.documentation, - logo: metadata.logo, + logo, compose: composeBase64, port: metadata.port, version: metadata.version, diff --git a/apps/control-panel-app/templates/README.md b/apps/control-panel-app/templates/README.md index 649b8b4..5bd94d4 100644 --- a/apps/control-panel-app/templates/README.md +++ b/apps/control-panel-app/templates/README.md @@ -145,7 +145,19 @@ After resolution, any placeholder still empty is **missing** and fails validatio 4. Prefer **`${VAR:-sensible}`** for optional tuning knobs so deploy works without passing every key. 5. Run **`npm run build:control-panel-app && npm run seed`** from `core` after editing. 6. Run **`npm run test:templates`** from `core` to validate compose structure, env/port rules, resource limits, and logging limits. -7. Register display metadata for new **slug** folders in `apps/control-panel-app/src/templates/build-template-records.util.ts` (`metadataBySlug`). +7. Add catalog metadata as leading comments in `docker-compose.yml` (read during `npm run seed`): + + | Comment key | DB column | Notes | + |-------------|-----------|--------| + | `# shortDescription:` | `shortDescription` | Also accepts legacy `# description:` / `# slogan:` | + | `# longDescription:` | `longDescription` | HTML string; or place HTML in `long-description.html` beside compose | + | `# documentation:` | `documentation` | | + | `# category:` | `category` | Comma-separated values | + | `# tags:` | `tags` | Comma-separated values | + | `# logo:` | `logo` | Path relative to `templates/` (encoded as data URI on seed) | + | `# port:` | `port` | | + +8. Register optional per-slug overrides (name, version) in `apps/control-panel-app/src/templates/build-template-records.util.ts` (`metadataBySlug`) when compose comments are not enough. --- diff --git a/apps/control-panel-app/templates/n8n/docker-compose.yml b/apps/control-panel-app/templates/n8n/docker-compose.yml index 228fcd8..be103c8 100644 --- a/apps/control-panel-app/templates/n8n/docker-compose.yml +++ b/apps/control-panel-app/templates/n8n/docker-compose.yml @@ -1,5 +1,6 @@ # documentation: https://n8n.io -# slogan: n8n is an extendable workflow automation tool. +# shortDescription: Extendable workflow automation tool +# longDescription:

n8n is a fair-code workflow automation platform that connects APIs, databases, and services with visual flows.

Build automations with low-code nodes and custom logic.

# category: automation # tags: n8n,workflow,automation,open,source,low,code # port: 5678 diff --git a/apps/control-panel-app/templates/postgresV2/docker-compose.yml b/apps/control-panel-app/templates/postgresV2/docker-compose.yml index c1cbd20..5aedba7 100644 --- a/apps/control-panel-app/templates/postgresV2/docker-compose.yml +++ b/apps/control-panel-app/templates/postgresV2/docker-compose.yml @@ -1,5 +1,6 @@ # documentation: https://www.postgresql.org -# slogan: PostgreSQL database (compose-only / Coolify-style) +# shortDescription: PostgreSQL database (compose-only / Coolify-style) +# longDescription:

PostgreSQL V2 template for compose-only deployments with magic variables and DB-backed deployment environment configuration.

# category: database # tags: postgres,postgresql,database,sql,v2 # port: 5432 diff --git a/apps/control-panel-app/templates/postgresql/docker-compose.yml b/apps/control-panel-app/templates/postgresql/docker-compose.yml index c4728cb..6bba338 100644 --- a/apps/control-panel-app/templates/postgresql/docker-compose.yml +++ b/apps/control-panel-app/templates/postgresql/docker-compose.yml @@ -1,7 +1,9 @@ # documentation: https://www.postgresql.org -# slogan: Advanced open source relational database -# category: database +# shortDescription: Advanced open source relational database +# longDescription:

PostgreSQL is a powerful, open source object-relational database system with over 35 years of active development.

Use it for transactional apps, analytics, and geospatial workloads.

+# category: database,postgresql,sql # tags: postgres,postgresql,database,sql +# logo: svgs/postgresql-logo-svgrepo-com.svg # port: 5432 services: diff --git a/apps/control-panel-app/templates/redis/docker-compose.yml b/apps/control-panel-app/templates/redis/docker-compose.yml index 52bc3bb..dadd195 100644 --- a/apps/control-panel-app/templates/redis/docker-compose.yml +++ b/apps/control-panel-app/templates/redis/docker-compose.yml @@ -1,5 +1,6 @@ # documentation: https://redis.io/docs -# slogan: In-memory data structure store +# shortDescription: In-memory data structure store +# longDescription:

Redis is an in-memory data store used as a cache, message broker, and lightweight database.

Ideal for sessions, queues, pub/sub, and rate limiting.

# category: cache # tags: cache,redis,key-value # port: 6379 diff --git a/apps/control-panel-app/templates/svgs/postgresql-logo-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/postgresql-logo-svgrepo-com.svg new file mode 100644 index 0000000..ecfcb48 --- /dev/null +++ b/apps/control-panel-app/templates/svgs/postgresql-logo-svgrepo-com.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/console-app/src/features/templates/components/deploy-service-summary-card.tsx b/console-app/src/features/templates/components/deploy-service-summary-card.tsx index ee9680a..2f1df2e 100644 --- a/console-app/src/features/templates/components/deploy-service-summary-card.tsx +++ b/console-app/src/features/templates/components/deploy-service-summary-card.tsx @@ -43,8 +43,8 @@ export function DeployServiceSummaryCard({ {template.category ? (

{template.category}

) : null} - {template.description ? ( -

{template.description}

+ {template.shortDescription ? ( +

{template.shortDescription}

) : null}
diff --git a/console-app/src/features/templates/components/marketplace-template-card.tsx b/console-app/src/features/templates/components/marketplace-template-card.tsx index d2d5f49..25dde7d 100644 --- a/console-app/src/features/templates/components/marketplace-template-card.tsx +++ b/console-app/src/features/templates/components/marketplace-template-card.tsx @@ -67,8 +67,8 @@ export function MarketplaceTemplateCard({
- {template.description ? ( -

{template.description}

+ {template.shortDescription ? ( +

{template.shortDescription}

) : (

No description provided. diff --git a/console-app/src/features/templates/types/index.ts b/console-app/src/features/templates/types/index.ts index 2685dc7..5f88e8e 100644 --- a/console-app/src/features/templates/types/index.ts +++ b/console-app/src/features/templates/types/index.ts @@ -10,7 +10,8 @@ export interface TemplateVariable { export interface ApiTemplate { slug: string; name: string; - description: string | null; + shortDescription: string | null; + longDescription?: string | null; category: string | null; tags: string[] | null; logo?: string | null; diff --git a/console-app/src/pages/deploy-logs-page.tsx b/console-app/src/pages/deploy-logs-page.tsx index 3cce1d6..b56c467 100644 --- a/console-app/src/pages/deploy-logs-page.tsx +++ b/console-app/src/pages/deploy-logs-page.tsx @@ -143,7 +143,7 @@ export function DeployLogsPage() { template={{ id: template.slug, name: template.name, - description: template.description ?? "", + description: template.shortDescription ?? "", category: template.category ?? "", color: getTemplateAccentColor(template.slug), }} diff --git a/libs/common/src/image-data-uri/image-data-uri.util.spec.ts b/libs/common/src/image-data-uri/image-data-uri.util.spec.ts new file mode 100644 index 0000000..8c4e8f1 --- /dev/null +++ b/libs/common/src/image-data-uri/image-data-uri.util.spec.ts @@ -0,0 +1,44 @@ +import { mkdirSync, mkdtempSync, writeFileSync } from "fs"; +import { tmpdir } from "os"; +import { join } from "path"; + +import { describe, expect, it } from "@jest/globals"; + +import { + encodeImageFileToDataUri, + encodeLogoReferenceToDataUri, +} from "./image-data-uri.util"; + +describe("image-data-uri.util", () => { + it("encodes an SVG file as a base64 data URI", () => { + const dir = mkdtempSync(join(tmpdir(), "kubeara-logo-")); + const svgPath = join(dir, "postgresql.svg"); + const svg = ''; + + writeFileSync(svgPath, svg, "utf8"); + + const dataUri = encodeImageFileToDataUri(svgPath); + const expectedBase64 = Buffer.from(svg, "utf8").toString("base64"); + + expect(dataUri).toBe(`data:image/svg+xml;base64,${expectedBase64}`); + }); + + it("resolves a templates-relative logo path", () => { + const templatesDir = mkdtempSync(join(tmpdir(), "kubeara-templates-")); + const svgPath = join(templatesDir, "svgs", "redis.svg"); + const svg = ""; + + mkdirSync(join(templatesDir, "svgs")); + writeFileSync(svgPath, svg, "utf8"); + + const dataUri = encodeLogoReferenceToDataUri(templatesDir, "svgs/redis.svg"); + + expect(dataUri.startsWith("data:image/svg+xml;base64,")).toBe(true); + }); + + it("returns an existing data URI unchanged", () => { + const existing = "data:image/svg+xml;base64,abc"; + + expect(encodeLogoReferenceToDataUri("/tmp", existing)).toBe(existing); + }); +}); diff --git a/libs/common/src/image-data-uri/image-data-uri.util.ts b/libs/common/src/image-data-uri/image-data-uri.util.ts new file mode 100644 index 0000000..c4e501e --- /dev/null +++ b/libs/common/src/image-data-uri/image-data-uri.util.ts @@ -0,0 +1,56 @@ +import * as fs from "fs"; +import * as path from "path"; + +const MIME_TYPE_BY_EXTENSION: Record = { + ".svg": "image/svg+xml", + ".png": "image/png", + ".webp": "image/webp", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".gif": "image/gif", +}; + +/** + * Encodes a local image file as a base64 data URI suitable for ``. + */ +export function encodeImageFileToDataUri(filePath: string): string { + const extension = path.extname(filePath).toLowerCase(); + const mimeType = MIME_TYPE_BY_EXTENSION[extension]; + + if (!mimeType) { + throw new Error( + `Unsupported image extension "${extension}" for file "${filePath}"`, + ); + } + + const base64 = fs.readFileSync(filePath).toString("base64"); + return `data:${mimeType};base64,${base64}`; +} + +/** + * Resolves a logo reference from template metadata into a data URI. + * Accepts an existing data URI or a path relative to `templatesDir`. + */ +export function encodeLogoReferenceToDataUri( + templatesDir: string, + logoRef: string, +): string { + const trimmed = logoRef.trim(); + if (!trimmed) { + return ""; + } + + if (trimmed.startsWith("data:")) { + return trimmed; + } + + const absolutePath = path.isAbsolute(trimmed) + ? trimmed + : path.join(templatesDir, trimmed); + + if (!fs.existsSync(absolutePath)) { + throw new Error(`Logo file not found: ${absolutePath}`); + } + + return encodeImageFileToDataUri(absolutePath); +} diff --git a/libs/common/src/index.ts b/libs/common/src/index.ts index 92f04d3..445c20d 100644 --- a/libs/common/src/index.ts +++ b/libs/common/src/index.ts @@ -11,6 +11,7 @@ export * from "./compose-parser/compose-parser.module"; export * from "./compose-parser/compose-parser.service"; export * from "./compose-parser/compose-parser.util"; export * from "./template-variables/template-variables.util"; +export * from "./image-data-uri/image-data-uri.util"; export * from "./server-url/server-url.util"; export * from "./traefik/traefik-labels.util"; export * from "./utils/deployment.utils"; diff --git a/libs/common/src/template-variables/template-variables.util.spec.ts b/libs/common/src/template-variables/template-variables.util.spec.ts index 8b6a66c..e6a3fb4 100644 --- a/libs/common/src/template-variables/template-variables.util.spec.ts +++ b/libs/common/src/template-variables/template-variables.util.spec.ts @@ -4,6 +4,8 @@ import { join } from "path"; import { describe, expect, it } from "@jest/globals"; import { + getTemplateDescriptionFromComments, + getTemplateLongDescriptionFromComments, parseTemplateCommentMetadata, parseTemplateVariables, } from "./template-variables.util"; @@ -36,12 +38,64 @@ services: expect(parseTemplateCommentMetadata(n8nCompose)).toEqual({ documentation: "https://n8n.io", slogan: "n8n workflow automation", - category: "automation", + category: ["automation"], tags: ["automation", "workflow"], port: 5678, }); }); + it("parses description comment key and resolves description from comments", () => { + const compose = `# description: Advanced open source relational database +# category: database + +services: + postgres: + image: postgres:16 +`; + + const metadata = parseTemplateCommentMetadata(compose); + + expect(metadata.description).toBe( + "Advanced open source relational database", + ); + expect(getTemplateDescriptionFromComments(metadata)).toBe( + "Advanced open source relational database", + ); + expect(metadata.category).toEqual(["database"]); + }); + + it("parses shortDescription and longDescription comment keys", () => { + const compose = `# shortDescription: In-memory data structure store +# longDescription:

Redis is a fast in-memory store.

+ +services: + redis: + image: redis:7 +`; + + const metadata = parseTemplateCommentMetadata(compose); + + expect(getTemplateDescriptionFromComments(metadata)).toBe( + "In-memory data structure store", + ); + expect(getTemplateLongDescriptionFromComments(metadata)).toBe( + "

Redis is a fast in-memory store.

", + ); + }); + + it("parses comma-separated category values into an array", () => { + expect( + parseTemplateCommentMetadata(`# category: database,postgresql,sql + +services: + postgres: + image: postgres:16 +`), + ).toEqual({ + category: ["database", "postgresql", "sql"], + }); + }); + it("parses deduplicated variables with occurrence-based required flags", () => { const variables = parseTemplateVariables(n8nCompose); const byName = Object.fromEntries( diff --git a/libs/common/src/template-variables/template-variables.util.ts b/libs/common/src/template-variables/template-variables.util.ts index 31ea662..040c2cd 100644 --- a/libs/common/src/template-variables/template-variables.util.ts +++ b/libs/common/src/template-variables/template-variables.util.ts @@ -22,7 +22,11 @@ export interface TemplateVariableDefinition { export interface TemplateCommentMetadata { documentation?: string; slogan?: string; - category?: string; + shortDescription?: string; + description?: string; + longDescription?: string; + logo?: string; + category?: string[]; tags?: string[]; port?: number; } @@ -314,11 +318,28 @@ export function parseTemplateCommentMetadata( case "documentation": metadata.documentation = value; break; + case "shortdescription": + case "short-description": + metadata.shortDescription = value; + break; + case "description": + metadata.description = value; + break; + case "longdescription": + case "long-description": + metadata.longDescription = value; + break; case "slogan": metadata.slogan = value; break; case "category": - metadata.category = value; + metadata.category = value + .split(",") + .map((entry) => entry.trim()) + .filter(Boolean); + break; + case "logo": + metadata.logo = value; break; case "tags": metadata.tags = value @@ -339,6 +360,25 @@ export function parseTemplateCommentMetadata( return metadata; } +/** Resolves short description from compose comment metadata. */ +export function getTemplateDescriptionFromComments( + metadata: TemplateCommentMetadata, +): string { + return ( + metadata.shortDescription?.trim() || + metadata.description?.trim() || + metadata.slogan?.trim() || + "" + ); +} + +/** Resolves long (HTML) description from compose comment metadata. */ +export function getTemplateLongDescriptionFromComments( + metadata: TemplateCommentMetadata, +): string { + return metadata.longDescription?.trim() || ""; +} + /** * Parses deduplicated deployment variables from compose YAML. */ From 5e4d581f975d44e690ad5c6a383f328df0230955 Mon Sep 17 00:00:00 2001 From: Purvang V Date: Tue, 9 Jun 2026 13:19:42 +0530 Subject: [PATCH 2/5] refactor: committing refactored code by lint fixing --- .../1779720000000-service-templates-category-array.ts | 4 +--- .../1779730000000-service-templates-descriptions.ts | 4 +--- libs/common/src/image-data-uri/image-data-uri.util.spec.ts | 5 ++++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/apps/control-panel-app/migrations/1779720000000-service-templates-category-array.ts b/apps/control-panel-app/migrations/1779720000000-service-templates-category-array.ts index ab8297b..778a402 100644 --- a/apps/control-panel-app/migrations/1779720000000-service-templates-category-array.ts +++ b/apps/control-panel-app/migrations/1779720000000-service-templates-category-array.ts @@ -1,8 +1,6 @@ import { MigrationInterface, QueryRunner } from "typeorm"; -export class ServiceTemplatesCategoryArray1779720000000 - implements MigrationInterface -{ +export class ServiceTemplatesCategoryArray1779720000000 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(` DROP INDEX IF EXISTS "IDX_serviceTemplates_category" diff --git a/apps/control-panel-app/migrations/1779730000000-service-templates-descriptions.ts b/apps/control-panel-app/migrations/1779730000000-service-templates-descriptions.ts index 751e9c3..c620ee9 100644 --- a/apps/control-panel-app/migrations/1779730000000-service-templates-descriptions.ts +++ b/apps/control-panel-app/migrations/1779730000000-service-templates-descriptions.ts @@ -1,8 +1,6 @@ import { MigrationInterface, QueryRunner } from "typeorm"; -export class ServiceTemplatesDescriptions1779730000000 - implements MigrationInterface -{ +export class ServiceTemplatesDescriptions1779730000000 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(` ALTER TABLE "serviceTemplates" diff --git a/libs/common/src/image-data-uri/image-data-uri.util.spec.ts b/libs/common/src/image-data-uri/image-data-uri.util.spec.ts index 8c4e8f1..c8faf4b 100644 --- a/libs/common/src/image-data-uri/image-data-uri.util.spec.ts +++ b/libs/common/src/image-data-uri/image-data-uri.util.spec.ts @@ -31,7 +31,10 @@ describe("image-data-uri.util", () => { mkdirSync(join(templatesDir, "svgs")); writeFileSync(svgPath, svg, "utf8"); - const dataUri = encodeLogoReferenceToDataUri(templatesDir, "svgs/redis.svg"); + const dataUri = encodeLogoReferenceToDataUri( + templatesDir, + "svgs/redis.svg", + ); expect(dataUri.startsWith("data:image/svg+xml;base64,")).toBe(true); }); From f5e1be3e5e7d1bb68aa45de5f817241421308884 Mon Sep 17 00:00:00 2001 From: Purvang V Date: Tue, 9 Jun 2026 17:24:38 +0530 Subject: [PATCH 3/5] fix: add template gitea, gitlab-ce, code-server, sql, grafana, prometheus and uptime-kuma --- .gitignore | 4 ++ .../templates/build-template-records.util.ts | 28 ++++++++++ apps/control-panel-app/templates/README.md | 7 +++ .../templates/code-server/.env.example | 10 ++++ .../templates/code-server/docker-compose.yml | 53 +++++++++++++++++++ .../templates/gitea/.env.example | 11 ++++ .../templates/gitea/docker-compose.yml | 50 +++++++++++++++++ .../templates/gitlab-ce/.env.example | 9 ++++ .../templates/gitlab-ce/docker-compose.yml | 53 +++++++++++++++++++ .../templates/grafana/.env.example | 14 +++++ .../templates/grafana/docker-compose.yml | 50 +++++++++++++++++ .../{postgresV2 => postgres}/.env.example | 0 .../docker-compose.yml | 0 .../templates/postgresql/.env.example | 7 --- .../templates/postgresql/docker-compose.yml | 49 ----------------- .../templates/prometheus/.env.example | 4 ++ .../templates/prometheus/docker-compose.yml | 50 +++++++++++++++++ .../templates/sql-server/.env.example | 8 +++ .../templates/sql-server/docker-compose.yml | 53 +++++++++++++++++++ .../templates/uptime-kuma/.env.example | 3 ++ .../templates/uptime-kuma/docker-compose.yml | 42 +++++++++++++++ 21 files changed, 449 insertions(+), 56 deletions(-) create mode 100644 apps/control-panel-app/templates/code-server/.env.example create mode 100644 apps/control-panel-app/templates/code-server/docker-compose.yml create mode 100644 apps/control-panel-app/templates/gitea/.env.example create mode 100644 apps/control-panel-app/templates/gitea/docker-compose.yml create mode 100644 apps/control-panel-app/templates/gitlab-ce/.env.example create mode 100644 apps/control-panel-app/templates/gitlab-ce/docker-compose.yml create mode 100644 apps/control-panel-app/templates/grafana/.env.example create mode 100644 apps/control-panel-app/templates/grafana/docker-compose.yml rename apps/control-panel-app/templates/{postgresV2 => postgres}/.env.example (100%) rename apps/control-panel-app/templates/{postgresV2 => postgres}/docker-compose.yml (100%) delete mode 100644 apps/control-panel-app/templates/postgresql/.env.example delete mode 100644 apps/control-panel-app/templates/postgresql/docker-compose.yml create mode 100644 apps/control-panel-app/templates/prometheus/.env.example create mode 100644 apps/control-panel-app/templates/prometheus/docker-compose.yml create mode 100644 apps/control-panel-app/templates/sql-server/.env.example create mode 100644 apps/control-panel-app/templates/sql-server/docker-compose.yml create mode 100644 apps/control-panel-app/templates/uptime-kuma/.env.example create mode 100644 apps/control-panel-app/templates/uptime-kuma/docker-compose.yml diff --git a/.gitignore b/.gitignore index 88a6875..620f778 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,7 @@ console-app/node_modules .dev.vars* !.dev.vars.example !.env.example + + +scripts/e2e/.known_hosts +scripts/e2e/.known_hosts.old \ No newline at end of file diff --git a/apps/control-panel-app/src/templates/build-template-records.util.ts b/apps/control-panel-app/src/templates/build-template-records.util.ts index eb2f117..bf46921 100644 --- a/apps/control-panel-app/src/templates/build-template-records.util.ts +++ b/apps/control-panel-app/src/templates/build-template-records.util.ts @@ -76,6 +76,34 @@ const metadataBySlug: Partial>> = { name: "n8n", version: "2.10.2", }, + "uptime-kuma": { + name: "Uptime Kuma", + version: "1", + }, + grafana: { + name: "Grafana", + version: "11.4.0", + }, + prometheus: { + name: "Prometheus", + version: "2.55.1", + }, + gitea: { + name: "Gitea", + version: "1.22.6", + }, + "gitlab-ce": { + name: "GitLab CE", + version: "17.7.0", + }, + "code-server": { + name: "Code Server", + version: "4.96.2", + }, + "sql-server": { + name: "SQL Server", + version: "2022", + }, }; /** diff --git a/apps/control-panel-app/templates/README.md b/apps/control-panel-app/templates/README.md index 5bd94d4..b099085 100644 --- a/apps/control-panel-app/templates/README.md +++ b/apps/control-panel-app/templates/README.md @@ -167,6 +167,13 @@ After resolution, any placeholder still empty is **missing** and fails validatio |----------|--------| | `postgresV2/` | Compose-only; magic vars; `SERVICE_PORT_POSTGRES`, passwords, etc. | | `n8n/` | Compose-only; `SERVICE_URL_N8N_5678` declaration + Traefik-friendly URL vars | +| `uptime-kuma/` | Self-hosted uptime monitoring on port 3001 | +| `grafana/` | Dashboards; `SERVICE_URL_GRAFANA_3000` + admin credentials | +| `prometheus/` | Metrics collection on port 9090 with default scrape config | +| `gitea/` | Lightweight Git hosting on port 3000 (SQLite, HTTP-only) | +| `gitlab-ce/` | Full DevOps platform on port 8929; high memory footprint | +| `code-server/` | Browser VS Code on port 8080 with password auth | +| `sql-server/` | Microsoft SQL Server 2022 on port 1433; 2 GB memory minimum | --- diff --git a/apps/control-panel-app/templates/code-server/.env.example b/apps/control-panel-app/templates/code-server/.env.example new file mode 100644 index 0000000..1612769 --- /dev/null +++ b/apps/control-panel-app/templates/code-server/.env.example @@ -0,0 +1,10 @@ +SERVICE_PORT_CODE_SERVER=8080 +SERVICE_PASSWORD_CODE_SERVER=code_server_password +CODE_SERVER_IMAGE=codercom/code-server:4.96.2 +CODE_SERVER_RESTART_POLICY=unless-stopped + +# Public URL when running behind a reverse proxy. +SERVICE_URL_CODE_SERVER_8080=http://localhost:8080 +SERVICE_URL_CODE_SERVER=http://localhost:8080 +SERVICE_FQDN_CODE_SERVER_8080=localhost +SERVICE_FQDN_CODE_SERVER=localhost diff --git a/apps/control-panel-app/templates/code-server/docker-compose.yml b/apps/control-panel-app/templates/code-server/docker-compose.yml new file mode 100644 index 0000000..3b0a51c --- /dev/null +++ b/apps/control-panel-app/templates/code-server/docker-compose.yml @@ -0,0 +1,53 @@ +# documentation: https://coder.com/docs/code-server/latest +# shortDescription: VS Code in the browser for remote development +# longDescription:

code-server runs VS Code on a remote server and exposes it through the browser.

Edit code, use terminals, and install extensions from anywhere with a consistent IDE experience.

+# category: development,ide +# tags: code-server,vscode,ide,editor,remote,development +# port: 8080 + +services: + code-server: + image: ${CODE_SERVER_IMAGE:-codercom/code-server:4.123.0} + restart: ${CODE_SERVER_RESTART_POLICY:-unless-stopped} + + ports: + - '${SERVICE_PORT_CODE_SERVER:-8080}:8080' + + environment: + - SERVICE_URL_CODE_SERVER_8080 + - PASSWORD=${SERVICE_PASSWORD_CODE_SERVER} + + volumes: + - code_server_data:/home/coder + + command: + - --auth + - password + - --bind-addr + - 0.0.0.0:8080 + - /home/coder/project + + healthcheck: + test: ['CMD-SHELL', 'wget -qO- http://127.0.0.1:8080/healthz || exit 1'] + interval: 15s + timeout: 10s + retries: 5 + start_period: 30s + + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + +volumes: + code_server_data: diff --git a/apps/control-panel-app/templates/gitea/.env.example b/apps/control-panel-app/templates/gitea/.env.example new file mode 100644 index 0000000..4951d3f --- /dev/null +++ b/apps/control-panel-app/templates/gitea/.env.example @@ -0,0 +1,11 @@ +SERVICE_PORT_GITEA=3000 +GITEA_IMAGE=gitea/gitea:1.22.6 +GITEA_RESTART_POLICY=unless-stopped + +# Public URL used by Gitea behind a reverse proxy. +SERVICE_URL_GITEA_3000=http://localhost:3000/ +SERVICE_URL_GITEA=http://localhost:3000/ +SERVICE_FQDN_GITEA_3000=localhost +SERVICE_FQDN_GITEA=localhost + +GITEA_DISABLE_SSH=true diff --git a/apps/control-panel-app/templates/gitea/docker-compose.yml b/apps/control-panel-app/templates/gitea/docker-compose.yml new file mode 100644 index 0000000..465d1ec --- /dev/null +++ b/apps/control-panel-app/templates/gitea/docker-compose.yml @@ -0,0 +1,50 @@ +# documentation: https://docs.gitea.com/installation/install-with-docker +# shortDescription: Lightweight self-hosted Git service +# longDescription:

Gitea is a painless self-hosted Git service with issues, pull requests, and CI integration.

Run your own lightweight alternative to GitHub with a simple web UI and organization support.

+# category: development,git +# tags: gitea,git,scm,repository,self-hosted +# port: 3000 + +services: + gitea: + image: ${GITEA_IMAGE:-gitea/gitea:1.26.2} + restart: ${GITEA_RESTART_POLICY:-unless-stopped} + + ports: + - '${SERVICE_PORT_GITEA:-3000}:3000' + + environment: + - SERVICE_URL_GITEA_3000 + - GITEA__database__DB_TYPE=sqlite3 + - GITEA__server__DOMAIN=${SERVICE_FQDN_GITEA:-${SERVICE_FQDN_GITEA_3000:-localhost}} + - GITEA__server__ROOT_URL=${SERVICE_URL_GITEA:-${SERVICE_URL_GITEA_3000:-http://localhost:3000/}} + - GITEA__server__HTTP_PORT=3000 + - GITEA__server__DISABLE_SSH=${GITEA_DISABLE_SSH:-true} + + volumes: + - gitea_data:/data + + healthcheck: + test: ['CMD-SHELL', 'wget -qO- http://127.0.0.1:3000/ || exit 1'] + interval: 15s + timeout: 10s + retries: 5 + start_period: 30s + + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + +volumes: + gitea_data: diff --git a/apps/control-panel-app/templates/gitlab-ce/.env.example b/apps/control-panel-app/templates/gitlab-ce/.env.example new file mode 100644 index 0000000..dff8725 --- /dev/null +++ b/apps/control-panel-app/templates/gitlab-ce/.env.example @@ -0,0 +1,9 @@ +SERVICE_PORT_GITLAB=8929 +GITLAB_IMAGE=gitlab/gitlab-ce:17.7.0-ce.0 +GITLAB_RESTART_POLICY=unless-stopped + +# Public URL used by GitLab behind a reverse proxy. +SERVICE_URL_GITLAB_8929=http://localhost:8929 +SERVICE_URL_GITLAB=http://localhost:8929 +SERVICE_FQDN_GITLAB_8929=localhost +SERVICE_FQDN_GITLAB=localhost diff --git a/apps/control-panel-app/templates/gitlab-ce/docker-compose.yml b/apps/control-panel-app/templates/gitlab-ce/docker-compose.yml new file mode 100644 index 0000000..a067051 --- /dev/null +++ b/apps/control-panel-app/templates/gitlab-ce/docker-compose.yml @@ -0,0 +1,53 @@ +# documentation: https://docs.gitlab.com/ee/install/docker.html +# shortDescription: Self-hosted DevOps platform with Git, CI/CD, and registry +# longDescription:

GitLab Community Edition is a complete DevOps platform delivered as a single application.

Includes Git repositories, issue tracking, CI/CD pipelines, and container registry. Requires substantial memory for production workloads.

+# category: development,git,devops +# tags: gitlab,git,ci,cd,devops,scm +# port: 8929 + +services: + gitlab: + image: ${GITLAB_IMAGE:-gitlab/gitlab-ce:latest} + restart: ${GITLAB_RESTART_POLICY:-unless-stopped} + hostname: gitlab + + ports: + - '${SERVICE_PORT_GITLAB:-8929}:80' + + environment: + - SERVICE_URL_GITLAB_8929 + - GITLAB_OMNIBUS_CONFIG=external_url '${SERVICE_URL_GITLAB:-${SERVICE_URL_GITLAB_8929:-http://localhost:8929}}'; nginx['listen_port'] = 80; gitlab_rails['gitlab_shell_ssh_port'] = 2224; + + volumes: + - gitlab_config:/etc/gitlab + - gitlab_logs:/var/log/gitlab + - gitlab_data:/var/opt/gitlab + + shm_size: '256m' + + healthcheck: + test: ['CMD-SHELL', 'wget -qO- http://127.0.0.1/-/health || exit 1'] + interval: 30s + timeout: 10s + retries: 5 + start_period: 180s + + deploy: + resources: + limits: + cpus: '2.0' + memory: 2G + reservations: + cpus: '0.5' + memory: 1G + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + +volumes: + gitlab_config: + gitlab_logs: + gitlab_data: diff --git a/apps/control-panel-app/templates/grafana/.env.example b/apps/control-panel-app/templates/grafana/.env.example new file mode 100644 index 0000000..5b99ec5 --- /dev/null +++ b/apps/control-panel-app/templates/grafana/.env.example @@ -0,0 +1,14 @@ +SERVICE_PORT_GRAFANA=3000 +SERVICE_USER_GRAFANA=admin +SERVICE_PASSWORD_GRAFANA=grafana_admin_password +GRAFANA_IMAGE=grafana/grafana:11.4.0 +GRAFANA_RESTART_POLICY=unless-stopped + +# Public URL used by Grafana UI behind a reverse proxy. +SERVICE_URL_GRAFANA_3000=http://localhost:3000 +SERVICE_URL_GRAFANA=http://localhost:3000 +SERVICE_FQDN_GRAFANA_3000=localhost +SERVICE_FQDN_GRAFANA=localhost + +GF_USERS_ALLOW_SIGN_UP=false +GF_AUTH_ANONYMOUS_ENABLED=false diff --git a/apps/control-panel-app/templates/grafana/docker-compose.yml b/apps/control-panel-app/templates/grafana/docker-compose.yml new file mode 100644 index 0000000..530042c --- /dev/null +++ b/apps/control-panel-app/templates/grafana/docker-compose.yml @@ -0,0 +1,50 @@ +# documentation: https://grafana.com/docs/grafana/latest/ +# shortDescription: Observability dashboards for metrics, logs, and traces +# longDescription:

Grafana is an open source platform for monitoring and observability.

Visualize Prometheus metrics, logs, traces, and alerts in customizable dashboards.

+# category: monitoring +# tags: grafana,monitoring,dashboards,metrics,observability +# port: 3000 + +services: + grafana: + image: ${GRAFANA_IMAGE:-grafana/grafana:13.0.2} + restart: ${GRAFANA_RESTART_POLICY:-unless-stopped} + + ports: + - '${SERVICE_PORT_GRAFANA:-3000}:3000' + + environment: + - SERVICE_URL_GRAFANA_3000 + - GF_SECURITY_ADMIN_USER=${SERVICE_USER_GRAFANA:-admin} + - GF_SECURITY_ADMIN_PASSWORD=${SERVICE_PASSWORD_GRAFANA} + - GF_SERVER_ROOT_URL=${SERVICE_URL_GRAFANA:-${SERVICE_URL_GRAFANA_3000}} + - GF_USERS_ALLOW_SIGN_UP=${GF_USERS_ALLOW_SIGN_UP:-false} + - GF_AUTH_ANONYMOUS_ENABLED=${GF_AUTH_ANONYMOUS_ENABLED:-false} + + volumes: + - grafana_data:/var/lib/grafana + + healthcheck: + test: ['CMD-SHELL', 'wget -qO- http://127.0.0.1:3000/api/health || exit 1'] + interval: 15s + timeout: 10s + retries: 5 + start_period: 30s + + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + +volumes: + grafana_data: diff --git a/apps/control-panel-app/templates/postgresV2/.env.example b/apps/control-panel-app/templates/postgres/.env.example similarity index 100% rename from apps/control-panel-app/templates/postgresV2/.env.example rename to apps/control-panel-app/templates/postgres/.env.example diff --git a/apps/control-panel-app/templates/postgresV2/docker-compose.yml b/apps/control-panel-app/templates/postgres/docker-compose.yml similarity index 100% rename from apps/control-panel-app/templates/postgresV2/docker-compose.yml rename to apps/control-panel-app/templates/postgres/docker-compose.yml diff --git a/apps/control-panel-app/templates/postgresql/.env.example b/apps/control-panel-app/templates/postgresql/.env.example deleted file mode 100644 index 1b6813e..0000000 --- a/apps/control-panel-app/templates/postgresql/.env.example +++ /dev/null @@ -1,7 +0,0 @@ -SERVICE_PORT_POSTGRES=5432 -SERVICE_USER_POSTGRES=postgres -SERVICE_PASSWORD_POSTGRES=postgres -POSTGRES_DB=postgres -POSTGRES_IMAGE=postgres:16 -POSTGRES_RESTART_POLICY=unless-stopped -POSTGRES_DATA_PATH=/var/lib/postgresql/data diff --git a/apps/control-panel-app/templates/postgresql/docker-compose.yml b/apps/control-panel-app/templates/postgresql/docker-compose.yml deleted file mode 100644 index 6bba338..0000000 --- a/apps/control-panel-app/templates/postgresql/docker-compose.yml +++ /dev/null @@ -1,49 +0,0 @@ -# documentation: https://www.postgresql.org -# shortDescription: Advanced open source relational database -# longDescription:

PostgreSQL is a powerful, open source object-relational database system with over 35 years of active development.

Use it for transactional apps, analytics, and geospatial workloads.

-# category: database,postgresql,sql -# tags: postgres,postgresql,database,sql -# logo: svgs/postgresql-logo-svgrepo-com.svg -# port: 5432 - -services: - postgres: - image: ${POSTGRES_IMAGE:-postgres:16} - restart: ${POSTGRES_RESTART_POLICY:-unless-stopped} - - ports: - - '${SERVICE_PORT_POSTGRES}:5432' - - environment: - POSTGRES_USER: ${SERVICE_USER_POSTGRES} - POSTGRES_PASSWORD: ${SERVICE_PASSWORD_POSTGRES} - POSTGRES_DB: ${POSTGRES_DB:-postgres} - PGDATA: ${POSTGRES_DATA_PATH:-/var/lib/postgresql/data} - - volumes: - - postgres_data:/var/lib/postgresql/data - - healthcheck: - test: ['CMD-SHELL', 'pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB'] - interval: 10s - timeout: 5s - retries: 5 - start_period: 10s - - deploy: - resources: - limits: - cpus: '1.0' - memory: 1G - reservations: - cpus: '0.25' - memory: 256M - - logging: - driver: json-file - options: - max-size: "10m" - max-file: "3" - -volumes: - postgres_data: diff --git a/apps/control-panel-app/templates/prometheus/.env.example b/apps/control-panel-app/templates/prometheus/.env.example new file mode 100644 index 0000000..3f7b550 --- /dev/null +++ b/apps/control-panel-app/templates/prometheus/.env.example @@ -0,0 +1,4 @@ +SERVICE_PORT_PROMETHEUS=9090 +PROMETHEUS_IMAGE=prom/prometheus:v2.55.1 +PROMETHEUS_RESTART_POLICY=unless-stopped +PROMETHEUS_RETENTION_TIME=15d diff --git a/apps/control-panel-app/templates/prometheus/docker-compose.yml b/apps/control-panel-app/templates/prometheus/docker-compose.yml new file mode 100644 index 0000000..f0baf25 --- /dev/null +++ b/apps/control-panel-app/templates/prometheus/docker-compose.yml @@ -0,0 +1,50 @@ +# documentation: https://prometheus.io/docs/introduction/overview/ +# shortDescription: Time-series monitoring and alerting toolkit +# longDescription:

Prometheus collects and stores time-series metrics with a powerful query language (PromQL).

Use it for service monitoring, alerting, and integration with Grafana dashboards.

+# category: monitoring +# tags: prometheus,monitoring,metrics,alerting,timeseries +# port: 9090 + +services: + prometheus: + image: ${PROMETHEUS_IMAGE:-prom/prometheus:v3.12.0} + restart: ${PROMETHEUS_RESTART_POLICY:-unless-stopped} + + ports: + - '${SERVICE_PORT_PROMETHEUS:-9090}:9090' + + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/etc/prometheus/console_libraries' + - '--web.console.templates=/etc/prometheus/consoles' + - '--storage.tsdb.retention.time=${PROMETHEUS_RETENTION_TIME:-15d}' + - '--web.enable-lifecycle' + + volumes: + - prometheus_data:/prometheus + + healthcheck: + test: ['CMD-SHELL', 'wget -qO- http://127.0.0.1:9090/-/healthy || exit 1'] + interval: 15s + timeout: 10s + retries: 5 + start_period: 30s + + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + +volumes: + prometheus_data: diff --git a/apps/control-panel-app/templates/sql-server/.env.example b/apps/control-panel-app/templates/sql-server/.env.example new file mode 100644 index 0000000..db2f17c --- /dev/null +++ b/apps/control-panel-app/templates/sql-server/.env.example @@ -0,0 +1,8 @@ +SERVICE_PORT_MSSQL=1433 +SERVICE_PASSWORD_MSSQL=YourStrong!Passw0rd +ACCEPT_EULA=Y +MSSQL_PID=Developer +MSSQL_AGENT_ENABLED=false +MSSQL_IMAGE=mcr.microsoft.com/mssql/server:2022-latest +MSSQL_RESTART_POLICY=unless-stopped +TZ=UTC diff --git a/apps/control-panel-app/templates/sql-server/docker-compose.yml b/apps/control-panel-app/templates/sql-server/docker-compose.yml new file mode 100644 index 0000000..25c130f --- /dev/null +++ b/apps/control-panel-app/templates/sql-server/docker-compose.yml @@ -0,0 +1,53 @@ +# documentation: https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-configure +# shortDescription: Microsoft SQL Server relational database +# longDescription:

SQL Server is a relational database management system from Microsoft.

Runs on Linux via the official container image with the sa administrator account. Requires at least 2 GB of memory.

+# category: database +# tags: sql-server,mssql,database,sql,microsoft +# port: 1433 + +services: + mssql: + image: ${MSSQL_IMAGE:-mcr.microsoft.com/mssql/server:2025-latest} + restart: ${MSSQL_RESTART_POLICY:-unless-stopped} + + ports: + - '${SERVICE_PORT_MSSQL:-1433}:1433' + + environment: + ACCEPT_EULA: ${ACCEPT_EULA:-Y} + MSSQL_SA_PASSWORD: ${SERVICE_PASSWORD_MSSQL} + MSSQL_PID: ${MSSQL_PID:-Developer} + MSSQL_AGENT_ENABLED: ${MSSQL_AGENT_ENABLED:-false} + TZ: ${TZ:-UTC} + + volumes: + - mssql_data:/var/opt/mssql + + healthcheck: + test: + [ + 'CMD-SHELL', + '/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "$$MSSQL_SA_PASSWORD" -C -Q "SELECT 1" || exit 1', + ] + interval: 10s + timeout: 10s + retries: 10 + start_period: 60s + + deploy: + resources: + limits: + cpus: '2.0' + memory: 2G + reservations: + cpus: '0.5' + memory: 1G + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + +volumes: + mssql_data: diff --git a/apps/control-panel-app/templates/uptime-kuma/.env.example b/apps/control-panel-app/templates/uptime-kuma/.env.example new file mode 100644 index 0000000..510b779 --- /dev/null +++ b/apps/control-panel-app/templates/uptime-kuma/.env.example @@ -0,0 +1,3 @@ +SERVICE_PORT_UPTIME_KUMA=3001 +UPTIME_KUMA_IMAGE=louislam/uptime-kuma:1 +UPTIME_KUMA_RESTART_POLICY=unless-stopped diff --git a/apps/control-panel-app/templates/uptime-kuma/docker-compose.yml b/apps/control-panel-app/templates/uptime-kuma/docker-compose.yml new file mode 100644 index 0000000..1ce972b --- /dev/null +++ b/apps/control-panel-app/templates/uptime-kuma/docker-compose.yml @@ -0,0 +1,42 @@ +# documentation: https://uptime.kuma.pet +# shortDescription: Self-hosted uptime and status page monitoring +# longDescription:

Uptime Kuma is a self-hosted monitoring tool for HTTP(s), TCP, ping, DNS, and more.

Get alerts and publish status pages for your services and infrastructure.

+# category: monitoring +# tags: uptime,monitoring,status,alerts,healthcheck +# port: 3001 + +services: + uptime-kuma: + image: ${UPTIME_KUMA_IMAGE:-louislam/uptime-kuma:2} + restart: ${UPTIME_KUMA_RESTART_POLICY:-unless-stopped} + + ports: + - '${SERVICE_PORT_UPTIME_KUMA:-3001}:3001' + + volumes: + - uptime_kuma_data:/app/data + + healthcheck: + test: ['CMD-SHELL', 'node extra/healthcheck.js'] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + + deploy: + resources: + limits: + cpus: '0.5' + memory: 512M + reservations: + cpus: '0.1' + memory: 128M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + +volumes: + uptime_kuma_data: From b23109c37b84678e1665e4ed38a6adbf8fa76b55 Mon Sep 17 00:00:00 2001 From: Purvang V Date: Tue, 9 Jun 2026 18:32:33 +0530 Subject: [PATCH 4/5] fix: add template wordpress, strapi, and directus --- .../templates/build-template-records.util.ts | 12 +++ apps/control-panel-app/templates/README.md | 3 + .../templates/directus/.env.example | 21 ++++ .../templates/directus/docker-compose.yml | 101 ++++++++++++++++++ .../templates/strapi/.env.example | 27 +++++ .../templates/strapi/docker-compose.yml | 101 ++++++++++++++++++ .../templates/wordpress/.env.example | 18 ++++ .../templates/wordpress/docker-compose.yml | 91 ++++++++++++++++ 8 files changed, 374 insertions(+) create mode 100644 apps/control-panel-app/templates/directus/.env.example create mode 100644 apps/control-panel-app/templates/directus/docker-compose.yml create mode 100644 apps/control-panel-app/templates/strapi/.env.example create mode 100644 apps/control-panel-app/templates/strapi/docker-compose.yml create mode 100644 apps/control-panel-app/templates/wordpress/.env.example create mode 100644 apps/control-panel-app/templates/wordpress/docker-compose.yml diff --git a/apps/control-panel-app/src/templates/build-template-records.util.ts b/apps/control-panel-app/src/templates/build-template-records.util.ts index bf46921..96f3531 100644 --- a/apps/control-panel-app/src/templates/build-template-records.util.ts +++ b/apps/control-panel-app/src/templates/build-template-records.util.ts @@ -104,6 +104,18 @@ const metadataBySlug: Partial>> = { name: "SQL Server", version: "2022", }, + wordpress: { + name: "WordPress", + version: "6.8", + }, + directus: { + name: "Directus", + version: "11.5.5", + }, + strapi: { + name: "Strapi", + version: "5.30.1", + }, }; /** diff --git a/apps/control-panel-app/templates/README.md b/apps/control-panel-app/templates/README.md index b099085..37108c0 100644 --- a/apps/control-panel-app/templates/README.md +++ b/apps/control-panel-app/templates/README.md @@ -174,6 +174,9 @@ After resolution, any placeholder still empty is **missing** and fails validatio | `gitlab-ce/` | Full DevOps platform on port 8929; high memory footprint | | `code-server/` | Browser VS Code on port 8080 with password auth | | `sql-server/` | Microsoft SQL Server 2022 on port 1433; 2 GB memory minimum | +| `wordpress/` | WordPress with MariaDB on port 80 | +| `directus/` | Headless CMS with PostgreSQL on port 8055 | +| `strapi/` | Headless CMS with PostgreSQL on port 1337 (`naskio/strapi` community image) | --- diff --git a/apps/control-panel-app/templates/directus/.env.example b/apps/control-panel-app/templates/directus/.env.example new file mode 100644 index 0000000..f3226c5 --- /dev/null +++ b/apps/control-panel-app/templates/directus/.env.example @@ -0,0 +1,21 @@ +SERVICE_PORT_DIRECTUS=8055 +SERVICE_USER_DIRECTUS=directus +SERVICE_PASSWORD_DIRECTUS=directus_password +DIRECTUS_ADMIN_EMAIL=admin@example.com +DIRECTUS_DB_NAME=directus +DIRECTUS_DB_HOST=postgres +DIRECTUS_DB_PORT=5432 +DIRECTUS_WEBSOCKETS_ENABLED=true +DIRECTUS_IMAGE=directus/directus:latest +DIRECTUS_RESTART_POLICY=unless-stopped +DIRECTUS_POSTGRES_IMAGE=postgres:16 +DIRECTUS_POSTGRES_RESTART_POLICY=unless-stopped +DIRECTUS_POSTGRES_DATA_PATH=/var/lib/postgresql/data +TZ=UTC +PGTZ=UTC + +# Public URL when running behind a reverse proxy. +SERVICE_URL_DIRECTUS_8055=http://localhost:8055 +SERVICE_URL_DIRECTUS=http://localhost:8055 +SERVICE_FQDN_DIRECTUS_8055=localhost +SERVICE_FQDN_DIRECTUS=localhost diff --git a/apps/control-panel-app/templates/directus/docker-compose.yml b/apps/control-panel-app/templates/directus/docker-compose.yml new file mode 100644 index 0000000..8f75ae1 --- /dev/null +++ b/apps/control-panel-app/templates/directus/docker-compose.yml @@ -0,0 +1,101 @@ +# documentation: https://docs.directus.io/self-hosted/docker-guide.html +# shortDescription: Open-source headless CMS and data platform +# longDescription:

Directus is an open-source headless CMS that wraps any SQL database with a real-time API and admin app.

Includes PostgreSQL. Sign in with the admin credentials on first launch.

+# category: cms,content,api +# tags: directus,cms,headless,api,postgresql,content +# port: 8055 + +services: + directus: + image: ${DIRECTUS_IMAGE:-directus/directus:latest} + restart: ${DIRECTUS_RESTART_POLICY:-unless-stopped} + + ports: + - '${SERVICE_PORT_DIRECTUS:-8055}:8055' + + environment: + - SERVICE_URL_DIRECTUS_8055 + - KEY=${SERVICE_HEX_32_DIRECTUS} + - SECRET=${SERVICE_HEX_64_DIRECTUS} + - ADMIN_EMAIL=${DIRECTUS_ADMIN_EMAIL:-admin@example.com} + - ADMIN_PASSWORD=${SERVICE_PASSWORD_DIRECTUS} + - DB_CLIENT=pg + - DB_HOST=${DIRECTUS_DB_HOST:-postgres} + - DB_PORT=${DIRECTUS_DB_PORT:-5432} + - DB_DATABASE=${DIRECTUS_DB_NAME:-directus} + - DB_USER=${SERVICE_USER_DIRECTUS} + - DB_PASSWORD=${SERVICE_PASSWORD_DIRECTUS} + - PUBLIC_URL=${SERVICE_URL_DIRECTUS:-${SERVICE_URL_DIRECTUS_8055}} + - WEBSOCKETS_ENABLED=${DIRECTUS_WEBSOCKETS_ENABLED:-true} + - TZ=${TZ:-UTC} + + volumes: + - directus_uploads:/directus/uploads + - directus_extensions:/directus/extensions + + depends_on: + postgres: + condition: service_healthy + + healthcheck: + test: ['CMD-SHELL', 'wget -qO- http://127.0.0.1:8055/server/health || exit 1'] + interval: 15s + timeout: 10s + retries: 5 + start_period: 60s + + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + + postgres: + image: ${DIRECTUS_POSTGRES_IMAGE:-postgres:16} + restart: ${DIRECTUS_POSTGRES_RESTART_POLICY:-unless-stopped} + + environment: + POSTGRES_USER: ${SERVICE_USER_DIRECTUS} + POSTGRES_PASSWORD: ${SERVICE_PASSWORD_DIRECTUS} + POSTGRES_DB: ${DIRECTUS_DB_NAME:-directus} + PGDATA: ${DIRECTUS_POSTGRES_DATA_PATH:-/var/lib/postgresql/data} + TZ: ${TZ:-UTC} + PGTZ: ${PGTZ:-UTC} + + volumes: + - directus_postgres_data:/var/lib/postgresql/data + + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB'] + interval: 5s + timeout: 20s + retries: 10 + + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + +volumes: + directus_uploads: + directus_extensions: + directus_postgres_data: diff --git a/apps/control-panel-app/templates/strapi/.env.example b/apps/control-panel-app/templates/strapi/.env.example new file mode 100644 index 0000000..c135f21 --- /dev/null +++ b/apps/control-panel-app/templates/strapi/.env.example @@ -0,0 +1,27 @@ +SERVICE_PORT_STRAPI=1337 +SERVICE_USER_STRAPI=strapi +SERVICE_PASSWORD_STRAPI=strapi_password +STRAPI_DB_NAME=strapi +STRAPI_DB_HOST=postgres +STRAPI_DB_PORT=5432 +STRAPI_HOST=0.0.0.0 +STRAPI_PORT=1337 +STRAPI_APP_KEYS=key1,key2,key3,key4 +STRAPI_API_TOKEN_SALT=apiTokenSalt +STRAPI_ADMIN_JWT_SECRET=adminJwtSecret +STRAPI_TRANSFER_TOKEN_SALT=transferTokenSalt +STRAPI_JWT_SECRET=jwtSecret +STRAPI_IMAGE=naskio/strapi:5.30.1-alpine +NODE_ENV=production +STRAPI_RESTART_POLICY=unless-stopped +STRAPI_POSTGRES_IMAGE=postgres:16 +STRAPI_POSTGRES_RESTART_POLICY=unless-stopped +STRAPI_POSTGRES_DATA_PATH=/var/lib/postgresql/data +TZ=UTC +PGTZ=UTC + +# Public URL when running behind a reverse proxy. +SERVICE_URL_STRAPI_1337=http://localhost:1337 +SERVICE_URL_STRAPI=http://localhost:1337 +SERVICE_FQDN_STRAPI_1337=localhost +SERVICE_FQDN_STRAPI=localhost diff --git a/apps/control-panel-app/templates/strapi/docker-compose.yml b/apps/control-panel-app/templates/strapi/docker-compose.yml new file mode 100644 index 0000000..407027b --- /dev/null +++ b/apps/control-panel-app/templates/strapi/docker-compose.yml @@ -0,0 +1,101 @@ +# documentation: https://docs.strapi.io/cms/installation/docker +# shortDescription: Open-source headless CMS built with Node.js +# longDescription:

Strapi is a flexible headless CMS for building APIs and content-rich applications.

Uses the community naskio/strapi image (Strapi does not publish an official pre-built image). Includes PostgreSQL — complete admin registration on first launch.

+# category: cms,content,api +# tags: strapi,cms,headless,api,nodejs,postgresql +# port: 1337 + +services: + strapi: + image: ${STRAPI_IMAGE:-naskio/strapi:5.30.1-alpine} + restart: ${STRAPI_RESTART_POLICY:-unless-stopped} + + ports: + - '${SERVICE_PORT_STRAPI:-1337}:1337' + + environment: + - SERVICE_URL_STRAPI_1337 + - NODE_ENV=${NODE_ENV:-production} + - DATABASE_CLIENT=postgres + - DATABASE_HOST=${STRAPI_DB_HOST:-postgres} + - DATABASE_PORT=${STRAPI_DB_PORT:-5432} + - DATABASE_NAME=${STRAPI_DB_NAME:-strapi} + - DATABASE_USERNAME=${SERVICE_USER_STRAPI} + - DATABASE_PASSWORD=${SERVICE_PASSWORD_STRAPI} + - APP_KEYS=${STRAPI_APP_KEYS:-key1,key2,key3,key4} + - API_TOKEN_SALT=${STRAPI_API_TOKEN_SALT:-apiTokenSalt} + - ADMIN_JWT_SECRET=${STRAPI_ADMIN_JWT_SECRET:-adminJwtSecret} + - TRANSFER_TOKEN_SALT=${STRAPI_TRANSFER_TOKEN_SALT:-transferTokenSalt} + - JWT_SECRET=${STRAPI_JWT_SECRET:-jwtSecret} + - HOST=${STRAPI_HOST:-0.0.0.0} + - PORT=${STRAPI_PORT:-1337} + - TZ=${TZ:-UTC} + + volumes: + - strapi_data:/srv/app + + depends_on: + postgres: + condition: service_healthy + + healthcheck: + test: ['CMD-SHELL', 'wget -qO- http://127.0.0.1:1337/_health || exit 1'] + interval: 15s + timeout: 10s + retries: 5 + start_period: 120s + + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + + postgres: + image: ${STRAPI_POSTGRES_IMAGE:-postgres:16} + restart: ${STRAPI_POSTGRES_RESTART_POLICY:-unless-stopped} + + environment: + POSTGRES_USER: ${SERVICE_USER_STRAPI} + POSTGRES_PASSWORD: ${SERVICE_PASSWORD_STRAPI} + POSTGRES_DB: ${STRAPI_DB_NAME:-strapi} + PGDATA: ${STRAPI_POSTGRES_DATA_PATH:-/var/lib/postgresql/data} + TZ: ${TZ:-UTC} + PGTZ: ${PGTZ:-UTC} + + volumes: + - strapi_postgres_data:/var/lib/postgresql/data + + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB'] + interval: 5s + timeout: 20s + retries: 10 + + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + +volumes: + strapi_data: + strapi_postgres_data: diff --git a/apps/control-panel-app/templates/wordpress/.env.example b/apps/control-panel-app/templates/wordpress/.env.example new file mode 100644 index 0000000..07f5aca --- /dev/null +++ b/apps/control-panel-app/templates/wordpress/.env.example @@ -0,0 +1,18 @@ +SERVICE_PORT_WORDPRESS=80 +SERVICE_USER_WORDPRESS=wordpress +SERVICE_PASSWORD_WORDPRESS=wordpress_password +SERVICE_PASSWORD_MARIADB_ROOT=mariadb_root_password +WORDPRESS_DB_NAME=wordpress +WORDPRESS_DB_HOST=mariadb +WORDPRESS_TABLE_PREFIX=wp_ +WORDPRESS_IMAGE=wordpress:latest +WORDPRESS_RESTART_POLICY=unless-stopped +MARIADB_IMAGE=mariadb:latest +MARIADB_RESTART_POLICY=unless-stopped +TZ=UTC + +# Public URL when running behind a reverse proxy. +SERVICE_URL_WORDPRESS_80=http://localhost +SERVICE_URL_WORDPRESS=http://localhost +SERVICE_FQDN_WORDPRESS_80=localhost +SERVICE_FQDN_WORDPRESS=localhost diff --git a/apps/control-panel-app/templates/wordpress/docker-compose.yml b/apps/control-panel-app/templates/wordpress/docker-compose.yml new file mode 100644 index 0000000..0f59c21 --- /dev/null +++ b/apps/control-panel-app/templates/wordpress/docker-compose.yml @@ -0,0 +1,91 @@ +# documentation: https://wordpress.org/documentation/article/installation/ +# shortDescription: Popular CMS for websites and blogs +# longDescription:

WordPress powers millions of websites as a flexible content management system.

Includes MariaDB for persistent storage. Complete the web installer on first launch.

+# category: cms,content +# tags: wordpress,cms,blog,website,php,mariadb +# port: 80 + +services: + wordpress: + image: ${WORDPRESS_IMAGE:-wordpress:latest} + restart: ${WORDPRESS_RESTART_POLICY:-unless-stopped} + + ports: + - '${SERVICE_PORT_WORDPRESS:-80}:80' + + environment: + - SERVICE_URL_WORDPRESS_80 + - WORDPRESS_DB_HOST=${WORDPRESS_DB_HOST:-mariadb} + - WORDPRESS_DB_USER=${SERVICE_USER_WORDPRESS} + - WORDPRESS_DB_PASSWORD=${SERVICE_PASSWORD_WORDPRESS} + - WORDPRESS_DB_NAME=${WORDPRESS_DB_NAME:-wordpress} + - WORDPRESS_TABLE_PREFIX=${WORDPRESS_TABLE_PREFIX:-wp_} + + volumes: + - wordpress_data:/var/www/html + + depends_on: + mariadb: + condition: service_healthy + + healthcheck: + test: ['CMD-SHELL', 'wget -qO- http://127.0.0.1/ || exit 1'] + interval: 15s + timeout: 10s + retries: 5 + start_period: 60s + + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + + mariadb: + image: ${MARIADB_IMAGE:-mariadb:latest} + restart: ${MARIADB_RESTART_POLICY:-unless-stopped} + + environment: + MARIADB_USER: ${SERVICE_USER_WORDPRESS} + MARIADB_PASSWORD: ${SERVICE_PASSWORD_WORDPRESS} + MARIADB_DATABASE: ${WORDPRESS_DB_NAME:-wordpress} + MARIADB_ROOT_PASSWORD: ${SERVICE_PASSWORD_MARIADB_ROOT} + TZ: ${TZ:-UTC} + + volumes: + - mariadb_data:/var/lib/mysql + + healthcheck: + test: ['CMD-SHELL', 'healthcheck.sh --connect --innodb_initialized'] + interval: 10s + timeout: 10s + retries: 10 + start_period: 30s + + deploy: + resources: + limits: + cpus: '1.0' + memory: 1G + reservations: + cpus: '0.25' + memory: 256M + + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + +volumes: + wordpress_data: + mariadb_data: From d287eeb55922ea0b55627a0a5274227ea2c008b5 Mon Sep 17 00:00:00 2001 From: Purvang V Date: Tue, 9 Jun 2026 19:04:39 +0530 Subject: [PATCH 5/5] fix: updated descriptions and logos for the yml files --- .../templates/build-template-records.util.ts | 20 +++++-------- apps/control-panel-app/templates/README.md | 2 +- .../templates/code-server/docker-compose.yml | 2 +- .../templates/directus/docker-compose.yml | 7 +++-- .../templates/gitea/docker-compose.yml | 7 +++-- .../templates/gitlab-ce/docker-compose.yml | 7 +++-- .../templates/grafana/docker-compose.yml | 7 +++-- .../templates/n8n/docker-compose.yml | 8 ++--- .../templates/postgres/docker-compose.yml | 11 +++---- .../templates/prometheus/docker-compose.yml | 9 +++--- .../templates/redis/docker-compose.yml | 9 +++--- .../templates/sql-server/docker-compose.yml | 9 +++--- .../templates/strapi/docker-compose.yml | 5 ++-- .../templates/svgs/directus-svgrepo-com.svg | 2 ++ .../templates/svgs/gitea-svgrepo-com.svg | 12 ++++++++ .../templates/svgs/gitlab-svgrepo-com.svg | 4 +++ .../templates/svgs/grafana-svgrepo-com.svg | 2 ++ .../templates/svgs/prometheus-svgrepo-com.svg | 2 ++ .../templates/svgs/redis-svgrepo-com.svg | 28 ++++++++++++++++++ .../svgs/sql-database-generic-svgrepo-com.svg | 29 +++++++++++++++++++ .../svgs/strapi-icon-svgrepo-com.svg | 12 ++++++++ .../svgs/uptimerobot-svgrepo-com.svg | 5 ++++ .../svgs/wordpress-color-svgrepo-com.svg | 17 +++++++++++ .../templates/uptime-kuma/docker-compose.yml | 9 +++--- .../templates/wordpress/docker-compose.yml | 7 +++-- 25 files changed, 176 insertions(+), 56 deletions(-) create mode 100644 apps/control-panel-app/templates/svgs/directus-svgrepo-com.svg create mode 100644 apps/control-panel-app/templates/svgs/gitea-svgrepo-com.svg create mode 100644 apps/control-panel-app/templates/svgs/gitlab-svgrepo-com.svg create mode 100644 apps/control-panel-app/templates/svgs/grafana-svgrepo-com.svg create mode 100644 apps/control-panel-app/templates/svgs/prometheus-svgrepo-com.svg create mode 100644 apps/control-panel-app/templates/svgs/redis-svgrepo-com.svg create mode 100644 apps/control-panel-app/templates/svgs/sql-database-generic-svgrepo-com.svg create mode 100644 apps/control-panel-app/templates/svgs/strapi-icon-svgrepo-com.svg create mode 100644 apps/control-panel-app/templates/svgs/uptimerobot-svgrepo-com.svg create mode 100644 apps/control-panel-app/templates/svgs/wordpress-color-svgrepo-com.svg diff --git a/apps/control-panel-app/src/templates/build-template-records.util.ts b/apps/control-panel-app/src/templates/build-template-records.util.ts index 96f3531..f7a672f 100644 --- a/apps/control-panel-app/src/templates/build-template-records.util.ts +++ b/apps/control-panel-app/src/templates/build-template-records.util.ts @@ -60,14 +60,10 @@ export interface ServiceTemplateRecord { * source for documentation, short/long descriptions, category, tags, logo path, and port. */ const metadataBySlug: Partial>> = { - postgresql: { + postgres: { name: "PostgreSQL", version: "16", }, - postgresV2: { - name: "PostgreSQL V2", - version: "16", - }, redis: { name: "Redis", version: "7", @@ -78,31 +74,31 @@ const metadataBySlug: Partial>> = { }, "uptime-kuma": { name: "Uptime Kuma", - version: "1", + version: "2", }, grafana: { name: "Grafana", - version: "11.4.0", + version: "13.0.2", }, prometheus: { name: "Prometheus", - version: "2.55.1", + version: "3.12.0", }, gitea: { name: "Gitea", - version: "1.22.6", + version: "1.26.2", }, "gitlab-ce": { name: "GitLab CE", - version: "17.7.0", + version: "latest", }, "code-server": { name: "Code Server", - version: "4.96.2", + version: "4.123.0", }, "sql-server": { name: "SQL Server", - version: "2022", + version: "2025", }, wordpress: { name: "WordPress", diff --git a/apps/control-panel-app/templates/README.md b/apps/control-panel-app/templates/README.md index 37108c0..cb6534d 100644 --- a/apps/control-panel-app/templates/README.md +++ b/apps/control-panel-app/templates/README.md @@ -165,7 +165,7 @@ After resolution, any placeholder still empty is **missing** and fails validatio | Template | Notes | |----------|--------| -| `postgresV2/` | Compose-only; magic vars; `SERVICE_PORT_POSTGRES`, passwords, etc. | +| `postgres/` | Compose-only PostgreSQL; magic vars; `SERVICE_PORT_POSTGRES`, passwords, etc. | | `n8n/` | Compose-only; `SERVICE_URL_N8N_5678` declaration + Traefik-friendly URL vars | | `uptime-kuma/` | Self-hosted uptime monitoring on port 3001 | | `grafana/` | Dashboards; `SERVICE_URL_GRAFANA_3000` + admin credentials | diff --git a/apps/control-panel-app/templates/code-server/docker-compose.yml b/apps/control-panel-app/templates/code-server/docker-compose.yml index 3b0a51c..094e8f6 100644 --- a/apps/control-panel-app/templates/code-server/docker-compose.yml +++ b/apps/control-panel-app/templates/code-server/docker-compose.yml @@ -1,6 +1,6 @@ # documentation: https://coder.com/docs/code-server/latest # shortDescription: VS Code in the browser for remote development -# longDescription:

code-server runs VS Code on a remote server and exposes it through the browser.

Edit code, use terminals, and install extensions from anywhere with a consistent IDE experience.

+# longDescription:

code-server runs VS Code on a remote server and exposes it through the browser.

Password authentication is configured via SERVICE_PASSWORD_CODE_SERVER. Project files persist under /home/coder/project.

# category: development,ide # tags: code-server,vscode,ide,editor,remote,development # port: 8080 diff --git a/apps/control-panel-app/templates/directus/docker-compose.yml b/apps/control-panel-app/templates/directus/docker-compose.yml index 8f75ae1..06f14a4 100644 --- a/apps/control-panel-app/templates/directus/docker-compose.yml +++ b/apps/control-panel-app/templates/directus/docker-compose.yml @@ -1,8 +1,9 @@ -# documentation: https://docs.directus.io/self-hosted/docker-guide.html +# documentation: https://docs.directus.io/self-hosted/docker-guide # shortDescription: Open-source headless CMS and data platform -# longDescription:

Directus is an open-source headless CMS that wraps any SQL database with a real-time API and admin app.

Includes PostgreSQL. Sign in with the admin credentials on first launch.

+# longDescription:

Directus is an open-source headless CMS that wraps any SQL database with a real-time API and admin app.

Includes PostgreSQL. Admin credentials use DIRECTUS_ADMIN_EMAIL and SERVICE_PASSWORD_DIRECTUS on first launch.

# category: cms,content,api -# tags: directus,cms,headless,api,postgresql,content +# tags: directus,cms,headless,api,postgresql,content,data +# logo: svgs/directus-svgrepo-com.svg # port: 8055 services: diff --git a/apps/control-panel-app/templates/gitea/docker-compose.yml b/apps/control-panel-app/templates/gitea/docker-compose.yml index 465d1ec..731074d 100644 --- a/apps/control-panel-app/templates/gitea/docker-compose.yml +++ b/apps/control-panel-app/templates/gitea/docker-compose.yml @@ -1,8 +1,9 @@ # documentation: https://docs.gitea.com/installation/install-with-docker # shortDescription: Lightweight self-hosted Git service -# longDescription:

Gitea is a painless self-hosted Git service with issues, pull requests, and CI integration.

Run your own lightweight alternative to GitHub with a simple web UI and organization support.

-# category: development,git -# tags: gitea,git,scm,repository,self-hosted +# longDescription:

Gitea is a painless self-hosted Git service with issues, pull requests, and CI integration.

Uses embedded SQLite and HTTP-only mode by default. Configure SERVICE_URL_GITEA_* when deploying behind a reverse proxy.

+# category: development,git,devops +# tags: gitea,git,scm,repository,self-hosted,version-control +# logo: svgs/gitea-svgrepo-com.svg # port: 3000 services: diff --git a/apps/control-panel-app/templates/gitlab-ce/docker-compose.yml b/apps/control-panel-app/templates/gitlab-ce/docker-compose.yml index a067051..8595e75 100644 --- a/apps/control-panel-app/templates/gitlab-ce/docker-compose.yml +++ b/apps/control-panel-app/templates/gitlab-ce/docker-compose.yml @@ -1,8 +1,9 @@ -# documentation: https://docs.gitlab.com/ee/install/docker.html +# documentation: https://docs.gitlab.com/install/docker/installation/ # shortDescription: Self-hosted DevOps platform with Git, CI/CD, and registry -# longDescription:

GitLab Community Edition is a complete DevOps platform delivered as a single application.

Includes Git repositories, issue tracking, CI/CD pipelines, and container registry. Requires substantial memory for production workloads.

+# longDescription:

GitLab Community Edition is a complete DevOps platform delivered as a single application.

Includes Git repositories, issue tracking, CI/CD pipelines, and container registry. First boot is slow and production use requires at least 4 GB RAM.

# category: development,git,devops -# tags: gitlab,git,ci,cd,devops,scm +# tags: gitlab,git,ci,cd,devops,scm,registry +# logo: svgs/gitlab-svgrepo-com.svg # port: 8929 services: diff --git a/apps/control-panel-app/templates/grafana/docker-compose.yml b/apps/control-panel-app/templates/grafana/docker-compose.yml index 530042c..956d61c 100644 --- a/apps/control-panel-app/templates/grafana/docker-compose.yml +++ b/apps/control-panel-app/templates/grafana/docker-compose.yml @@ -1,8 +1,9 @@ # documentation: https://grafana.com/docs/grafana/latest/ # shortDescription: Observability dashboards for metrics, logs, and traces -# longDescription:

Grafana is an open source platform for monitoring and observability.

Visualize Prometheus metrics, logs, traces, and alerts in customizable dashboards.

-# category: monitoring -# tags: grafana,monitoring,dashboards,metrics,observability +# longDescription:

Grafana is an open source platform for monitoring and observability.

Visualize Prometheus metrics, logs, traces, and alerts in customizable dashboards. Admin credentials are set via SERVICE_USER_GRAFANA and SERVICE_PASSWORD_GRAFANA.

+# category: monitoring,observability +# tags: grafana,monitoring,dashboards,metrics,visualization +# logo: svgs/grafana-svgrepo-com.svg # port: 3000 services: diff --git a/apps/control-panel-app/templates/n8n/docker-compose.yml b/apps/control-panel-app/templates/n8n/docker-compose.yml index be103c8..200573f 100644 --- a/apps/control-panel-app/templates/n8n/docker-compose.yml +++ b/apps/control-panel-app/templates/n8n/docker-compose.yml @@ -1,8 +1,8 @@ -# documentation: https://n8n.io +# documentation: https://docs.n8n.io # shortDescription: Extendable workflow automation tool -# longDescription:

n8n is a fair-code workflow automation platform that connects APIs, databases, and services with visual flows.

Build automations with low-code nodes and custom logic.

-# category: automation -# tags: n8n,workflow,automation,open,source,low,code +# longDescription:

n8n is a fair-code workflow automation platform that connects APIs, databases, and services with visual flows.

Includes external task runners and Traefik-friendly SERVICE_URL_* variables for webhooks and the editor UI.

+# category: automation,workflow +# tags: n8n,workflow,automation,no-code,integration # port: 5678 services: diff --git a/apps/control-panel-app/templates/postgres/docker-compose.yml b/apps/control-panel-app/templates/postgres/docker-compose.yml index 5aedba7..7da7df9 100644 --- a/apps/control-panel-app/templates/postgres/docker-compose.yml +++ b/apps/control-panel-app/templates/postgres/docker-compose.yml @@ -1,8 +1,9 @@ -# documentation: https://www.postgresql.org -# shortDescription: PostgreSQL database (compose-only / Coolify-style) -# longDescription:

PostgreSQL V2 template for compose-only deployments with magic variables and DB-backed deployment environment configuration.

-# category: database -# tags: postgres,postgresql,database,sql,v2 +# documentation: https://www.postgresql.org/docs/ +# shortDescription: Advanced open source relational database +# longDescription:

PostgreSQL is a powerful, open source object-relational database system with over 35 years of active development.

Compose-only template using magic SERVICE_* variables for credentials and host port configuration.

+# category: database,postgresql,sql +# tags: postgres,postgresql,database,sql,relational +# logo: svgs/postgresql-logo-svgrepo-com.svg # port: 5432 services: diff --git a/apps/control-panel-app/templates/prometheus/docker-compose.yml b/apps/control-panel-app/templates/prometheus/docker-compose.yml index f0baf25..df62a05 100644 --- a/apps/control-panel-app/templates/prometheus/docker-compose.yml +++ b/apps/control-panel-app/templates/prometheus/docker-compose.yml @@ -1,8 +1,9 @@ -# documentation: https://prometheus.io/docs/introduction/overview/ +# documentation: https://prometheus.io/docs/prometheus/latest/getting_started/ # shortDescription: Time-series monitoring and alerting toolkit -# longDescription:

Prometheus collects and stores time-series metrics with a powerful query language (PromQL).

Use it for service monitoring, alerting, and integration with Grafana dashboards.

-# category: monitoring -# tags: prometheus,monitoring,metrics,alerting,timeseries +# longDescription:

Prometheus collects and stores time-series metrics with a powerful query language (PromQL).

Ships with a default scrape configuration and configurable retention via PROMETHEUS_RETENTION_TIME.

+# category: monitoring,metrics +# tags: prometheus,monitoring,metrics,alerting,timeseries,observability +# logo: svgs/prometheus-svgrepo-com.svg # port: 9090 services: diff --git a/apps/control-panel-app/templates/redis/docker-compose.yml b/apps/control-panel-app/templates/redis/docker-compose.yml index dadd195..ee9bb3b 100644 --- a/apps/control-panel-app/templates/redis/docker-compose.yml +++ b/apps/control-panel-app/templates/redis/docker-compose.yml @@ -1,8 +1,9 @@ -# documentation: https://redis.io/docs +# documentation: https://redis.io/docs/latest/ # shortDescription: In-memory data structure store -# longDescription:

Redis is an in-memory data store used as a cache, message broker, and lightweight database.

Ideal for sessions, queues, pub/sub, and rate limiting.

-# category: cache -# tags: cache,redis,key-value +# longDescription:

Redis is an in-memory data store used as a cache, message broker, and lightweight database.

Supports optional password authentication via SERVICE_PASSWORD_REDIS. Ideal for sessions, queues, pub/sub, and rate limiting.

+# category: cache,database +# tags: cache,redis,key-value,in-memory +# logo: svgs/redis-svgrepo-com.svg # port: 6379 services: diff --git a/apps/control-panel-app/templates/sql-server/docker-compose.yml b/apps/control-panel-app/templates/sql-server/docker-compose.yml index 25c130f..2605211 100644 --- a/apps/control-panel-app/templates/sql-server/docker-compose.yml +++ b/apps/control-panel-app/templates/sql-server/docker-compose.yml @@ -1,8 +1,9 @@ -# documentation: https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-configure +# documentation: https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-deployment # shortDescription: Microsoft SQL Server relational database -# longDescription:

SQL Server is a relational database management system from Microsoft.

Runs on Linux via the official container image with the sa administrator account. Requires at least 2 GB of memory.

-# category: database -# tags: sql-server,mssql,database,sql,microsoft +# longDescription:

SQL Server is a relational database management system from Microsoft.

Runs on Linux via the official container image with the sa account (SERVICE_PASSWORD_MSSQL). Requires accepting the EULA and at least 2 GB of memory.

+# category: database,sql +# tags: sql-server,mssql,database,sql,microsoft,relational +# logo: svgs/sql-database-generic-svgrepo-com.svg # port: 1433 services: diff --git a/apps/control-panel-app/templates/strapi/docker-compose.yml b/apps/control-panel-app/templates/strapi/docker-compose.yml index 407027b..0337ae1 100644 --- a/apps/control-panel-app/templates/strapi/docker-compose.yml +++ b/apps/control-panel-app/templates/strapi/docker-compose.yml @@ -1,8 +1,9 @@ # documentation: https://docs.strapi.io/cms/installation/docker # shortDescription: Open-source headless CMS built with Node.js -# longDescription:

Strapi is a flexible headless CMS for building APIs and content-rich applications.

Uses the community naskio/strapi image (Strapi does not publish an official pre-built image). Includes PostgreSQL — complete admin registration on first launch.

+# longDescription:

Strapi is a flexible headless CMS for building APIs and content-rich applications.

Uses the community naskio/strapi image (Strapi does not publish an official pre-built image). Includes PostgreSQL — first boot creates the project and admin registration wizard.

# category: cms,content,api -# tags: strapi,cms,headless,api,nodejs,postgresql +# tags: strapi,cms,headless,api,nodejs,postgresql,rest +# logo: svgs/strapi-icon-svgrepo-com.svg # port: 1337 services: diff --git a/apps/control-panel-app/templates/svgs/directus-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/directus-svgrepo-com.svg new file mode 100644 index 0000000..2bc3d23 --- /dev/null +++ b/apps/control-panel-app/templates/svgs/directus-svgrepo-com.svg @@ -0,0 +1,2 @@ + +Directus icon \ No newline at end of file diff --git a/apps/control-panel-app/templates/svgs/gitea-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/gitea-svgrepo-com.svg new file mode 100644 index 0000000..3d0c51b --- /dev/null +++ b/apps/control-panel-app/templates/svgs/gitea-svgrepo-com.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/apps/control-panel-app/templates/svgs/gitlab-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/gitlab-svgrepo-com.svg new file mode 100644 index 0000000..7d2dd15 --- /dev/null +++ b/apps/control-panel-app/templates/svgs/gitlab-svgrepo-com.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/apps/control-panel-app/templates/svgs/grafana-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/grafana-svgrepo-com.svg new file mode 100644 index 0000000..9457f19 --- /dev/null +++ b/apps/control-panel-app/templates/svgs/grafana-svgrepo-com.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/apps/control-panel-app/templates/svgs/prometheus-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/prometheus-svgrepo-com.svg new file mode 100644 index 0000000..aeb9129 --- /dev/null +++ b/apps/control-panel-app/templates/svgs/prometheus-svgrepo-com.svg @@ -0,0 +1,2 @@ + +file_type_prometheus \ No newline at end of file diff --git a/apps/control-panel-app/templates/svgs/redis-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/redis-svgrepo-com.svg new file mode 100644 index 0000000..1cde9ca --- /dev/null +++ b/apps/control-panel-app/templates/svgs/redis-svgrepo-com.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/control-panel-app/templates/svgs/sql-database-generic-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/sql-database-generic-svgrepo-com.svg new file mode 100644 index 0000000..c7acdb1 --- /dev/null +++ b/apps/control-panel-app/templates/svgs/sql-database-generic-svgrepo-com.svg @@ -0,0 +1,29 @@ + + + + + + + Data + + + sql-database-generic + + + SQL Database (Generic) + + + image/svg+xml + + + Amido Limited + + + Richard Slater + + + + + + + \ No newline at end of file diff --git a/apps/control-panel-app/templates/svgs/strapi-icon-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/strapi-icon-svgrepo-com.svg new file mode 100644 index 0000000..6ef3d24 --- /dev/null +++ b/apps/control-panel-app/templates/svgs/strapi-icon-svgrepo-com.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/control-panel-app/templates/svgs/uptimerobot-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/uptimerobot-svgrepo-com.svg new file mode 100644 index 0000000..b336eca --- /dev/null +++ b/apps/control-panel-app/templates/svgs/uptimerobot-svgrepo-com.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/apps/control-panel-app/templates/svgs/wordpress-color-svgrepo-com.svg b/apps/control-panel-app/templates/svgs/wordpress-color-svgrepo-com.svg new file mode 100644 index 0000000..895e0a2 --- /dev/null +++ b/apps/control-panel-app/templates/svgs/wordpress-color-svgrepo-com.svg @@ -0,0 +1,17 @@ + + + + + Wordpress-color + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/apps/control-panel-app/templates/uptime-kuma/docker-compose.yml b/apps/control-panel-app/templates/uptime-kuma/docker-compose.yml index 1ce972b..d897d92 100644 --- a/apps/control-panel-app/templates/uptime-kuma/docker-compose.yml +++ b/apps/control-panel-app/templates/uptime-kuma/docker-compose.yml @@ -1,8 +1,9 @@ -# documentation: https://uptime.kuma.pet +# documentation: https://github.com/louislam/uptime-kuma/wiki # shortDescription: Self-hosted uptime and status page monitoring -# longDescription:

Uptime Kuma is a self-hosted monitoring tool for HTTP(s), TCP, ping, DNS, and more.

Get alerts and publish status pages for your services and infrastructure.

-# category: monitoring -# tags: uptime,monitoring,status,alerts,healthcheck +# longDescription:

Uptime Kuma is a self-hosted monitoring tool for HTTP(s), TCP, ping, DNS, and more.

Create monitors, receive alerts, and publish public status pages. Complete the setup wizard on first launch.

+# category: monitoring,uptime +# tags: uptime-kuma,monitoring,status,alerts,healthcheck,notifications +# logo: svgs/uptimerobot-svgrepo-com.svg # port: 3001 services: diff --git a/apps/control-panel-app/templates/wordpress/docker-compose.yml b/apps/control-panel-app/templates/wordpress/docker-compose.yml index 0f59c21..5f1375d 100644 --- a/apps/control-panel-app/templates/wordpress/docker-compose.yml +++ b/apps/control-panel-app/templates/wordpress/docker-compose.yml @@ -1,8 +1,9 @@ -# documentation: https://wordpress.org/documentation/article/installation/ +# documentation: https://wordpress.org/documentation/ # shortDescription: Popular CMS for websites and blogs -# longDescription:

WordPress powers millions of websites as a flexible content management system.

Includes MariaDB for persistent storage. Complete the web installer on first launch.

-# category: cms,content +# longDescription:

WordPress powers millions of websites as a flexible content management system.

Includes MariaDB for persistent storage. Database credentials use SERVICE_USER_WORDPRESS and SERVICE_PASSWORD_WORDPRESS. Complete the web installer on first launch.

+# category: cms,content,blog # tags: wordpress,cms,blog,website,php,mariadb +# logo: svgs/wordpress-color-svgrepo-com.svg # port: 80 services: