mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-28 07:41:27 +00:00
Merge pull request #31 from Dvorinka/feat/template-catalog
feat(templates): catalog expansion — 5 new managed-DB stacks
This commit is contained in:
2 files changed
+111
No files matched your search
@@ -1,6 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -157,3 +158,45 @@ func TestValidateTemplateGraph(t *testing.T) {
|
|||||||
t.Fatal("expected missing runtime error")
|
t.Fatal("expected missing runtime error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestOfficialTemplatesAllParse walks every seeded template and asserts the
|
||||||
|
// config parses, graph templates topo-sort + validate, and a dry-run resolve
|
||||||
|
// produces no unresolved refs (defaults cover all expressions).
|
||||||
|
func TestOfficialTemplatesAllParse(t *testing.T) {
|
||||||
|
for _, tpl := range SeedTemplates() {
|
||||||
|
var cfg TemplateConfig
|
||||||
|
if err := json.Unmarshal([]byte(tpl.Config), &cfg); err != nil {
|
||||||
|
t.Errorf("%s: config parse: %v", tpl.ID, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(cfg.Services) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sorted, err := topoSortServices(cfg.Services)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: topo sort: %v", tpl.ID, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := validateTemplateGraph(sorted); err != nil {
|
||||||
|
t.Errorf("%s: validate: %v", tpl.ID, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var vars []TemplateVariable
|
||||||
|
if tpl.Variables != "" {
|
||||||
|
if err := json.Unmarshal([]byte(tpl.Variables), &vars); err != nil {
|
||||||
|
t.Errorf("%s: variables parse: %v", tpl.ID, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userVars := map[string]string{}
|
||||||
|
for _, v := range vars {
|
||||||
|
if v.Default != "" {
|
||||||
|
userVars[v.Key] = v.Default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
graph := resolveTemplateGraph(sorted, userVars)
|
||||||
|
if len(graph.unresolved) > 0 {
|
||||||
|
t.Errorf("%s: unresolved refs: %v", tpl.ID, graph.unresolved)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1006,6 +1006,74 @@ func SeedTemplates() []ServiceTemplate {
|
|||||||
Variables: `[]`,
|
Variables: `[]`,
|
||||||
IsOfficial: true,
|
IsOfficial: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ID: "tpl-ghost-stack",
|
||||||
|
Name: "Ghost + MySQL",
|
||||||
|
Description: "Ghost publishing platform backed by a managed MySQL database",
|
||||||
|
Category: "stack",
|
||||||
|
Logo: "https://cdn.simpleicons.org/ghost",
|
||||||
|
Config: `{"version":2,"services":[
|
||||||
|
{"key":"db","type":"database","runtime":"mysql","environment":{"MYSQL_DATABASE":"ghost"}},
|
||||||
|
{"key":"web","name":"ghost","type":"web","runtime":"ghost:5-alpine","port":2368,"depends_on":["db"],
|
||||||
|
"environment":{"url":"{{APP_URL:-http://localhost:2368}}","database__client":"mysql","database__connection__host":"{{service.db.host}}","database__connection__user":"{{service.db.user}}","database__connection__password":"{{service.db.password}}","database__connection__database":"{{service.db.database}}"}}]}`,
|
||||||
|
Variables: `[{"key":"APP_URL","label":"Public URL","default":"","required":false,"secret":false}]`,
|
||||||
|
IsOfficial: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "tpl-gitea-stack",
|
||||||
|
Name: "Gitea + PostgreSQL",
|
||||||
|
Description: "Self-hosted Git service backed by a managed PostgreSQL database",
|
||||||
|
Category: "stack",
|
||||||
|
Logo: "https://cdn.simpleicons.org/gitea",
|
||||||
|
Config: `{"version":2,"services":[
|
||||||
|
{"key":"db","type":"database","runtime":"postgresql","environment":{"POSTGRES_DB":"gitea"}},
|
||||||
|
{"key":"web","name":"gitea","type":"web","runtime":"gitea/gitea:1","port":3000,"health_check":"/api/healthz","depends_on":["db"],
|
||||||
|
"environment":{"GITEA__database__DB_TYPE":"postgres","GITEA__database__HOST":"{{service.db.host}}:{{service.db.port}}","GITEA__database__NAME":"{{service.db.database}}","GITEA__database__USER":"{{service.db.user}}","GITEA__database__PASSWD":"{{service.db.password}}","GITEA__security__SECRET_KEY":"{{secret}}","GITEA__security__INTERNAL_TOKEN":"{{secret(64)}}"}}]}`,
|
||||||
|
Variables: `[]`,
|
||||||
|
IsOfficial: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "tpl-nextcloud-stack",
|
||||||
|
Name: "Nextcloud + PostgreSQL + Redis",
|
||||||
|
Description: "Nextcloud with a managed PostgreSQL database and Redis cache",
|
||||||
|
Category: "stack",
|
||||||
|
Logo: "https://cdn.simpleicons.org/nextcloud",
|
||||||
|
Config: `{"version":2,"services":[
|
||||||
|
{"key":"db","type":"database","runtime":"postgresql","environment":{"POSTGRES_DB":"nextcloud"}},
|
||||||
|
{"key":"cache","type":"database","runtime":"redis"},
|
||||||
|
{"key":"web","name":"nextcloud","type":"web","runtime":"nextcloud:30-apache","port":80,"health_check":"/status.php","depends_on":["db","cache"],
|
||||||
|
"environment":{"POSTGRES_HOST":"{{service.db.host}}","POSTGRES_DB":"{{service.db.database}}","POSTGRES_USER":"{{service.db.user}}","POSTGRES_PASSWORD":"{{service.db.password}}","REDIS_HOST":"{{service.cache.host}}","REDIS_HOST_PASSWORD":"{{service.cache.password}}","NEXTCLOUD_ADMIN_USER":"admin","NEXTCLOUD_ADMIN_PASSWORD":"{{secret}}","NEXTCLOUD_TRUSTED_DOMAINS":"{{APP_DOMAIN:-localhost}}"}}]}`,
|
||||||
|
Variables: `[{"key":"APP_DOMAIN","label":"Trusted domain","default":"","required":false,"secret":false}]`,
|
||||||
|
IsOfficial: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "tpl-paperless-stack",
|
||||||
|
Name: "Paperless-ngx + PostgreSQL + Redis",
|
||||||
|
Description: "Document management with managed PostgreSQL and Redis",
|
||||||
|
Category: "stack",
|
||||||
|
Logo: "https://cdn.simpleicons.org/paperlessngx",
|
||||||
|
Config: `{"version":2,"services":[
|
||||||
|
{"key":"db","type":"database","runtime":"postgresql","environment":{"POSTGRES_DB":"paperless"}},
|
||||||
|
{"key":"cache","type":"database","runtime":"redis"},
|
||||||
|
{"key":"web","name":"paperless","type":"web","runtime":"ghcr.io/paperless-ngx/paperless-ngx:latest","port":8000,"depends_on":["db","cache"],
|
||||||
|
"environment":{"PAPERLESS_DBHOST":"{{service.db.host}}","PAPERLESS_DBPORT":"{{service.db.port}}","PAPERLESS_DBNAME":"{{service.db.database}}","PAPERLESS_DBUSER":"{{service.db.user}}","PAPERLESS_DBPASS":"{{service.db.password}}","PAPERLESS_REDIS":"{{service.cache.url}}","PAPERLESS_ADMIN_USER":"admin","PAPERLESS_ADMIN_PASSWORD":"{{secret}}","PAPERLESS_SECRET_KEY":"{{secret(48)}}","PAPERLESS_URL":"{{APP_URL:-http://localhost:8000}}"}}]}`,
|
||||||
|
Variables: `[{"key":"APP_URL","label":"Public URL","default":"","required":false,"secret":false}]`,
|
||||||
|
IsOfficial: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "tpl-plausible-stack",
|
||||||
|
Name: "Plausible + PostgreSQL + ClickHouse",
|
||||||
|
Description: "Privacy-friendly analytics with managed PostgreSQL and ClickHouse",
|
||||||
|
Category: "stack",
|
||||||
|
Logo: "https://cdn.simpleicons.org/plausibleanalytics",
|
||||||
|
Config: `{"version":2,"services":[
|
||||||
|
{"key":"db","type":"database","runtime":"postgresql","environment":{"POSTGRES_DB":"plausible"}},
|
||||||
|
{"key":"events","type":"database","runtime":"clickhouse","environment":{"CLICKHOUSE_DB":"plausible"}},
|
||||||
|
{"key":"web","name":"plausible","type":"web","runtime":"ghcr.io/plausible/community-edition:v2","port":8000,"health_check":"/api/health","depends_on":["db","events"],
|
||||||
|
"environment":{"BASE_URL":"{{APP_URL:-http://localhost:8000}}","SECRET_KEY_BASE":"{{secret(64)}}","DATABASE_URL":"{{service.db.url}}","CLICKHOUSE_DATABASE_URL":"http://{{service.events.host}}:{{service.events.port}}/{{service.events.database}}","TOTP_VAULT_KEY":"{{secret(32)}}"}}]}`,
|
||||||
|
Variables: `[{"key":"APP_URL","label":"Public URL","default":"","required":false,"secret":false}]`,
|
||||||
|
IsOfficial: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return templates
|
return templates
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user