Merge pull request #121 from Dokploy/feat/add-templates-ref

Feat/add templates ref
This commit is contained in:
Mauricio Siu
2026-01-29 18:47:45 -06:00
committed by GitHub
11 changed files with 3001 additions and 917 deletions

View File

@@ -14,6 +14,8 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --filter=./apps/d
# Generate OpenAPI documentation from apps/docs/public/openapi.json # Generate OpenAPI documentation from apps/docs/public/openapi.json
RUN pnpm --filter=./apps/docs run build:docs RUN pnpm --filter=./apps/docs run build:docs
# Generate templates
RUN pnpm --filter=./apps/docs run generate-templates
# Deploy only the dokploy app # Deploy only the dokploy app
ENV NODE_ENV=production ENV NODE_ENV=production

View File

@@ -21,6 +21,9 @@ _openapi:
- depth: 2 - depth: 2
title: Registry test Registry title: Registry test Registry
url: '#registry-test-registry' url: '#registry-test-registry'
- depth: 2
title: Registry test Registry By Id
url: '#registry-test-registry-by-id'
structuredData: structuredData:
headings: headings:
- content: Registry create - content: Registry create
@@ -35,9 +38,11 @@ _openapi:
id: registry-one id: registry-one
- content: Registry test Registry - content: Registry test Registry
id: registry-test-registry id: registry-test-registry
- content: Registry test Registry By Id
id: registry-test-registry-by-id
contents: [] contents: []
--- ---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
<APIPage document={"./public/openapi.json"} webhooks={[]} operations={[{"path":"/registry.create","method":"post"},{"path":"/registry.remove","method":"post"},{"path":"/registry.update","method":"post"},{"path":"/registry.all","method":"get"},{"path":"/registry.one","method":"get"},{"path":"/registry.testRegistry","method":"post"}]} showTitle={true} /> <APIPage document={"./public/openapi.json"} webhooks={[]} operations={[{"path":"/registry.create","method":"post"},{"path":"/registry.remove","method":"post"},{"path":"/registry.update","method":"post"},{"path":"/registry.all","method":"get"},{"path":"/registry.one","method":"get"},{"path":"/registry.testRegistry","method":"post"},{"path":"/registry.testRegistryById","method":"post"}]} showTitle={true} />

View File

@@ -3,6 +3,9 @@ title: Settings
full: true full: true
_openapi: _openapi:
toc: toc:
- depth: 2
title: Settings get Web Server Settings
url: '#settings-get-web-server-settings'
- depth: 2 - depth: 2
title: Settings reload Server title: Settings reload Server
url: '#settings-reload-server' url: '#settings-reload-server'
@@ -93,6 +96,9 @@ _openapi:
- depth: 2 - depth: 2
title: Settings get Ip title: Settings get Ip
url: '#settings-get-ip' url: '#settings-get-ip'
- depth: 2
title: Settings update Server Ip
url: '#settings-update-server-ip'
- depth: 2 - depth: 2
title: Settings get Open Api Document title: Settings get Open Api Document
url: '#settings-get-open-api-document' url: '#settings-get-open-api-document'
@@ -143,6 +149,8 @@ _openapi:
url: '#settings-get-dokploy-cloud-ips' url: '#settings-get-dokploy-cloud-ips'
structuredData: structuredData:
headings: headings:
- content: Settings get Web Server Settings
id: settings-get-web-server-settings
- content: Settings reload Server - content: Settings reload Server
id: settings-reload-server id: settings-reload-server
- content: Settings clean Redis - content: Settings clean Redis
@@ -203,6 +211,8 @@ _openapi:
id: settings-read-traefik-file id: settings-read-traefik-file
- content: Settings get Ip - content: Settings get Ip
id: settings-get-ip id: settings-get-ip
- content: Settings update Server Ip
id: settings-update-server-ip
- content: Settings get Open Api Document - content: Settings get Open Api Document
id: settings-get-open-api-document id: settings-get-open-api-document
- content: Settings read Traefik Env - content: Settings read Traefik Env
@@ -240,4 +250,4 @@ _openapi:
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
<APIPage document={"./public/openapi.json"} webhooks={[]} operations={[{"path":"/settings.reloadServer","method":"post"},{"path":"/settings.cleanRedis","method":"post"},{"path":"/settings.reloadRedis","method":"post"},{"path":"/settings.reloadTraefik","method":"post"},{"path":"/settings.toggleDashboard","method":"post"},{"path":"/settings.cleanUnusedImages","method":"post"},{"path":"/settings.cleanUnusedVolumes","method":"post"},{"path":"/settings.cleanStoppedContainers","method":"post"},{"path":"/settings.cleanDockerBuilder","method":"post"},{"path":"/settings.cleanDockerPrune","method":"post"},{"path":"/settings.cleanAll","method":"post"},{"path":"/settings.cleanMonitoring","method":"post"},{"path":"/settings.saveSSHPrivateKey","method":"post"},{"path":"/settings.assignDomainServer","method":"post"},{"path":"/settings.cleanSSHPrivateKey","method":"post"},{"path":"/settings.updateDockerCleanup","method":"post"},{"path":"/settings.readTraefikConfig","method":"get"},{"path":"/settings.updateTraefikConfig","method":"post"},{"path":"/settings.readWebServerTraefikConfig","method":"get"},{"path":"/settings.updateWebServerTraefikConfig","method":"post"},{"path":"/settings.readMiddlewareTraefikConfig","method":"get"},{"path":"/settings.updateMiddlewareTraefikConfig","method":"post"},{"path":"/settings.getUpdateData","method":"post"},{"path":"/settings.updateServer","method":"post"},{"path":"/settings.getDokployVersion","method":"get"},{"path":"/settings.getReleaseTag","method":"get"},{"path":"/settings.readDirectories","method":"get"},{"path":"/settings.updateTraefikFile","method":"post"},{"path":"/settings.readTraefikFile","method":"get"},{"path":"/settings.getIp","method":"get"},{"path":"/settings.getOpenApiDocument","method":"get"},{"path":"/settings.readTraefikEnv","method":"get"},{"path":"/settings.writeTraefikEnv","method":"post"},{"path":"/settings.haveTraefikDashboardPortEnabled","method":"get"},{"path":"/settings.haveActivateRequests","method":"get"},{"path":"/settings.toggleRequests","method":"post"},{"path":"/settings.isCloud","method":"get"},{"path":"/settings.isUserSubscribed","method":"get"},{"path":"/settings.health","method":"get"},{"path":"/settings.setupGPU","method":"post"},{"path":"/settings.checkGPUStatus","method":"get"},{"path":"/settings.updateTraefikPorts","method":"post"},{"path":"/settings.getTraefikPorts","method":"get"},{"path":"/settings.updateLogCleanup","method":"post"},{"path":"/settings.getLogCleanupStatus","method":"get"},{"path":"/settings.getDokployCloudIps","method":"get"}]} showTitle={true} /> <APIPage document={"./public/openapi.json"} webhooks={[]} operations={[{"path":"/settings.getWebServerSettings","method":"get"},{"path":"/settings.reloadServer","method":"post"},{"path":"/settings.cleanRedis","method":"post"},{"path":"/settings.reloadRedis","method":"post"},{"path":"/settings.reloadTraefik","method":"post"},{"path":"/settings.toggleDashboard","method":"post"},{"path":"/settings.cleanUnusedImages","method":"post"},{"path":"/settings.cleanUnusedVolumes","method":"post"},{"path":"/settings.cleanStoppedContainers","method":"post"},{"path":"/settings.cleanDockerBuilder","method":"post"},{"path":"/settings.cleanDockerPrune","method":"post"},{"path":"/settings.cleanAll","method":"post"},{"path":"/settings.cleanMonitoring","method":"post"},{"path":"/settings.saveSSHPrivateKey","method":"post"},{"path":"/settings.assignDomainServer","method":"post"},{"path":"/settings.cleanSSHPrivateKey","method":"post"},{"path":"/settings.updateDockerCleanup","method":"post"},{"path":"/settings.readTraefikConfig","method":"get"},{"path":"/settings.updateTraefikConfig","method":"post"},{"path":"/settings.readWebServerTraefikConfig","method":"get"},{"path":"/settings.updateWebServerTraefikConfig","method":"post"},{"path":"/settings.readMiddlewareTraefikConfig","method":"get"},{"path":"/settings.updateMiddlewareTraefikConfig","method":"post"},{"path":"/settings.getUpdateData","method":"post"},{"path":"/settings.updateServer","method":"post"},{"path":"/settings.getDokployVersion","method":"get"},{"path":"/settings.getReleaseTag","method":"get"},{"path":"/settings.readDirectories","method":"get"},{"path":"/settings.updateTraefikFile","method":"post"},{"path":"/settings.readTraefikFile","method":"get"},{"path":"/settings.getIp","method":"get"},{"path":"/settings.updateServerIp","method":"post"},{"path":"/settings.getOpenApiDocument","method":"get"},{"path":"/settings.readTraefikEnv","method":"get"},{"path":"/settings.writeTraefikEnv","method":"post"},{"path":"/settings.haveTraefikDashboardPortEnabled","method":"get"},{"path":"/settings.haveActivateRequests","method":"get"},{"path":"/settings.toggleRequests","method":"post"},{"path":"/settings.isCloud","method":"get"},{"path":"/settings.isUserSubscribed","method":"get"},{"path":"/settings.health","method":"get"},{"path":"/settings.setupGPU","method":"post"},{"path":"/settings.checkGPUStatus","method":"get"},{"path":"/settings.updateTraefikPorts","method":"post"},{"path":"/settings.getTraefikPorts","method":"get"},{"path":"/settings.updateLogCleanup","method":"post"},{"path":"/settings.getLogCleanupStatus","method":"get"},{"path":"/settings.getDokployCloudIps","method":"get"}]} showTitle={true} />

View File

@@ -35,7 +35,6 @@
"applications", "applications",
"docker-compose", "docker-compose",
"databases", "databases",
"templates",
"(examples)", "(examples)",
"auto-deploy", "auto-deploy",
"schedule-jobs", "schedule-jobs",

View File

@@ -1,122 +0,0 @@
---
title: Open Source Templates
description: Deploy open source templates with Dokploy
---
By default we include a set of templates, that you can use to spin up templates quickly. You can also create your own templates.
## Templates
The following templates are available (100):
- **Appwrite**: End-to-end backend server for Web, Mobile, Native, or Backend apps with user authentication, database, storage, and more.
- **Outline**: Self-hosted knowledge base and documentation platform.
- **Supabase**: The open-source Firebase alternative with a dedicated Postgres database for web, mobile, and AI applications.
- **Pocketbase**: Open-source backend for your next SaaS and Mobile app in 1 file.
- **Plausible**: Open-source, privacy-focused, self-hosted web analytics platform.
- **Calcom**: Open-source alternative to Calendly for creating scheduling and booking services.
- **Grafana**: Open-source platform for data visualization and monitoring.
- **Directus**: API-first, open-source headless CMS for building custom backends.
- **Baserow**: Open-source database management tool.
- **Budibase**: Open-source low-code platform for building forms, portals, and approval apps.
- **Ghost**: Professional publishing platform built on Node.js.
- **Uptime Kuma**: Free and open-source monitoring tool.
- **n8n**: Open-source low-code platform for automating workflows.
- **Wordpress**: Free and open-source CMS for publishing websites.
- **Odoo**: Free and open-source business management software.
- **Appsmith**: Open-source platform for building internal tools.
- **Excalidraw**: Open-source online diagramming tool.
- **Documenso**: Open-source alternative to DocuSign.
- **NocoDB**: Airtable alternative for databases.
- **Meilisearch**: Free and open-source search engine.
- **Phpmyadmin**: Web interface for MySQL/MariaDB management.
- **Rocketchat**: Open-source web chat platform.
- **Minio**: Open-source object storage server.
- **Metabase**: Open-source business intelligence tool.
- **Glitchtip**: Simple, open-source error tracking.
- **Open WebUI**: Open-source ChatGPT alternative.
- **Listmonk**: Self-hosted newsletter manager.
- **Double Zero**: Self-hostable SES dashboard.
- **Umami**: Privacy-focused analytics alternative.
- **Jellyfin**: Free software media system.
- **Teable**: No-code database with spreadsheet interface.
- **Zipline**: ShareX/file upload server.
- **Soketi**: Open-source WebSockets server.
- **Aptabase**: Self-hosted analytics platform.
- **Typebot**: Open-source chatbot builder.
- **Gitea**: Self-hosted software development service.
- **Roundcube**: Open-source webmail software.
- **File Browser**: Web-based file manager.
- **Tolgee**: Web-based localization platform.
- **Portainer**: Container management tool.
- **InfluxDB**: Time-series data platform.
- **Infisical**: Configuration and secrets manager.
- **Docmost**: Collaborative wiki software.
- **Vaultwarden**: Bitwarden-compatible server.
- **Hi.events**: Event management platform.
- **Windows/MacOS**: Dockerized operating systems.
- **Coder**: Cloud development environment.
- **Stirling PDF**: PDF tools suite.
- **Lobe Chat**: Modern AI chat framework.
- **Peppermint**: API development platform.
- **Windmill**: Workflow and internal apps platform.
- **Activepieces**: No-code automation tool.
- **InvoiceShelf**: Self-hosted invoicing system.
- **Postiz**: Content management platform.
- **Slash**: Bookmarking and link shortener.
- **Discord Tickets**: Support ticket bot.
- **Nextcloud AIO**: File storage and collaboration.
- **Blender**: 3D creation suite.
- **HeyForm**: Conversational form builder.
- **Chatwoot**: Customer engagement platform.
- **Discourse**: Modern forum software.
- **Immich**: Photo/video backup solution.
- **Twenty CRM**: Modern CRM alternative.
- **YOURLS**: URL shortening service.
- **Ryot**: Media tracking platform.
- **PhotoPrism**: AI-powered photos app.
- **Ontime**: Event rundown manager.
- **Trigger.dev**: Event-driven application platform.
- **Browserless**: Headless browser automation.
- **draw.io**: Diagramming application.
- **Kimai**: Time-tracking application.
- **Logto**: Identity management platform.
- **Penpot**: Open-source design tool.
- **Huly**: Project management platform.
- **Unsend**: Email service platform.
- **Langflow**: Low-code AI application builder.
- **Elasticsearch**: Search and analytics engine.
- **OneDev**: Git server with CI/CD.
- **Unifi Network**: Network management platform.
- **GLPI**: Service management software.
- **Checkmate**: Server monitoring tool.
- **Gotenberg**: PDF generation API.
- **Actual Budget**: Privacy-focused finance app.
- **Conduit/Conduwuit**: Matrix chat servers.
- **Cloudflared**: Cloudflare Tunnel daemon.
- **CouchDB**: Document-oriented database.
- **IT Tools**: Developer utilities collection.
- **Superset**: Data visualization platform.
- **Glance/Homarr**: Dashboard solutions.
- **ERPNext**: Open-source ERP software.
- **Maybe**: Finance tracking application.
- **Spacedrive**: Cross-platform file manager.
- **AList**: Multi-storage file manager.
- **Answer**: Q&A platform.
- **Shlink**: URL shortener.
- **Frappe HR**: HR & Payroll software.
- **Formbricks**: Survey platform.
- **Trilium**: Note-taking application.
- **Convex**: Reactive database platform.
For an up to date list of available template you can visit [Dokploy templates website](https://templates.dokploy.com/).
## Create your own template
We accept contributions to upload new templates to the dokploy repository.
Make sure to follow the guidelines for creating a template:
[Steps to create your own template](https://github.com/Dokploy/templates)
[^1]: Please note that if you're self-hosting a mail server you need port 25 to be open for SMTP (Mail Transmission Protocol that allows you to send and receive) to work properly. Some VPS providers like [Hetzner](https://docs.hetzner.com/cloud/servers/faq/#why-can-i-not-send-any-mails-from-my-server) block this port by default for new clients.

View File

@@ -1,3 +1,3 @@
{ {
"pages": ["core", "cli", "api"] "pages": ["core", "cli", "api", "templates"]
} }

View File

@@ -1,6 +1,7 @@
import { APIPage } from "@/lib/source"; import { APIPage } from "@/lib/source";
import { Callout } from "fumadocs-ui/components/callout"; import { Callout } from "fumadocs-ui/components/callout";
import { ImageZoom } from "fumadocs-ui/components/image-zoom"; import { ImageZoom } from "fumadocs-ui/components/image-zoom";
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
import defaultMdxComponents from "fumadocs-ui/mdx"; import defaultMdxComponents from "fumadocs-ui/mdx";
import type { MDXComponents } from "mdx/types"; import type { MDXComponents } from "mdx/types";
@@ -9,6 +10,8 @@ export function getMDXComponents(components?: MDXComponents): MDXComponents {
...defaultMdxComponents, ...defaultMdxComponents,
ImageZoom, ImageZoom,
Callout, Callout,
Tab,
Tabs,
APIPage, APIPage,
...components, ...components,
p: ({ children }) => ( p: ({ children }) => (

View File

@@ -5,6 +5,14 @@ const withMDX = createMDX();
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const config = { const config = {
reactStrictMode: true, reactStrictMode: true,
images: {
remotePatterns: [
{
protocol: "https",
hostname: "templates.dokploy.com",
},
],
},
}; };
export default withMDX(config); export default withMDX(config);

View File

@@ -9,7 +9,8 @@
"types:check": "fumadocs-mdx && tsc --noEmit", "types:check": "fumadocs-mdx && tsc --noEmit",
"postinstall": "fumadocs-mdx", "postinstall": "fumadocs-mdx",
"fix-openapi": "node scripts/fix-openapi.mjs", "fix-openapi": "node scripts/fix-openapi.mjs",
"build:docs": "npm run fix-openapi && node generate-docs.mjs" "generate-templates": "node scripts/generate-templates.mjs",
"build:docs": "npm run fix-openapi && npm run generate-templates && node generate-docs.mjs"
}, },
"dependencies": { "dependencies": {
"@next/third-parties": "16.0.7", "@next/third-parties": "16.0.7",

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,193 @@
import fs from 'node:fs';
import path from 'node:path';
const TEMPLATES_URL = 'https://templates.dokploy.com/meta.json';
const BASE_BLUEPRINT_URL = 'https://templates.dokploy.com/blueprints';
const OUTPUT_DIR = './content/docs/templates';
async function fetchWithTimeout(url, options = {}, timeout = 10000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
...options,
signal: controller.signal
});
clearTimeout(id);
return response;
} catch (e) {
clearTimeout(id);
throw e;
}
}
async function getTemplateFile(id, fileName) {
try {
const response = await fetchWithTimeout(`${BASE_BLUEPRINT_URL}/${id}/${fileName}`);
if (!response.ok) return null;
return await response.text();
} catch (error) {
console.error(`Error fetching ${fileName} for ${id}:`, error.message);
return null;
}
}
/** Normalize and indent code so it renders correctly inside MDX code blocks (preserves YAML/TOML formatting). */
function formatCodeForMdx(code) {
if (!code || !code.trim()) return '# Not available';
return code
.replace(/\r\n/g, '\n')
.trim()
.split('\n')
.map((line) => line.trimEnd())
.join('\n')
.split('\n')
.map(line => ` ${line}`)
.join('\n');
}
/** Build Base64 payload for Dokploy import (same format as UI: compose + config as JSON, then base64). */
function templateToBase64(dockerCompose, config) {
const configObj = {
compose: dockerCompose || '',
config: config || '',
};
const jsonString = JSON.stringify(configObj, null, 2);
return Buffer.from(jsonString, 'utf-8').toString('base64');
}
async function generateTemplates() {
try {
console.log('Fetching templates metadata...');
const response = await fetch(TEMPLATES_URL);
const templates = await response.json();
console.log(`Found ${templates.length} templates. Starting data collection...`);
if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
}
const batchSize = 10;
for (let i = 0; i < templates.length; i += batchSize) {
const batch = templates.slice(i, i + batchSize);
console.log(`Processing batch ${i / batchSize + 1}/${Math.ceil(templates.length / batchSize)}...`);
await Promise.all(batch.map(async (template) => {
const composeYaml = await getTemplateFile(template.id, 'docker-compose.yml');
const templateToml = await getTemplateFile(template.id, 'template.toml');
const instructionsRaw = await getTemplateFile(template.id, 'instructions.md');
const hasRealInstructions =
instructionsRaw &&
instructionsRaw.trim().length > 0 &&
!/^\s*<!doctype/i.test(instructionsRaw.trim()) &&
!/^\s*<html\b/i.test(instructionsRaw.trim());
const instructionsSafe = hasRealInstructions
? instructionsRaw.trim().replace(/\$\{/g, '\\${')
: '';
const safeDescription = template.description.replace(/"/g, '\\"');
const safeName = template.name.replace(/"/g, '\\"');
const logoUrl = `${BASE_BLUEPRINT_URL}/${template.id}/${template.logo}`;
const mdxContent = `---
title: "${safeName}"
description: "${safeDescription}"
---
<ImageZoom
src="${logoUrl}"
alt="${template.name} logo"
width={100}
height={100}
className="my-8 rounded-xl"
/>
## Configuration
<Tabs items={["docker-compose.yml", "template.toml"]}>
<Tab value="docker-compose.yml">
\`\`\`yaml
${formatCodeForMdx(composeYaml)}
\`\`\`
</Tab>
<Tab value="template.toml">
\`\`\`toml
${formatCodeForMdx(templateToml)}
\`\`\`
</Tab>
</Tabs>
## Base64
To import this template in Dokploy: create a **Compose** service → **Advanced** → **Base64 import** and paste the content below:
\`\`\`text
${templateToBase64(composeYaml, templateToml)}
\`\`\`
${instructionsSafe ? `
## Instructions
${instructionsSafe}
` : ''}
## Links
${template.links.website ? `- [Website](${template.links.website})` : ''}
${template.links.github ? `- [Github](${template.links.github})` : ''}
${template.links.docs ? `- [Documentation](${template.links.docs})` : ''}
## Tags
${template.tags.map(tag => `\`${tag}\``).join(', ')}
---
Version: \`${template.version}\`
`;
fs.writeFileSync(path.join(OUTPUT_DIR, `${template.id}.mdx`), mdxContent);
}));
}
// Generate index.mdx
const indexContent = `---
title: Introduction
description: Browse our collection of ${templates.length}+ self-hosted open source templates
---
# Templates
Welcome to the Dokploy Templates collection. We currently have **${templates.length}+** pre-configured templates that you can deploy with a single click.
Our templates cover a wide range of categories, including:
- **Databases**: PostgreSQL, MySQL, MongoDB, Redis, and more.
- **CMS**: WordPress, Ghost, Straple, Directus.
- **Analytics**: Umami, Plausible, Ackee.
- **Development Tools**: Gitea, Jenkins, Woodpecker CI.
- **And much more!**
Explore the sidebar to find the template you need.
`;
fs.writeFileSync(path.join(OUTPUT_DIR, 'index.mdx'), indexContent);
// Update meta.json with all template IDs
const metaContent = {
title: "Templates",
description: `Browse our collection of ${templates.length}+ self-hosted open source templates`,
icon: "LayoutGrid",
root: true,
pages: [
"index",
"---Templates---",
...templates.map(t => t.id)
]
};
fs.writeFileSync(path.join(OUTPUT_DIR, 'meta.json'), JSON.stringify(metaContent, null, 2));
console.log('✓ Successfully generated template documentation');
} catch (error) {
console.error('Error generating templates:', error);
process.exit(1);
}
}
generateTemplates();