From e7a7e1efa4fc885cd0ea827b4913f19dc4f93d4c Mon Sep 17 00:00:00 2001 From: Hermes Date: Wed, 12 Aug 2026 18:04:57 -0700 Subject: [PATCH] feat: add 16 new app templates (92 total) Added: authelia, keycloak, vikunja, openproject, plane, hedgedoc, yacht, openvpn, forgejo, gitlab, prometheus, netdata, kibana, openhab, bitwarden, subsonic Authelia includes DashCaddy forward_auth integration metadata. GitLab and Bitwarden include resourceWarning for minimum RAM. Prometheus includes DashCaddy metrics endpoint as setup instruction. All templates follow existing patterns (subpathSupport, healthCheck, setupInstructions). --- dashcaddy-api/src/docker/app-templates.js | 381 +++++++++++++++++++++- 1 file changed, 380 insertions(+), 1 deletion(-) diff --git a/dashcaddy-api/src/docker/app-templates.js b/dashcaddy-api/src/docker/app-templates.js index fdf57ae..dad52b0 100644 --- a/dashcaddy-api/src/docker/app-templates.js +++ b/dashcaddy-api/src/docker/app-templates.js @@ -2541,7 +2541,386 @@ const APP_TEMPLATES = { fix: "Check that uvicorn is binding 127.0.0.1:8765 (not 0.0.0.0). Use `ss -tlnp | grep 8765` to confirm." } ] - } + }, + + "authelia": { + name: "Authelia", + description: "Single sign-on portal and authentication gateway for web apps", + icon: "\u{1F6E1}\u{FE0F}", + category: "Security", + popularity: 82, + difficulty: "Advanced", + docker: { + image: "authelia/authelia:latest", + ports: ["{{PORT}}:9091"], + volumes: ["/opt/authelia/config:/config"], + environment: { + "AUTHELIA_STORAGE": "local", + "AUTHELIA_STORAGE_LOCAL_PATH": "/config/db.sqlite3" + } + }, + subdomain: "authelia", + defaultPort: 9091, + healthCheck: "/api/health", + subpathSupport: 'native', + setupInstructions: [ + "Edit /opt/authelia/config/configuration.yml with your domain and settings", + "Configure users in /opt/authelia/config/users_database.yml", + "Set up Caddy forward_auth to protect your services behind Authelia", + "Configure 2FA (TOTP, WebAuthn) in the Authelia portal" + ], + dashcaddyIntegration: { + ssoCompatible: true, + forwardAuth: true, + caddySnippet: "forward_auth authelia.:9091 { uri /api/verify?rd=https://authelia. copy_headers Remote-User Remote-Groups Remote-Name Remote-Email }" + } + }, + + "keycloak": { + name: "Keycloak", + description: "Open source identity and access management with SSO, OIDC, and SAML", + icon: "\u{1F511}", + category: "Security", + popularity: 85, + difficulty: "Advanced", + docker: { + image: "quay.io/keycloak/keycloak:latest", + ports: ["{{PORT}}:8080"], + volumes: ["/opt/keycloak/data:/opt/keycloak/data"], + environment: { + "KEYCLOAK_ADMIN": "admin", + "KEYCLOAK_ADMIN_PASSWORD": "{{GENERATED_SECRET}}", + "KC_DB": "dev-file", + "KC_HOSTNAME": "{{SUBDOMAIN}}.{{TLD}}" + }, + command: ["start-dev"] + }, + subdomain: "keycloak", + defaultPort: 8090, + healthCheck: "/health/ready", + subpathSupport: 'none', + setupInstructions: [ + "Log in with admin / generated password", + "Create a realm for your applications", + "Configure OIDC clients for each app you want to protect", + "Set up identity providers (Google, GitHub, etc.) for social login" + ], + secrets: [{ + envVar: "GENERATED_SECRET", + label: "Keycloak Admin Password", + description: "Initial admin password", + type: "password", + required: true, + generate: "alphanumeric", + length: 32 + }] + }, + + "vikunja": { + name: "Vikunja", + description: "Self-hosted to-do app with lists, kanban boards, and teams", + icon: "\u2705", + category: "Productivity", + popularity: 72, + difficulty: "Easy", + docker: { + image: "vikunja/vikunja:latest", + ports: ["{{PORT}}:3456"], + volumes: ["/opt/vikunja/files:/app/vikunja/files", "/opt/vikunja/db:/app/vikunja/database"], + environment: { + "VIKUNJA_SERVICE_JWTSECRET": "{{GENERATED_SECRET}}", + "VIKUNJA_SERVICE_FRONTENDURL": "https://{{SUBDOMAIN}}.{{TLD}}" + } + }, + subdomain: "vikunja", + defaultPort: 3456, + healthCheck: "/api/v1/info", + subpathSupport: 'native', + setupInstructions: ["Register the first user account", "Create projects and tasks", "Set up teams for shared task management"], + secrets: [{ + envVar: "GENERATED_SECRET", + label: "JWT Secret", + description: "Secret for signing auth tokens", + type: "password", + required: true, + generate: "alphanumeric", + length: 48 + }] + }, + + "openproject": { + name: "OpenProject", + description: "Project management with Gantt charts, time tracking, and Scrum boards", + icon: "\u{1F4CB}", + category: "Productivity", + popularity: 75, + difficulty: "Intermediate", + docker: { + image: "openproject/openproject:latest", + ports: ["{{PORT}}:80"], + volumes: ["/opt/openproject/pgdata:/var/openproject/pgdata", "/opt/openproject/assets:/var/openproject/assets"], + environment: { "OPENPROJECT_HOST__NAME": "{{SUBDOMAIN}}.{{TLD}}", "OPENPROJECT_HTTPS": "true" } + }, + subdomain: "projects", + defaultPort: 8091, + healthCheck: "/", + subpathSupport: 'none', + setupInstructions: ["Complete the initial setup wizard", "Create your first project", "Add team members and configure permissions"] + }, + + "plane": { + name: "Plane", + description: "Open-source Jira alternative with issues, cycles, and modules", + icon: "\u2708\uFE0F", + category: "Productivity", + popularity: 70, + difficulty: "Intermediate", + docker: { + image: "makeplane/plane-frontend:latest", + ports: ["{{PORT}}:3000"], + volumes: ["/opt/plane/data:/app/data"], + environment: { "NEXT_PUBLIC_API_BASE_URL": "https://{{SUBDOMAIN}}.{{TLD}}/api" } + }, + subdomain: "plane", + defaultPort: 8092, + healthCheck: "/", + subpathSupport: 'none', + setupInstructions: ["Plane requires multiple containers - use the recipe for full stack deploy", "Create an organization and invite team members", "Set up cycles and modules for project tracking"] + }, + + "hedgedoc": { + name: "HedgeDoc", + description: "Collaborative markdown editor with real-time editing", + icon: "\u{1F4DD}", + category: "Productivity", + popularity: 68, + difficulty: "Easy", + docker: { + image: "quay.io/hedgedoc/hedgedoc:latest", + ports: ["{{PORT}}:3000"], + volumes: ["/opt/hedgedoc/uploads:/hedgedoc/public/uploads"], + environment: { + "CMD_DOMAIN": "{{SUBDOMAIN}}.{{TLD}}", + "CMD_URL_ADDPORT": "false", + "CMD_PROTOCOL_USESSL": "true", + "CMD_DB_URL": "sqlite:/hedgedoc/database.sqlite" + } + }, + subdomain: "notes", + defaultPort: 8093, + healthCheck: "/status", + subpathSupport: 'native', + setupInstructions: ["Register an account or use guest mode", "Create collaborative markdown documents", "Share links for real-time co-editing"] + }, + + "yacht": { + name: "Yacht", + description: "Web-based Docker container manager with template support", + icon: "\u26F5", + category: "Management", + popularity: 65, + difficulty: "Easy", + docker: { + image: "selfhostedpro/yacht:latest", + ports: ["{{PORT}}:8000"], + volumes: ["/opt/yacht/config:/config", "/var/run/docker.sock:/var/run/docker.sock"], + environment: { "PUID": "1000", "PGID": "1000" } + }, + subdomain: "yacht", + defaultPort: 8094, + healthCheck: "/", + subpathSupport: 'strip', + setupInstructions: ["Set up admin account on first launch", "Add compose templates for one-click deployments", "Manage containers through the web interface"] + }, + + "openvpn": { + name: "OpenVPN", + description: "Virtual private network server for secure remote access", + icon: "\u{1F512}", + category: "Security", + popularity: 78, + difficulty: "Intermediate", + docker: { + image: "kylemanna/openvpn:latest", + ports: ["{{PORT}}:1194/udp"], + volumes: ["/opt/openvpn:/etc/openvpn"], + environment: {}, + cap_add: ["NET_ADMIN"] + }, + subdomain: "openvpn", + defaultPort: 1194, + healthCheck: null, + subpathSupport: 'none', + setupInstructions: ["Initialize the PKI: docker exec openvpn ovpn_initpki", "Generate client certificates for each device", "Download client configs and import into OpenVPN client"] + }, + + "forgejo": { + name: "Forgejo", + description: "Self-hosted Git service - soft fork of Gitea with enhanced features", + icon: "\u{1F527}", + category: "Development", + popularity: 73, + difficulty: "Easy", + docker: { + image: "codeberg.org/forgejo/forgejo:latest", + ports: ["{{PORT}}:3000", "2222:22"], + volumes: ["/opt/forgejo/data:/data", "/etc/localtime:/etc/localtime:ro"], + environment: { "USER_UID": "1000", "USER_GID": "1000" } + }, + subdomain: "forgejo", + defaultPort: 8095, + healthCheck: "/api/v1/version", + subpathSupport: 'native', + setupInstructions: ["Configure database on first run", "Create admin account and disable open registration", "Migrate repos from GitHub/GitLab via the built-in migration tool", "Set up Actions for CI/CD pipelines"] + }, + + "gitlab": { + name: "GitLab", + description: "Complete DevOps platform with Git, CI/CD, and project management", + icon: "\u{1F99A}", + category: "Development", + popularity: 88, + difficulty: "Advanced", + docker: { + image: "gitlab/gitlab-ce:latest", + ports: ["{{PORT}}:80", "8443:443", "2223:22"], + volumes: ["/opt/gitlab/config:/etc/gitlab", "/opt/gitlab/logs:/var/log/gitlab", "/opt/gitlab/data:/var/opt/gitlab"], + environment: { "GITLAB_OMNIBUS_CONFIG": "external_url https://{{SUBDOMAIN}}.{{TLD}}" }, + shm_size: "256m" + }, + subdomain: "gitlab", + defaultPort: 8096, + healthCheck: "/-/health", + subpathSupport: 'none', + setupInstructions: ["Requires at least 4GB RAM and 2 CPU cores", "Wait 5-10 minutes for first boot", "Set root password on first login", "Configure runners for CI/CD pipelines"], + resourceWarning: { minMemoryMB: 4096, minCpuCores: 2, message: "GitLab requires at least 4GB RAM. Deploying on a smaller server may cause instability." } + }, + + "prometheus": { + name: "Prometheus", + description: "Monitoring system with time-series database and alerting", + icon: "\u{1F525}", + category: "Monitoring", + popularity: 85, + difficulty: "Intermediate", + docker: { + image: "prom/prometheus:latest", + ports: ["{{PORT}}:9090"], + volumes: ["/opt/prometheus/data:/prometheus", "/opt/prometheus/config:/etc/prometheus"], + environment: {}, + command: ["--config.file=/etc/prometheus/prometheus.yml", "--storage.tsdb.path=/prometheus", "--web.enable-lifecycle"] + }, + subdomain: "prometheus", + defaultPort: 9090, + healthCheck: "/-/healthy", + subpathSupport: 'native', + setupInstructions: ["Edit /opt/prometheus/config/prometheus.yml to add scrape targets", "Add DashCaddy /api/v1/metrics/prometheus as a scrape target", "Pair with Grafana for dashboards", "Configure alert rules"] + }, + + "netdata": { + name: "Netdata", + description: "Real-time system metrics with zero configuration monitoring", + icon: "\u{1F4C8}", + category: "Monitoring", + popularity: 82, + difficulty: "Easy", + docker: { + image: "netdata/netdata:latest", + ports: ["{{PORT}}:19999"], + volumes: ["/opt/netdata/config:/etc/netdata", "/opt/netdata/lib:/var/lib/netdata", "/opt/netdata/cache:/var/cache/netdata", "/proc:/host/proc:ro", "/sys:/host/sys:ro", "/etc/os-release:/host/etc/os-release:ro"], + environment: { "NETDATA_CLAIM_URL": "https://app.netdata.cloud" }, + cap_add: ["SYS_PTRACE"], + security_opt: ["apparmor:unconfined"] + }, + subdomain: "netdata", + defaultPort: 19999, + healthCheck: "/api/v1/info", + subpathSupport: 'native', + setupInstructions: ["Dashboard is immediately available with zero configuration", "Monitor CPU, RAM, disk, network, Docker in real-time", "Configure alarms for resource thresholds", "Optional: claim to Netdata Cloud for centralized monitoring"] + }, + + "kibana": { + name: "Kibana", + description: "Visualization dashboard for Elasticsearch data analytics", + icon: "\u{1F4C9}", + category: "Monitoring", + popularity: 70, + difficulty: "Advanced", + docker: { + image: "kibana:8.12.0", + ports: ["{{PORT}}:5601"], + volumes: ["/opt/kibana/config:/usr/share/kibana/config"], + environment: { "ELASTICSEARCH_HOSTS": "http://elasticsearch:9200" } + }, + subdomain: "kibana", + defaultPort: 5601, + healthCheck: "/api/status", + subpathSupport: 'native', + setupInstructions: ["Requires an Elasticsearch instance running first", "Consider deploying via the ELK Stack recipe", "Create index patterns for your data", "Build dashboards and visualizations"] + }, + + "openhab": { + name: "OpenHAB", + description: "Open source home automation platform with broad device support", + icon: "\u2699\uFE0F", + category: "Home Automation", + popularity: 72, + difficulty: "Intermediate", + docker: { + image: "openhab/openhab:latest", + ports: ["{{PORT}}:8080", "8444:8443"], + volumes: ["/opt/openhab/conf:/openhab/conf", "/opt/openhab/userdata:/openhab/userdata", "/opt/openhab/addons:/openhab/addons", "/etc/localtime:/etc/localtime:ro"], + environment: { "OPENHAB_HTTP_PORT": "8080", "OPENHAB_HTTPS_PORT": "8443", "EXTRA_JAVA_OPTS": "-Duser.timezone={{TIMEZONE}}" } + }, + subdomain: "openhab", + defaultPort: 8097, + healthCheck: "/start/index", + subpathSupport: 'none', + setupInstructions: ["Choose your preferred package (Standard, Demo, or Minimal)", "Install bindings for your smart home devices", "Create items, sitemaps, and rules", "Access the Paper UI for configuration"] + }, + + "bitwarden": { + name: "Bitwarden", + description: "Official Bitwarden password manager server (unified self-hosted)", + icon: "\u{1F510}", + category: "Security", + popularity: 80, + difficulty: "Advanced", + docker: { + image: "bitwarden/self-host:latest", + ports: ["{{PORT}}:8080"], + volumes: ["/opt/bitwarden/data:/etc/bitwarden"], + environment: { "BW_DOMAIN": "{{SUBDOMAIN}}.{{TLD}}" } + }, + subdomain: "bitwarden", + defaultPort: 8098, + healthCheck: "/health", + subpathSupport: 'none', + setupInstructions: ["Complete the Bitwarden unified installation", "Generate installation ID and key at bitwarden.com/host", "Configure SMTP for email verification", "Note: Vaultwarden is recommended for smaller deployments"], + resourceWarning: { minMemoryMB: 2048, message: "Official Bitwarden requires 2GB+ RAM. For lightweight deployments, use Vaultwarden instead." } + }, + + "subsonic": { + name: "Subsonic", + description: "Web-based media streamer for music with wide client support", + icon: "\u{1F3B5}", + category: "Media", + popularity: 60, + difficulty: "Easy", + docker: { + image: "linuxserver/subsonic:latest", + ports: ["{{PORT}}:4040"], + volumes: ["/opt/subsonic/config:/config", "/opt/subsonic/music:/music", "/opt/subsonic/podcasts:/podcasts", "/opt/subsonic/playlists:/playlists"], + environment: { "PUID": "1000", "PGID": "1000", "TZ": "{{TIMEZONE}}" } + }, + subdomain: "subsonic", + defaultPort: 4040, + healthCheck: "/", + subpathSupport: 'native', + setupInstructions: ["Set admin password on first launch", "Add music folders in Settings", "Install Subsonic-compatible apps on your devices", "Note: Airsonic Advanced is also available as a fully open-source alternative"], + mediaMount: { required: true, containerPath: "/music", label: "Music Library", description: "Folder containing your music files", defaultPath: "/media/music" } + }, + }; // Template categories for organization