diff --git a/.github/workflows/base64-templates.yml b/.github/workflows/base64-templates.yml
deleted file mode 100644
index 80010d109..000000000
--- a/.github/workflows/base64-templates.yml
+++ /dev/null
@@ -1,66 +0,0 @@
-name: Generate Base64 Blueprints Table
-
-on:
- pull_request:
- branches:
- - main
- push:
- branches:
- - main
-
-jobs:
- encode-and-comment:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout repo
- uses: actions/checkout@v4
-
- - name: Generate base64 for blueprints
- id: generate
- run: |
- echo "### 📝 Blueprints Base64 Table" > comment.md
- echo '' >> comment.md
-
- echo "You can use the base64 value to import the blueprint into the UI." >> comment.md
- echo "" >> comment.md
- echo "🔍 Show all blueprints base64 " >> comment.md
- echo '' >> comment.md
-
- for dir in blueprints/*; do
- if [ -d "$dir" ]; then
- TEMPLATE_NAME=$(basename "$dir")
-
- COMPOSE_FILE="$dir/docker-compose.yml"
- TEMPLATE_FILE="$dir/template.yml"
-
- if [ -f "$COMPOSE_FILE" ] && [ -f "$TEMPLATE_FILE" ]; then
- COMPOSE_CONTENT=$(jq -Rs . < "$COMPOSE_FILE")
- TEMPLATE_CONTENT=$(jq -Rs . < "$TEMPLATE_FILE")
-
- JSON="{\"compose\":$COMPOSE_CONTENT,\"config\":$TEMPLATE_CONTENT}"
- BASE64_JSON=$(echo -n "$JSON" | base64 -w 0)
-
- echo "#### $TEMPLATE_NAME" >> comment.md
- echo '' >> comment.md
- echo '```' >> comment.md
- echo "$BASE64_JSON" >> comment.md
- echo '```' >> comment.md
- echo ''
- fi
- fi
- done
-
- echo ' ' >> comment.md
-
- - name: Post comment to PR
- uses: marocchino/sticky-pull-request-comment@v2
- if: github.event_name == 'pull_request'
- with:
- path: comment.md
-
- - name: Post comment to commit (fallback)
- uses: peter-evans/commit-comment@v3
- if: github.event_name != 'pull_request'
- with:
- body-path: comment.md
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 37cb7e2e2..000000000
--- a/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-node_modules/
-.DS_Store
-*.log
-dist/
-.env
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index fe1941000..0663e82a0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2024 Dokploy
+Copyright (c) 2024 Dokploy and Carlos Ortiz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..eebb475e8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,146 @@
+# Dokploy Open Source Templates
+
+This is the official repository for the Dokploy Open Source Templates.
+
+### How to add a new template
+
+1. Fork the repository
+2. Create a new branch
+3. Add the template to the `blueprints` folder (docker-compose.yml, template.yml)
+4. Add the template metadata (name, description, version, logo, links, tags) to the `meta.json` file
+5. Add the logo to the template folder
+6. Commit and push your changes
+7. Create a pull request (PR)
+8. Every PR will automatically deploy a preview of the template to Dokploy.
+9. if anyone want to test the template before merging it, you can enter to the preview URL in the PR description, and search the template, click on the Template Card, scroll down and then copy the BASE64 value, and paste in the advanced section of your compose service, in the Import section.
+
+#### Optional
+
+If you want to run the project locally, you can run the project with the following command:
+
+```bash
+cd app
+pnpm install
+pnpm run dev
+go to http://localhost:5173/
+```
+
+### Example
+
+Let's suppose you want to add the [Grafana](https://grafana.com/) template to the repository.
+
+1. Create a new folder inside the `blueprints` folder named `grafana`
+2. Add the `docker-compose.yml` file to the folder
+
+```yaml
+version: "3.8"
+services:
+ grafana:
+ image: grafana/grafana-enterprise:9.5.20
+ restart: unless-stopped
+ volumes:
+ - grafana-storage:/var/lib/grafana
+volumes:
+ grafana-storage: {}
+```
+3. Add the `template.yml` file to the folder, this is where we specify the domains, mounts and env variables, to understand more the structure of `template.yml` you can read here [Template.yml structure](#templateyml-structure)
+
+```yaml
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: grafana
+ port: 3000
+ host: ${main_domain}
+ env: []
+ mounts: []
+```
+4. Add the `meta.json` file to the folder
+
+```json
+{
+ "id": "grafana",
+ "name": "Grafana",
+ "version": "9.5.20",
+ "description": "Grafana is an open source platform for data visualization and monitoring.",
+ "logo": "grafana.svg",
+ "links": {
+ "github": "https://github.com/grafana/grafana",
+ "website": "https://grafana.com/",
+ "docs": "https://grafana.com/docs/"
+ },
+ "tags": [
+ "monitoring"
+ ]
+},
+```
+5. Add the logo to the folder
+6. Commit and push your changes
+7. Create a pull request
+
+### Template.yml structure
+
+Dokploy use a defined structure for the `template.yml` file, we have 4 sections available:
+
+
+1. `variables`: This is where we define the variables that will be used in the `domains`, `env` and `mounts` sections.
+2. `domains`: This is where we define the configuration for the template.
+3. `env`: This is where we define the environment variables for the template.
+4. `mounts`: This is where we define the mounts for the template.
+
+
+- The `variables(Optional)` structure is the following:
+
+```yaml
+variables:
+ main_domain: ${domain}
+ my_domain: https://my-domain.com
+ my_password: ${password:32}
+ any_helper: ${you-can-use-any-helper}
+```
+
+- The `config` structure is the following:
+
+```yaml
+config:
+ domains: # Optional
+ - serviceName: grafana # Required
+ port: 3000 # Required
+ host: ${main_domain} # Required
+ path: / -> Optional
+
+ env: # Optional
+ - AP_HOST=${main_domain}
+ - AP_API_KEY=${api_key}
+ - AP_ENCRYPTION_KEY=${encryption_key}
+ - AP_JWT_SECRET=${jwt_secret}
+ - AP_POSTGRES_PASSWORD=${postgres_password}
+
+ mounts: # Optional or []
+ - filePath: /content/file.txt
+ content: |
+ My content
+```
+
+Important: you can reference any variable in the `domains`, `env` and `mounts` sections. just use the `${variable_name}` syntax, in the case you don't want to define a variable, you can use the `domain`, `base64`, `password`, `hash`, `uuid`, `randomPort` or `timestamp` helpers.
+
+### Helpers
+
+We have a few helpers that are very common when creating a template, these are:
+
+- `domain`: This is a helper that will generate a random domain for the template.
+- `base64 or base64:length`: This is a helper that will encode a string to base64.
+- `password or password:length`: This is a helper that will generate a random password for the template.
+- `hash or hash:length`: This is a helper that will generate a hash for the template.
+- `uuid`: This is a helper that will generate a uuid for the template.
+- `randomPort`: This is a helper that will generate a random port for the template.
+- `timestamp`: This is a helper that will generate a timestamp.
+- `jwt or jwt:length`: This is a helper that will generate a jwt for the template.
+
+
+
+
+
+
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 000000000..a547bf36d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/app/components.json b/app/components.json
new file mode 100644
index 000000000..73afbdbcc
--- /dev/null
+++ b/app/components.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "new-york",
+ "rsc": false,
+ "tsx": true,
+ "tailwind": {
+ "config": "",
+ "css": "src/index.css",
+ "baseColor": "neutral",
+ "cssVariables": true,
+ "prefix": ""
+ },
+ "aliases": {
+ "components": "@/components",
+ "utils": "@/lib/utils",
+ "ui": "@/components/ui",
+ "lib": "@/lib",
+ "hooks": "@/hooks"
+ },
+ "iconLibrary": "lucide"
+}
\ No newline at end of file
diff --git a/app/index.html b/app/index.html
new file mode 100644
index 000000000..4600ddfec
--- /dev/null
+++ b/app/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Dokploy Blueprints
+
+
+
+
+
+
diff --git a/app/package.json b/app/package.json
new file mode 100644
index 000000000..bc134e988
--- /dev/null
+++ b/app/package.json
@@ -0,0 +1,47 @@
+{
+ "name": "my-app",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc -b && vite build",
+ "lint": "eslint .",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@radix-ui/react-dialog": "^1.1.6",
+ "@radix-ui/react-dropdown-menu": "^2.1.6",
+ "@radix-ui/react-slot": "^1.1.2",
+ "@tailwindcss/vite": "^4.0.12",
+ "class-variance-authority": "^0.7.1",
+ "clsx": "^2.1.1",
+ "copy-to-clipboard": "^3.3.3",
+ "lucide-react": "^0.479.0",
+ "next-themes": "^0.4.5",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "sonner": "^2.0.1",
+ "tailwind-merge": "^3.0.2",
+ "tailwindcss": "^4.0.12",
+ "tailwindcss-animate": "^1.0.7",
+ "vite-plugin-static-copy": "2.3.0",
+ "@codemirror/autocomplete": "^6.18.6",
+ "@codemirror/lang-json": "^6.0.1",
+ "@codemirror/lang-yaml": "^6.1.1",
+ "@codemirror/language": "^6.10.1",
+ "@codemirror/legacy-modes": "6.4.0",
+ "@codemirror/view": "6.29.0",
+ "@uiw/codemirror-theme-github": "^4.22.1",
+ "@uiw/react-codemirror": "^4.22.1"
+ },
+ "devDependencies": {
+ "@types/node": "^20.8.2",
+ "@types/react": "^19.0.10",
+ "@types/react-dom": "^19.0.4",
+ "@vitejs/plugin-react": "^4.3.4",
+ "globals": "^15.15.0",
+ "typescript": "~5.7.2",
+ "vite": "^6.2.0"
+ }
+}
diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml
new file mode 100644
index 000000000..a7869dd95
--- /dev/null
+++ b/app/pnpm-lock.yaml
@@ -0,0 +1,2642 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@codemirror/autocomplete':
+ specifier: ^6.18.6
+ version: 6.18.6
+ '@codemirror/lang-json':
+ specifier: ^6.0.1
+ version: 6.0.1
+ '@codemirror/lang-yaml':
+ specifier: ^6.1.1
+ version: 6.1.2
+ '@codemirror/language':
+ specifier: ^6.10.1
+ version: 6.10.8
+ '@codemirror/legacy-modes':
+ specifier: 6.4.0
+ version: 6.4.0
+ '@codemirror/view':
+ specifier: 6.29.0
+ version: 6.29.0
+ '@radix-ui/react-dialog':
+ specifier: ^1.1.6
+ version: 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-dropdown-menu':
+ specifier: ^2.1.6
+ version: 2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-slot':
+ specifier: ^1.1.2
+ version: 1.1.2(@types/react@19.0.10)(react@19.0.0)
+ '@tailwindcss/vite':
+ specifier: ^4.0.12
+ version: 4.0.12(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2))
+ '@uiw/codemirror-theme-github':
+ specifier: ^4.22.1
+ version: 4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)
+ '@uiw/react-codemirror':
+ specifier: ^4.22.1
+ version: 4.23.10(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.29.0)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ class-variance-authority:
+ specifier: ^0.7.1
+ version: 0.7.1
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
+ copy-to-clipboard:
+ specifier: ^3.3.3
+ version: 3.3.3
+ lucide-react:
+ specifier: ^0.479.0
+ version: 0.479.0(react@19.0.0)
+ next-themes:
+ specifier: ^0.4.5
+ version: 0.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ react:
+ specifier: ^19.0.0
+ version: 19.0.0
+ react-dom:
+ specifier: ^19.0.0
+ version: 19.0.0(react@19.0.0)
+ sonner:
+ specifier: ^2.0.1
+ version: 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ tailwind-merge:
+ specifier: ^3.0.2
+ version: 3.0.2
+ tailwindcss:
+ specifier: ^4.0.12
+ version: 4.0.12
+ tailwindcss-animate:
+ specifier: ^1.0.7
+ version: 1.0.7(tailwindcss@4.0.12)
+ vite-plugin-static-copy:
+ specifier: 2.3.0
+ version: 2.3.0(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2))
+ devDependencies:
+ '@types/node':
+ specifier: ^20.8.2
+ version: 20.17.24
+ '@types/react':
+ specifier: ^19.0.10
+ version: 19.0.10
+ '@types/react-dom':
+ specifier: ^19.0.4
+ version: 19.0.4(@types/react@19.0.10)
+ '@vitejs/plugin-react':
+ specifier: ^4.3.4
+ version: 4.3.4(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2))
+ globals:
+ specifier: ^15.15.0
+ version: 15.15.0
+ typescript:
+ specifier: ~5.7.2
+ version: 5.7.3
+ vite:
+ specifier: ^6.2.0
+ version: 6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)
+
+packages:
+
+ '@ampproject/remapping@2.3.0':
+ resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
+ engines: {node: '>=6.0.0'}
+
+ '@babel/code-frame@7.26.2':
+ resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/compat-data@7.26.8':
+ resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/core@7.26.9':
+ resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/generator@7.26.9':
+ resolution: {integrity: sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-compilation-targets@7.26.5':
+ resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-imports@7.25.9':
+ resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-transforms@7.26.0':
+ resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+
+ '@babel/helper-plugin-utils@7.26.5':
+ resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-string-parser@7.25.9':
+ resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.25.9':
+ resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-option@7.25.9':
+ resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helpers@7.26.9':
+ resolution: {integrity: sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.26.9':
+ resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/plugin-transform-react-jsx-self@7.25.9':
+ resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-transform-react-jsx-source@7.25.9':
+ resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/runtime@7.26.9':
+ resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/template@7.26.9':
+ resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/traverse@7.26.9':
+ resolution: {integrity: sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.26.9':
+ resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==}
+ engines: {node: '>=6.9.0'}
+
+ '@codemirror/autocomplete@6.18.6':
+ resolution: {integrity: sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==}
+
+ '@codemirror/commands@6.8.0':
+ resolution: {integrity: sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ==}
+
+ '@codemirror/lang-json@6.0.1':
+ resolution: {integrity: sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==}
+
+ '@codemirror/lang-yaml@6.1.2':
+ resolution: {integrity: sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw==}
+
+ '@codemirror/language@6.10.8':
+ resolution: {integrity: sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw==}
+
+ '@codemirror/legacy-modes@6.4.0':
+ resolution: {integrity: sha512-5m/K+1A6gYR0e+h/dEde7LoGimMjRtWXZFg4Lo70cc8HzjSdHe3fLwjWMR0VRl5KFT1SxalSap7uMgPKF28wBA==}
+
+ '@codemirror/lint@6.8.4':
+ resolution: {integrity: sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==}
+
+ '@codemirror/search@6.5.10':
+ resolution: {integrity: sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==}
+
+ '@codemirror/state@6.5.2':
+ resolution: {integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==}
+
+ '@codemirror/theme-one-dark@6.1.2':
+ resolution: {integrity: sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==}
+
+ '@codemirror/view@6.29.0':
+ resolution: {integrity: sha512-ED4ims4fkf7eOA+HYLVP8VVg3NMllt1FPm9PEJBfYFnidKlRITBaua38u68L1F60eNtw2YNcDN5jsIzhKZwWQA==}
+
+ '@codemirror/view@6.36.4':
+ resolution: {integrity: sha512-ZQ0V5ovw/miKEXTvjgzRyjnrk9TwriUB1k4R5p7uNnHR9Hus+D1SXHGdJshijEzPFjU25xea/7nhIeSqYFKdbA==}
+
+ '@esbuild/aix-ppc64@0.25.1':
+ resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.25.1':
+ resolution: {integrity: sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.25.1':
+ resolution: {integrity: sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.25.1':
+ resolution: {integrity: sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.25.1':
+ resolution: {integrity: sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.25.1':
+ resolution: {integrity: sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.25.1':
+ resolution: {integrity: sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.25.1':
+ resolution: {integrity: sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.25.1':
+ resolution: {integrity: sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.25.1':
+ resolution: {integrity: sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.25.1':
+ resolution: {integrity: sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.25.1':
+ resolution: {integrity: sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.25.1':
+ resolution: {integrity: sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.25.1':
+ resolution: {integrity: sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.25.1':
+ resolution: {integrity: sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.25.1':
+ resolution: {integrity: sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.25.1':
+ resolution: {integrity: sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.25.1':
+ resolution: {integrity: sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.25.1':
+ resolution: {integrity: sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.25.1':
+ resolution: {integrity: sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.25.1':
+ resolution: {integrity: sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/sunos-x64@0.25.1':
+ resolution: {integrity: sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.25.1':
+ resolution: {integrity: sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.25.1':
+ resolution: {integrity: sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.25.1':
+ resolution: {integrity: sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@floating-ui/core@1.6.9':
+ resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==}
+
+ '@floating-ui/dom@1.6.13':
+ resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==}
+
+ '@floating-ui/react-dom@2.1.2':
+ resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+
+ '@floating-ui/utils@0.2.9':
+ resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==}
+
+ '@jridgewell/gen-mapping@0.3.8':
+ resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/set-array@1.2.1':
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.0':
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+
+ '@lezer/common@1.2.3':
+ resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==}
+
+ '@lezer/highlight@1.2.1':
+ resolution: {integrity: sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==}
+
+ '@lezer/json@1.0.3':
+ resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==}
+
+ '@lezer/lr@1.4.2':
+ resolution: {integrity: sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==}
+
+ '@lezer/yaml@1.0.3':
+ resolution: {integrity: sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA==}
+
+ '@marijn/find-cluster-break@1.0.2':
+ resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@radix-ui/primitive@1.1.1':
+ resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==}
+
+ '@radix-ui/react-arrow@1.1.2':
+ resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-collection@1.1.2':
+ resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-compose-refs@1.1.1':
+ resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-context@1.1.1':
+ resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-dialog@1.1.6':
+ resolution: {integrity: sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-direction@1.1.0':
+ resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-dismissable-layer@1.1.5':
+ resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-dropdown-menu@2.1.6':
+ resolution: {integrity: sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-focus-guards@1.1.1':
+ resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-focus-scope@1.1.2':
+ resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-id@1.1.0':
+ resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-menu@2.1.6':
+ resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-popper@1.2.2':
+ resolution: {integrity: sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-portal@1.1.4':
+ resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-presence@1.1.2':
+ resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-primitive@2.0.2':
+ resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-roving-focus@1.1.2':
+ resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-slot@1.1.2':
+ resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-callback-ref@1.1.0':
+ resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-controllable-state@1.1.0':
+ resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-escape-keydown@1.1.0':
+ resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-layout-effect@1.1.0':
+ resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-rect@1.1.0':
+ resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-size@1.1.0':
+ resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/rect@1.1.0':
+ resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==}
+
+ '@rollup/rollup-android-arm-eabi@4.35.0':
+ resolution: {integrity: sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.35.0':
+ resolution: {integrity: sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.35.0':
+ resolution: {integrity: sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.35.0':
+ resolution: {integrity: sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.35.0':
+ resolution: {integrity: sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.35.0':
+ resolution: {integrity: sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.35.0':
+ resolution: {integrity: sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.35.0':
+ resolution: {integrity: sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.35.0':
+ resolution: {integrity: sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.35.0':
+ resolution: {integrity: sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loongarch64-gnu@4.35.0':
+ resolution: {integrity: sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.35.0':
+ resolution: {integrity: sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.35.0':
+ resolution: {integrity: sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.35.0':
+ resolution: {integrity: sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.35.0':
+ resolution: {integrity: sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.35.0':
+ resolution: {integrity: sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-win32-arm64-msvc@4.35.0':
+ resolution: {integrity: sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.35.0':
+ resolution: {integrity: sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.35.0':
+ resolution: {integrity: sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==}
+ cpu: [x64]
+ os: [win32]
+
+ '@tailwindcss/node@4.0.12':
+ resolution: {integrity: sha512-a6J11K1Ztdln9OrGfoM75/hChYPcHYGNYimqciMrvKXRmmPaS8XZTHhdvb5a3glz4Kd4ZxE1MnuFE2c0fGGmtg==}
+
+ '@tailwindcss/oxide-android-arm64@4.0.12':
+ resolution: {integrity: sha512-dAXCaemu3mHLXcA5GwGlQynX8n7tTdvn5i1zAxRvZ5iC9fWLl5bGnjZnzrQqT7ttxCvRwdVf3IHUnMVdDBO/kQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [android]
+
+ '@tailwindcss/oxide-darwin-arm64@4.0.12':
+ resolution: {integrity: sha512-vPNI+TpJQ7sizselDXIJdYkx9Cu6JBdtmRWujw9pVIxW8uz3O2PjgGGzL/7A0sXI8XDjSyRChrUnEW9rQygmJQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-darwin-x64@4.0.12':
+ resolution: {integrity: sha512-RL/9jM41Fdq4Efr35C5wgLx98BirnrfwuD+zgMFK6Ir68HeOSqBhW9jsEeC7Y/JcGyPd3MEoJVIU4fAb7YLg7A==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-freebsd-x64@4.0.12':
+ resolution: {integrity: sha512-7WzWiax+LguJcMEimY0Q4sBLlFXu1tYxVka3+G2M9KmU/3m84J3jAIV4KZWnockbHsbb2XgrEjtlJKVwHQCoRA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.12':
+ resolution: {integrity: sha512-X9LRC7jjE1QlfIaBbXjY0PGeQP87lz5mEfLSVs2J1yRc9PSg1tEPS9NBqY4BU9v5toZgJgzKeaNltORyTs22TQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.0.12':
+ resolution: {integrity: sha512-i24IFNq2402zfDdoWKypXz0ZNS2G4NKaA82tgBlE2OhHIE+4mg2JDb5wVfyP6R+MCm5grgXvurcIcKWvo44QiQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.0.12':
+ resolution: {integrity: sha512-LmOdshJBfAGIBG0DdBWhI0n5LTMurnGGJCHcsm9F//ISfsHtCnnYIKgYQui5oOz1SUCkqsMGfkAzWyNKZqbGNw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.0.12':
+ resolution: {integrity: sha512-OSK667qZRH30ep8RiHbZDQfqkXjnzKxdn0oRwWzgCO8CoTxV+MvIkd0BWdQbYtYuM1wrakARV/Hwp0eA/qzdbw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-musl@4.0.12':
+ resolution: {integrity: sha512-uylhWq6OWQ8krV8Jk+v0H/3AZKJW6xYMgNMyNnUbbYXWi7hIVdxRKNUB5UvrlC3RxtgsK5EAV2i1CWTRsNcAnA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.0.12':
+ resolution: {integrity: sha512-XDLnhMoXZEEOir1LK43/gHHwK84V1GlV8+pAncUAIN2wloeD+nNciI9WRIY/BeFTqES22DhTIGoilSO39xDb2g==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.0.12':
+ resolution: {integrity: sha512-I/BbjCLpKDQucvtn6rFuYLst1nfFwSMYyPzkx/095RE+tuzk5+fwXuzQh7T3fIBTcbn82qH/sFka7yPGA50tLw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@tailwindcss/oxide@4.0.12':
+ resolution: {integrity: sha512-DWb+myvJB9xJwelwT9GHaMc1qJj6MDXRDR0CS+T8IdkejAtu8ctJAgV4r1drQJLPeS7mNwq2UHW2GWrudTf63A==}
+ engines: {node: '>= 10'}
+
+ '@tailwindcss/vite@4.0.12':
+ resolution: {integrity: sha512-JM3gp601UJiryIZ9R2bSqalzcOy15RCybQ1Q+BJqDEwVyo4LkWKeqQAcrpHapWXY31OJFTuOUVBFDWMhzHm2Bg==}
+ peerDependencies:
+ vite: ^5.2.0 || ^6
+
+ '@types/babel__core@7.20.5':
+ resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
+
+ '@types/babel__generator@7.6.8':
+ resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==}
+
+ '@types/babel__template@7.4.4':
+ resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
+
+ '@types/babel__traverse@7.20.6':
+ resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==}
+
+ '@types/estree@1.0.6':
+ resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
+
+ '@types/node@20.17.24':
+ resolution: {integrity: sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==}
+
+ '@types/react-dom@19.0.4':
+ resolution: {integrity: sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==}
+ peerDependencies:
+ '@types/react': ^19.0.0
+
+ '@types/react@19.0.10':
+ resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==}
+
+ '@uiw/codemirror-extensions-basic-setup@4.23.10':
+ resolution: {integrity: sha512-zpbmSeNs3OU/f/Eyd6brFnjsBUYwv2mFjWxlAsIRSwTlW+skIT60rQHFBSfsj/5UVSxSLWVeUYczN7AyXvgTGQ==}
+ peerDependencies:
+ '@codemirror/autocomplete': '>=6.0.0'
+ '@codemirror/commands': '>=6.0.0'
+ '@codemirror/language': '>=6.0.0'
+ '@codemirror/lint': '>=6.0.0'
+ '@codemirror/search': '>=6.0.0'
+ '@codemirror/state': '>=6.0.0'
+ '@codemirror/view': '>=6.0.0'
+
+ '@uiw/codemirror-theme-github@4.23.10':
+ resolution: {integrity: sha512-jTg2sHAcU1d+8x0O+EBDI71rtJ8PWKIW8gzy+SW4wShQTAdsqGHk5y1ynt3KIeoaUkqngLqAK4SkhPaUKlqZqg==}
+
+ '@uiw/codemirror-themes@4.23.10':
+ resolution: {integrity: sha512-dU0UgEEgEXCAYpxuVDQ6fovE82XsqgHZckTJOH6Bs8xCi3Z7dwBKO4pXuiA8qGDwTOXOMjSzfi+pRViDm7OfWw==}
+ peerDependencies:
+ '@codemirror/language': '>=6.0.0'
+ '@codemirror/state': '>=6.0.0'
+ '@codemirror/view': '>=6.0.0'
+
+ '@uiw/react-codemirror@4.23.10':
+ resolution: {integrity: sha512-AbN4eVHOL4ckRuIXpZxkzEqL/1ChVA+BSdEnAKjIB68pLQvKsVoYbiFP8zkXkYc4+Fcgq5KbAjvYqdo4ewemKw==}
+ peerDependencies:
+ '@babel/runtime': '>=7.11.0'
+ '@codemirror/state': '>=6.0.0'
+ '@codemirror/theme-one-dark': '>=6.0.0'
+ '@codemirror/view': '>=6.0.0'
+ codemirror: '>=6.0.0'
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+
+ '@vitejs/plugin-react@4.3.4':
+ resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ vite: ^4.2.0 || ^5.0.0 || ^6.0.0
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ aria-hidden@1.2.4:
+ resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
+ engines: {node: '>=10'}
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.24.4:
+ resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ caniuse-lite@1.0.30001703:
+ resolution: {integrity: sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ class-variance-authority@0.7.1:
+ resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ codemirror@6.0.1:
+ resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==}
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ copy-to-clipboard@3.3.3:
+ resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==}
+
+ crelt@1.0.6:
+ resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
+
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ debug@4.4.0:
+ resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ detect-libc@2.0.3:
+ resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
+ engines: {node: '>=8'}
+
+ detect-node-es@1.1.0:
+ resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
+
+ electron-to-chromium@1.5.113:
+ resolution: {integrity: sha512-wjT2O4hX+wdWPJ76gWSkMhcHAV2PTMX+QetUCPYEdCIe+cxmgzzSSiGRCKW8nuh4mwKZlpv0xvoW7OF2X+wmHg==}
+
+ enhanced-resolve@5.18.1:
+ resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==}
+ engines: {node: '>=10.13.0'}
+
+ esbuild@0.25.1:
+ resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ fast-glob@3.3.3:
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
+ engines: {node: '>=8.6.0'}
+
+ fastq@1.19.1:
+ resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ fs-extra@11.3.0:
+ resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==}
+ engines: {node: '>=14.14'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ gensync@1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+
+ get-nonce@1.0.1:
+ resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
+ engines: {node: '>=6'}
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ globals@11.12.0:
+ resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+ engines: {node: '>=4'}
+
+ globals@15.15.0:
+ resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==}
+ engines: {node: '>=18'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ jiti@2.4.2:
+ resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
+ hasBin: true
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ jsesc@3.1.0:
+ resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ jsonfile@6.1.0:
+ resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+
+ lightningcss-darwin-arm64@1.29.2:
+ resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.29.2:
+ resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.29.2:
+ resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.29.2:
+ resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.29.2:
+ resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-arm64-musl@1.29.2:
+ resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-x64-gnu@1.29.2:
+ resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-linux-x64-musl@1.29.2:
+ resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-win32-arm64-msvc@1.29.2:
+ resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.29.2:
+ resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.29.2:
+ resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==}
+ engines: {node: '>= 12.0.0'}
+
+ lru-cache@5.1.1:
+ resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+
+ lucide-react@0.479.0:
+ resolution: {integrity: sha512-aBhNnveRhorBOK7uA4gDjgaf+YlHMdMhQ/3cupk6exM10hWlEU+2QtWYOfhXhjAsmdb6LeKR+NZnow4UxRRiTQ==}
+ peerDependencies:
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ nanoid@3.3.9:
+ resolution: {integrity: sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ next-themes@0.4.5:
+ resolution: {integrity: sha512-E8/gYKBxZknOXBiDk/sRokAvkOw35PTUD4Gxtq1eBhd0r4Dx5S42zU65/q8ozR5rcSG2ZlE1E3+ShlUpC7an+A==}
+ peerDependencies:
+ react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
+
+ node-releases@2.0.19:
+ resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ p-map@7.0.3:
+ resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==}
+ engines: {node: '>=18'}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ postcss@8.5.3:
+ resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ react-dom@19.0.0:
+ resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
+ peerDependencies:
+ react: ^19.0.0
+
+ react-refresh@0.14.2:
+ resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
+ engines: {node: '>=0.10.0'}
+
+ react-remove-scroll-bar@2.3.8:
+ resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-remove-scroll@2.6.3:
+ resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-style-singleton@2.2.3:
+ resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react@19.0.0:
+ resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
+ engines: {node: '>=0.10.0'}
+
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ regenerator-runtime@0.14.1:
+ resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+
+ reusify@1.1.0:
+ resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rollup@4.35.0:
+ resolution: {integrity: sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ scheduler@0.25.0:
+ resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
+
+ semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+
+ sonner@2.0.1:
+ resolution: {integrity: sha512-FRBphaehZ5tLdLcQ8g2WOIRE+Y7BCfWi5Zyd8bCvBjiW8TxxAyoWZIxS661Yz6TGPqFQ4VLzOF89WEYhfynSFQ==}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ style-mod@4.1.2:
+ resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
+
+ tailwind-merge@3.0.2:
+ resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==}
+
+ tailwindcss-animate@1.0.7:
+ resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || insiders'
+
+ tailwindcss@4.0.12:
+ resolution: {integrity: sha512-bT0hJo91FtncsAMSsMzUkoo/iEU0Xs5xgFgVC9XmdM9bw5MhZuQFjPNl6wxAE0SiQF/YTZJa+PndGWYSDtuxAg==}
+
+ tapable@2.2.1:
+ resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
+ engines: {node: '>=6'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ toggle-selection@1.0.6:
+ resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ typescript@5.7.3:
+ resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ undici-types@6.19.8:
+ resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
+
+ universalify@2.0.1:
+ resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
+ engines: {node: '>= 10.0.0'}
+
+ update-browserslist-db@1.1.3:
+ resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ use-callback-ref@1.3.3:
+ resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-sidecar@1.1.3:
+ resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ vite-plugin-static-copy@2.3.0:
+ resolution: {integrity: sha512-LLKwhhHetGaCnWz4mas4qqjjguDka6/6b4+SeIohRroj8aCE7QTfiZECfPecslFQkWZ3HdQuq5kOPmWZjNYlKA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ peerDependencies:
+ vite: ^5.0.0 || ^6.0.0
+
+ vite@6.2.1:
+ resolution: {integrity: sha512-n2GnqDb6XPhlt9B8olZPrgMD/es/Nd1RdChF6CBD/fHW6pUyUTt2sQW2fPRX5GiD9XEa6+8A6A4f2vT6pSsE7Q==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ jiti: '>=1.21.0'
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ w3c-keyname@2.2.8:
+ resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
+
+ yallist@3.1.1:
+ resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+
+snapshots:
+
+ '@ampproject/remapping@2.3.0':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.8
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@babel/code-frame@7.26.2':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.25.9
+ js-tokens: 4.0.0
+ picocolors: 1.1.1
+
+ '@babel/compat-data@7.26.8': {}
+
+ '@babel/core@7.26.9':
+ dependencies:
+ '@ampproject/remapping': 2.3.0
+ '@babel/code-frame': 7.26.2
+ '@babel/generator': 7.26.9
+ '@babel/helper-compilation-targets': 7.26.5
+ '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.9)
+ '@babel/helpers': 7.26.9
+ '@babel/parser': 7.26.9
+ '@babel/template': 7.26.9
+ '@babel/traverse': 7.26.9
+ '@babel/types': 7.26.9
+ convert-source-map: 2.0.0
+ debug: 4.4.0
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/generator@7.26.9':
+ dependencies:
+ '@babel/parser': 7.26.9
+ '@babel/types': 7.26.9
+ '@jridgewell/gen-mapping': 0.3.8
+ '@jridgewell/trace-mapping': 0.3.25
+ jsesc: 3.1.0
+
+ '@babel/helper-compilation-targets@7.26.5':
+ dependencies:
+ '@babel/compat-data': 7.26.8
+ '@babel/helper-validator-option': 7.25.9
+ browserslist: 4.24.4
+ lru-cache: 5.1.1
+ semver: 6.3.1
+
+ '@babel/helper-module-imports@7.25.9':
+ dependencies:
+ '@babel/traverse': 7.26.9
+ '@babel/types': 7.26.9
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.9)':
+ dependencies:
+ '@babel/core': 7.26.9
+ '@babel/helper-module-imports': 7.25.9
+ '@babel/helper-validator-identifier': 7.25.9
+ '@babel/traverse': 7.26.9
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-plugin-utils@7.26.5': {}
+
+ '@babel/helper-string-parser@7.25.9': {}
+
+ '@babel/helper-validator-identifier@7.25.9': {}
+
+ '@babel/helper-validator-option@7.25.9': {}
+
+ '@babel/helpers@7.26.9':
+ dependencies:
+ '@babel/template': 7.26.9
+ '@babel/types': 7.26.9
+
+ '@babel/parser@7.26.9':
+ dependencies:
+ '@babel/types': 7.26.9
+
+ '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.9)':
+ dependencies:
+ '@babel/core': 7.26.9
+ '@babel/helper-plugin-utils': 7.26.5
+
+ '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.9)':
+ dependencies:
+ '@babel/core': 7.26.9
+ '@babel/helper-plugin-utils': 7.26.5
+
+ '@babel/runtime@7.26.9':
+ dependencies:
+ regenerator-runtime: 0.14.1
+
+ '@babel/template@7.26.9':
+ dependencies:
+ '@babel/code-frame': 7.26.2
+ '@babel/parser': 7.26.9
+ '@babel/types': 7.26.9
+
+ '@babel/traverse@7.26.9':
+ dependencies:
+ '@babel/code-frame': 7.26.2
+ '@babel/generator': 7.26.9
+ '@babel/parser': 7.26.9
+ '@babel/template': 7.26.9
+ '@babel/types': 7.26.9
+ debug: 4.4.0
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/types@7.26.9':
+ dependencies:
+ '@babel/helper-string-parser': 7.25.9
+ '@babel/helper-validator-identifier': 7.25.9
+
+ '@codemirror/autocomplete@6.18.6':
+ dependencies:
+ '@codemirror/language': 6.10.8
+ '@codemirror/state': 6.5.2
+ '@codemirror/view': 6.29.0
+ '@lezer/common': 1.2.3
+
+ '@codemirror/commands@6.8.0':
+ dependencies:
+ '@codemirror/language': 6.10.8
+ '@codemirror/state': 6.5.2
+ '@codemirror/view': 6.29.0
+ '@lezer/common': 1.2.3
+
+ '@codemirror/lang-json@6.0.1':
+ dependencies:
+ '@codemirror/language': 6.10.8
+ '@lezer/json': 1.0.3
+
+ '@codemirror/lang-yaml@6.1.2':
+ dependencies:
+ '@codemirror/autocomplete': 6.18.6
+ '@codemirror/language': 6.10.8
+ '@codemirror/state': 6.5.2
+ '@lezer/common': 1.2.3
+ '@lezer/highlight': 1.2.1
+ '@lezer/lr': 1.4.2
+ '@lezer/yaml': 1.0.3
+
+ '@codemirror/language@6.10.8':
+ dependencies:
+ '@codemirror/state': 6.5.2
+ '@codemirror/view': 6.29.0
+ '@lezer/common': 1.2.3
+ '@lezer/highlight': 1.2.1
+ '@lezer/lr': 1.4.2
+ style-mod: 4.1.2
+
+ '@codemirror/legacy-modes@6.4.0':
+ dependencies:
+ '@codemirror/language': 6.10.8
+
+ '@codemirror/lint@6.8.4':
+ dependencies:
+ '@codemirror/state': 6.5.2
+ '@codemirror/view': 6.36.4
+ crelt: 1.0.6
+
+ '@codemirror/search@6.5.10':
+ dependencies:
+ '@codemirror/state': 6.5.2
+ '@codemirror/view': 6.29.0
+ crelt: 1.0.6
+
+ '@codemirror/state@6.5.2':
+ dependencies:
+ '@marijn/find-cluster-break': 1.0.2
+
+ '@codemirror/theme-one-dark@6.1.2':
+ dependencies:
+ '@codemirror/language': 6.10.8
+ '@codemirror/state': 6.5.2
+ '@codemirror/view': 6.29.0
+ '@lezer/highlight': 1.2.1
+
+ '@codemirror/view@6.29.0':
+ dependencies:
+ '@codemirror/state': 6.5.2
+ style-mod: 4.1.2
+ w3c-keyname: 2.2.8
+
+ '@codemirror/view@6.36.4':
+ dependencies:
+ '@codemirror/state': 6.5.2
+ style-mod: 4.1.2
+ w3c-keyname: 2.2.8
+
+ '@esbuild/aix-ppc64@0.25.1':
+ optional: true
+
+ '@esbuild/android-arm64@0.25.1':
+ optional: true
+
+ '@esbuild/android-arm@0.25.1':
+ optional: true
+
+ '@esbuild/android-x64@0.25.1':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.25.1':
+ optional: true
+
+ '@esbuild/darwin-x64@0.25.1':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.25.1':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.25.1':
+ optional: true
+
+ '@esbuild/linux-arm64@0.25.1':
+ optional: true
+
+ '@esbuild/linux-arm@0.25.1':
+ optional: true
+
+ '@esbuild/linux-ia32@0.25.1':
+ optional: true
+
+ '@esbuild/linux-loong64@0.25.1':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.25.1':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.25.1':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.25.1':
+ optional: true
+
+ '@esbuild/linux-s390x@0.25.1':
+ optional: true
+
+ '@esbuild/linux-x64@0.25.1':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.25.1':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.25.1':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.25.1':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.25.1':
+ optional: true
+
+ '@esbuild/sunos-x64@0.25.1':
+ optional: true
+
+ '@esbuild/win32-arm64@0.25.1':
+ optional: true
+
+ '@esbuild/win32-ia32@0.25.1':
+ optional: true
+
+ '@esbuild/win32-x64@0.25.1':
+ optional: true
+
+ '@floating-ui/core@1.6.9':
+ dependencies:
+ '@floating-ui/utils': 0.2.9
+
+ '@floating-ui/dom@1.6.13':
+ dependencies:
+ '@floating-ui/core': 1.6.9
+ '@floating-ui/utils': 0.2.9
+
+ '@floating-ui/react-dom@2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@floating-ui/dom': 1.6.13
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+
+ '@floating-ui/utils@0.2.9': {}
+
+ '@jridgewell/gen-mapping@0.3.8':
+ dependencies:
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/set-array@1.2.1': {}
+
+ '@jridgewell/sourcemap-codec@1.5.0': {}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ '@lezer/common@1.2.3': {}
+
+ '@lezer/highlight@1.2.1':
+ dependencies:
+ '@lezer/common': 1.2.3
+
+ '@lezer/json@1.0.3':
+ dependencies:
+ '@lezer/common': 1.2.3
+ '@lezer/highlight': 1.2.1
+ '@lezer/lr': 1.4.2
+
+ '@lezer/lr@1.4.2':
+ dependencies:
+ '@lezer/common': 1.2.3
+
+ '@lezer/yaml@1.0.3':
+ dependencies:
+ '@lezer/common': 1.2.3
+ '@lezer/highlight': 1.2.1
+ '@lezer/lr': 1.4.2
+
+ '@marijn/find-cluster-break@1.0.2': {}
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.19.1
+
+ '@radix-ui/primitive@1.1.1': {}
+
+ '@radix-ui/react-arrow@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-collection@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-compose-refs@1.1.1(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-context@1.1.1(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-dialog@1.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ aria-hidden: 1.2.4
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ react-remove-scroll: 2.6.3(@types/react@19.0.10)(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-direction@1.1.0(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-menu': 2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-focus-guards@1.1.1(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-id@1.1.0(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-menu@2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ aria-hidden: 1.2.4
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ react-remove-scroll: 2.6.3(@types/react@19.0.10)(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-popper@1.2.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@floating-ui/react-dom': 2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-arrow': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-use-rect': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-use-size': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/rect': 1.1.0
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-portal@1.1.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-presence@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-primitive@2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-roving-focus@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+ '@types/react-dom': 19.0.4(@types/react@19.0.10)
+
+ '@radix-ui/react-slot@1.1.2(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-use-controllable-state@1.1.0(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-use-rect@1.1.0(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/rect': 1.1.0
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/react-use-size@1.1.0(@types/react@19.0.10)(react@19.0.0)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0)
+ react: 19.0.0
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ '@radix-ui/rect@1.1.0': {}
+
+ '@rollup/rollup-android-arm-eabi@4.35.0':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.35.0':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.35.0':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.35.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.35.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.35.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.35.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.35.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.35.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.35.0':
+ optional: true
+
+ '@rollup/rollup-linux-loongarch64-gnu@4.35.0':
+ optional: true
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.35.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.35.0':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.35.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.35.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.35.0':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.35.0':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.35.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.35.0':
+ optional: true
+
+ '@tailwindcss/node@4.0.12':
+ dependencies:
+ enhanced-resolve: 5.18.1
+ jiti: 2.4.2
+ tailwindcss: 4.0.12
+
+ '@tailwindcss/oxide-android-arm64@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-arm64@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-x64@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide-freebsd-x64@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-musl@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.0.12':
+ optional: true
+
+ '@tailwindcss/oxide@4.0.12':
+ optionalDependencies:
+ '@tailwindcss/oxide-android-arm64': 4.0.12
+ '@tailwindcss/oxide-darwin-arm64': 4.0.12
+ '@tailwindcss/oxide-darwin-x64': 4.0.12
+ '@tailwindcss/oxide-freebsd-x64': 4.0.12
+ '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.12
+ '@tailwindcss/oxide-linux-arm64-gnu': 4.0.12
+ '@tailwindcss/oxide-linux-arm64-musl': 4.0.12
+ '@tailwindcss/oxide-linux-x64-gnu': 4.0.12
+ '@tailwindcss/oxide-linux-x64-musl': 4.0.12
+ '@tailwindcss/oxide-win32-arm64-msvc': 4.0.12
+ '@tailwindcss/oxide-win32-x64-msvc': 4.0.12
+
+ '@tailwindcss/vite@4.0.12(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2))':
+ dependencies:
+ '@tailwindcss/node': 4.0.12
+ '@tailwindcss/oxide': 4.0.12
+ lightningcss: 1.29.2
+ tailwindcss: 4.0.12
+ vite: 6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)
+
+ '@types/babel__core@7.20.5':
+ dependencies:
+ '@babel/parser': 7.26.9
+ '@babel/types': 7.26.9
+ '@types/babel__generator': 7.6.8
+ '@types/babel__template': 7.4.4
+ '@types/babel__traverse': 7.20.6
+
+ '@types/babel__generator@7.6.8':
+ dependencies:
+ '@babel/types': 7.26.9
+
+ '@types/babel__template@7.4.4':
+ dependencies:
+ '@babel/parser': 7.26.9
+ '@babel/types': 7.26.9
+
+ '@types/babel__traverse@7.20.6':
+ dependencies:
+ '@babel/types': 7.26.9
+
+ '@types/estree@1.0.6': {}
+
+ '@types/node@20.17.24':
+ dependencies:
+ undici-types: 6.19.8
+
+ '@types/react-dom@19.0.4(@types/react@19.0.10)':
+ dependencies:
+ '@types/react': 19.0.10
+
+ '@types/react@19.0.10':
+ dependencies:
+ csstype: 3.1.3
+
+ '@uiw/codemirror-extensions-basic-setup@4.23.10(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)':
+ dependencies:
+ '@codemirror/autocomplete': 6.18.6
+ '@codemirror/commands': 6.8.0
+ '@codemirror/language': 6.10.8
+ '@codemirror/lint': 6.8.4
+ '@codemirror/search': 6.5.10
+ '@codemirror/state': 6.5.2
+ '@codemirror/view': 6.29.0
+
+ '@uiw/codemirror-theme-github@4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)':
+ dependencies:
+ '@uiw/codemirror-themes': 4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)
+ transitivePeerDependencies:
+ - '@codemirror/language'
+ - '@codemirror/state'
+ - '@codemirror/view'
+
+ '@uiw/codemirror-themes@4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)':
+ dependencies:
+ '@codemirror/language': 6.10.8
+ '@codemirror/state': 6.5.2
+ '@codemirror/view': 6.29.0
+
+ '@uiw/react-codemirror@4.23.10(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.29.0)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@babel/runtime': 7.26.9
+ '@codemirror/commands': 6.8.0
+ '@codemirror/state': 6.5.2
+ '@codemirror/theme-one-dark': 6.1.2
+ '@codemirror/view': 6.29.0
+ '@uiw/codemirror-extensions-basic-setup': 4.23.10(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)
+ codemirror: 6.0.1
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ transitivePeerDependencies:
+ - '@codemirror/autocomplete'
+ - '@codemirror/language'
+ - '@codemirror/lint'
+ - '@codemirror/search'
+
+ '@vitejs/plugin-react@4.3.4(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2))':
+ dependencies:
+ '@babel/core': 7.26.9
+ '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.9)
+ '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.9)
+ '@types/babel__core': 7.20.5
+ react-refresh: 0.14.2
+ vite: 6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)
+ transitivePeerDependencies:
+ - supports-color
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ aria-hidden@1.2.4:
+ dependencies:
+ tslib: 2.8.1
+
+ binary-extensions@2.3.0: {}
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browserslist@4.24.4:
+ dependencies:
+ caniuse-lite: 1.0.30001703
+ electron-to-chromium: 1.5.113
+ node-releases: 2.0.19
+ update-browserslist-db: 1.1.3(browserslist@4.24.4)
+
+ caniuse-lite@1.0.30001703: {}
+
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ class-variance-authority@0.7.1:
+ dependencies:
+ clsx: 2.1.1
+
+ clsx@2.1.1: {}
+
+ codemirror@6.0.1:
+ dependencies:
+ '@codemirror/autocomplete': 6.18.6
+ '@codemirror/commands': 6.8.0
+ '@codemirror/language': 6.10.8
+ '@codemirror/lint': 6.8.4
+ '@codemirror/search': 6.5.10
+ '@codemirror/state': 6.5.2
+ '@codemirror/view': 6.29.0
+
+ convert-source-map@2.0.0: {}
+
+ copy-to-clipboard@3.3.3:
+ dependencies:
+ toggle-selection: 1.0.6
+
+ crelt@1.0.6: {}
+
+ csstype@3.1.3: {}
+
+ debug@4.4.0:
+ dependencies:
+ ms: 2.1.3
+
+ detect-libc@2.0.3: {}
+
+ detect-node-es@1.1.0: {}
+
+ electron-to-chromium@1.5.113: {}
+
+ enhanced-resolve@5.18.1:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.2.1
+
+ esbuild@0.25.1:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.25.1
+ '@esbuild/android-arm': 0.25.1
+ '@esbuild/android-arm64': 0.25.1
+ '@esbuild/android-x64': 0.25.1
+ '@esbuild/darwin-arm64': 0.25.1
+ '@esbuild/darwin-x64': 0.25.1
+ '@esbuild/freebsd-arm64': 0.25.1
+ '@esbuild/freebsd-x64': 0.25.1
+ '@esbuild/linux-arm': 0.25.1
+ '@esbuild/linux-arm64': 0.25.1
+ '@esbuild/linux-ia32': 0.25.1
+ '@esbuild/linux-loong64': 0.25.1
+ '@esbuild/linux-mips64el': 0.25.1
+ '@esbuild/linux-ppc64': 0.25.1
+ '@esbuild/linux-riscv64': 0.25.1
+ '@esbuild/linux-s390x': 0.25.1
+ '@esbuild/linux-x64': 0.25.1
+ '@esbuild/netbsd-arm64': 0.25.1
+ '@esbuild/netbsd-x64': 0.25.1
+ '@esbuild/openbsd-arm64': 0.25.1
+ '@esbuild/openbsd-x64': 0.25.1
+ '@esbuild/sunos-x64': 0.25.1
+ '@esbuild/win32-arm64': 0.25.1
+ '@esbuild/win32-ia32': 0.25.1
+ '@esbuild/win32-x64': 0.25.1
+
+ escalade@3.2.0: {}
+
+ fast-glob@3.3.3:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fastq@1.19.1:
+ dependencies:
+ reusify: 1.1.0
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ fs-extra@11.3.0:
+ dependencies:
+ graceful-fs: 4.2.11
+ jsonfile: 6.1.0
+ universalify: 2.0.1
+
+ fsevents@2.3.3:
+ optional: true
+
+ gensync@1.0.0-beta.2: {}
+
+ get-nonce@1.0.1: {}
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ globals@11.12.0: {}
+
+ globals@15.15.0: {}
+
+ graceful-fs@4.2.11: {}
+
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
+ is-extglob@2.1.1: {}
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-number@7.0.0: {}
+
+ jiti@2.4.2: {}
+
+ js-tokens@4.0.0: {}
+
+ jsesc@3.1.0: {}
+
+ json5@2.2.3: {}
+
+ jsonfile@6.1.0:
+ dependencies:
+ universalify: 2.0.1
+ optionalDependencies:
+ graceful-fs: 4.2.11
+
+ lightningcss-darwin-arm64@1.29.2:
+ optional: true
+
+ lightningcss-darwin-x64@1.29.2:
+ optional: true
+
+ lightningcss-freebsd-x64@1.29.2:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.29.2:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.29.2:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.29.2:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.29.2:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.29.2:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.29.2:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.29.2:
+ optional: true
+
+ lightningcss@1.29.2:
+ dependencies:
+ detect-libc: 2.0.3
+ optionalDependencies:
+ lightningcss-darwin-arm64: 1.29.2
+ lightningcss-darwin-x64: 1.29.2
+ lightningcss-freebsd-x64: 1.29.2
+ lightningcss-linux-arm-gnueabihf: 1.29.2
+ lightningcss-linux-arm64-gnu: 1.29.2
+ lightningcss-linux-arm64-musl: 1.29.2
+ lightningcss-linux-x64-gnu: 1.29.2
+ lightningcss-linux-x64-musl: 1.29.2
+ lightningcss-win32-arm64-msvc: 1.29.2
+ lightningcss-win32-x64-msvc: 1.29.2
+
+ lru-cache@5.1.1:
+ dependencies:
+ yallist: 3.1.1
+
+ lucide-react@0.479.0(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+
+ merge2@1.4.1: {}
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
+ ms@2.1.3: {}
+
+ nanoid@3.3.9: {}
+
+ next-themes@0.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+
+ node-releases@2.0.19: {}
+
+ normalize-path@3.0.0: {}
+
+ p-map@7.0.3: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.1: {}
+
+ postcss@8.5.3:
+ dependencies:
+ nanoid: 3.3.9
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ queue-microtask@1.2.3: {}
+
+ react-dom@19.0.0(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+ scheduler: 0.25.0
+
+ react-refresh@0.14.2: {}
+
+ react-remove-scroll-bar@2.3.8(@types/react@19.0.10)(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+ react-style-singleton: 2.2.3(@types/react@19.0.10)(react@19.0.0)
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ react-remove-scroll@2.6.3(@types/react@19.0.10)(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+ react-remove-scroll-bar: 2.3.8(@types/react@19.0.10)(react@19.0.0)
+ react-style-singleton: 2.2.3(@types/react@19.0.10)(react@19.0.0)
+ tslib: 2.8.1
+ use-callback-ref: 1.3.3(@types/react@19.0.10)(react@19.0.0)
+ use-sidecar: 1.1.3(@types/react@19.0.10)(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ react-style-singleton@2.2.3(@types/react@19.0.10)(react@19.0.0):
+ dependencies:
+ get-nonce: 1.0.1
+ react: 19.0.0
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ react@19.0.0: {}
+
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.1
+
+ regenerator-runtime@0.14.1: {}
+
+ reusify@1.1.0: {}
+
+ rollup@4.35.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.35.0
+ '@rollup/rollup-android-arm64': 4.35.0
+ '@rollup/rollup-darwin-arm64': 4.35.0
+ '@rollup/rollup-darwin-x64': 4.35.0
+ '@rollup/rollup-freebsd-arm64': 4.35.0
+ '@rollup/rollup-freebsd-x64': 4.35.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.35.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.35.0
+ '@rollup/rollup-linux-arm64-gnu': 4.35.0
+ '@rollup/rollup-linux-arm64-musl': 4.35.0
+ '@rollup/rollup-linux-loongarch64-gnu': 4.35.0
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.35.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.35.0
+ '@rollup/rollup-linux-s390x-gnu': 4.35.0
+ '@rollup/rollup-linux-x64-gnu': 4.35.0
+ '@rollup/rollup-linux-x64-musl': 4.35.0
+ '@rollup/rollup-win32-arm64-msvc': 4.35.0
+ '@rollup/rollup-win32-ia32-msvc': 4.35.0
+ '@rollup/rollup-win32-x64-msvc': 4.35.0
+ fsevents: 2.3.3
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ scheduler@0.25.0: {}
+
+ semver@6.3.1: {}
+
+ sonner@2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+
+ source-map-js@1.2.1: {}
+
+ style-mod@4.1.2: {}
+
+ tailwind-merge@3.0.2: {}
+
+ tailwindcss-animate@1.0.7(tailwindcss@4.0.12):
+ dependencies:
+ tailwindcss: 4.0.12
+
+ tailwindcss@4.0.12: {}
+
+ tapable@2.2.1: {}
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ toggle-selection@1.0.6: {}
+
+ tslib@2.8.1: {}
+
+ typescript@5.7.3: {}
+
+ undici-types@6.19.8: {}
+
+ universalify@2.0.1: {}
+
+ update-browserslist-db@1.1.3(browserslist@4.24.4):
+ dependencies:
+ browserslist: 4.24.4
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
+ use-callback-ref@1.3.3(@types/react@19.0.10)(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ use-sidecar@1.1.3(@types/react@19.0.10)(react@19.0.0):
+ dependencies:
+ detect-node-es: 1.1.0
+ react: 19.0.0
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 19.0.10
+
+ vite-plugin-static-copy@2.3.0(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)):
+ dependencies:
+ chokidar: 3.6.0
+ fast-glob: 3.3.3
+ fs-extra: 11.3.0
+ p-map: 7.0.3
+ picocolors: 1.1.1
+ vite: 6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)
+
+ vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2):
+ dependencies:
+ esbuild: 0.25.1
+ postcss: 8.5.3
+ rollup: 4.35.0
+ optionalDependencies:
+ '@types/node': 20.17.24
+ fsevents: 2.3.3
+ jiti: 2.4.2
+ lightningcss: 1.29.2
+
+ w3c-keyname@2.2.8: {}
+
+ yallist@3.1.1: {}
diff --git a/app/public/vite.svg b/app/public/vite.svg
new file mode 100644
index 000000000..e7b8dfb1b
--- /dev/null
+++ b/app/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/src/App.css b/app/src/App.css
new file mode 100644
index 000000000..fbb646e0d
--- /dev/null
+++ b/app/src/App.css
@@ -0,0 +1,8 @@
+body {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
+ Arial, sans-serif;
+}
+
diff --git a/app/src/App.tsx b/app/src/App.tsx
new file mode 100644
index 000000000..af6f47cc6
--- /dev/null
+++ b/app/src/App.tsx
@@ -0,0 +1,10 @@
+import TemplateGrid from './components/TemplateGrid';
+import './App.css';
+
+function App() {
+ return (
+
+ );
+}
+
+export default App;
diff --git a/app/src/assets/react.svg b/app/src/assets/react.svg
new file mode 100644
index 000000000..6c87de9bb
--- /dev/null
+++ b/app/src/assets/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/src/components/TemplateGrid.tsx b/app/src/components/TemplateGrid.tsx
new file mode 100644
index 000000000..f7c63a46d
--- /dev/null
+++ b/app/src/components/TemplateGrid.tsx
@@ -0,0 +1,366 @@
+import React, { useEffect, useState } from 'react';
+import { Input } from './ui/input';
+import { Card, CardHeader, CardTitle, CardContent, CardFooter } from './ui/card';
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle,
+} from './ui/dialog';
+import { Button } from './ui/button';
+import { toast } from 'sonner';
+import copy from 'copy-to-clipboard';
+import { ModeToggle } from '../mode-toggle';
+import { CodeEditor } from './ui/code-editor';
+interface Template {
+ id: string;
+ name: string;
+ description: string;
+ version: string;
+ logo?: string;
+ links: {
+ github?: string;
+ website?: string;
+ docs?: string;
+ };
+ tags: string[];
+}
+
+interface TemplateFiles {
+ dockerCompose: string | null;
+ config: string | null;
+}
+
+const TemplateGrid: React.FC = () => {
+ const [templates, setTemplates] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+ const [searchQuery, setSearchQuery] = useState('');
+ const [selectedTemplate, setSelectedTemplate] = useState(null);
+ const [templateFiles, setTemplateFiles] = useState(null);
+ const [modalLoading, setModalLoading] = useState(false);
+
+ useEffect(() => {
+ const fetchTemplates = async () => {
+ try {
+ const response = await fetch('/meta.json');
+ if (!response.ok) {
+ throw new Error('Failed to fetch templates');
+ }
+ const data = await response.json();
+ setTemplates(data);
+ setLoading(false);
+ } catch (err) {
+ setError(err instanceof Error ? err.message : 'An error occurred');
+ setLoading(false);
+ }
+ };
+
+ fetchTemplates();
+ }, []);
+
+ const fetchTemplateFiles = async (templateId: string) => {
+ setModalLoading(true);
+ try {
+ const [dockerComposeRes, configRes] = await Promise.all([
+ fetch(`/blueprints/${templateId}/docker-compose.yml`),
+ fetch(`/blueprints/${templateId}/template.yml`)
+ ]);
+
+ const dockerCompose = dockerComposeRes.ok ? await dockerComposeRes.text() : null;
+ const config = configRes.ok ? await configRes.text() : null;
+
+ setTemplateFiles({ dockerCompose, config });
+ } catch (err) {
+ console.error('Error fetching template files:', err);
+ setTemplateFiles({ dockerCompose: null, config: null });
+ } finally {
+ setModalLoading(false);
+ }
+ };
+
+ const handleTemplateClick = (template: Template) => {
+ setSelectedTemplate(template);
+ setTemplateFiles(null); // Reset previous files
+ fetchTemplateFiles(template.id);
+ };
+
+ const filteredTemplates = templates.filter((template) =>
+ template.name.toLowerCase().includes(searchQuery.toLowerCase())
+ );
+
+ const getBase64Config = () => {
+ if (!templateFiles?.dockerCompose && !templateFiles?.config) return '';
+
+ const configObj = {
+ compose: templateFiles.dockerCompose || '',
+ config: templateFiles.config || ''
+ };
+
+ return btoa(JSON.stringify(configObj, null, 2));
+ };
+
+ if (loading) {
+ return (
+
+
+ Loading templates...
+
+
+ );
+ }
+
+ if (error) {
+ return (
+
+ );
+ }
+
+ return (
+ <>
+
+
+ Available Templates ({templates.length})
+
+
+
+
+
setSearchQuery(e.target.value)}
+ className="w-full"
+ />
+
+
+
+
+
+
+
+ {filteredTemplates.length > 0 ? (
+ filteredTemplates.map((template) => (
+
handleTemplateClick(template)}
+ >
+
+
+
+ {template.name}
+
+
+ {template.description}
+
+ {template.tags.slice(0, 3).map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+
+ v{template.version}
+
+
+
+
+
+ ))
+ ) : (
+
+
+ No templates found matching "{searchQuery}"
+
+
+ )}
+
+
+
+ setSelectedTemplate(null)}>
+
+
+
+ {selectedTemplate?.logo && (
+
+ )}
+
+
{selectedTemplate?.name}
+
+
{selectedTemplate?.version}
+
+
+
+
+
+ {selectedTemplate?.description}
+
+
+ {selectedTemplate?.tags.map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+
+ {modalLoading ? (
+
+
+
Loading template files...
+
+ ) : (
+
+ {templateFiles?.dockerCompose && (
+
+
+ Docker Compose
+ docker-compose.yml
+
+
+ {
+ toast.success('Copied to clipboard')
+ copy(templateFiles.dockerCompose || '')
+ }}
+ className="absolute top-10 right-2 px-3 py-1 text-sm cursor-pointer"
+ >
+ Copy
+
+
+ )}
+ {templateFiles?.config && (
+
+
+ Configuration
+ template.yml
+
+
+
+ {
+ toast.success('Copied to clipboard')
+ copy(templateFiles.config || '')
+ }}
+ className="absolute top-10 right-2 px-3 py-1 text-sm cursor-pointer"
+ >
+ Copy
+
+
+ )}
+ {(templateFiles?.dockerCompose || templateFiles?.config) && (
+
+
+ Base64 Configuration
+ Encoded template files
+
+
+
+ {
+ toast.success('Copied to clipboard')
+ copy(getBase64Config())
+ }}
+ className="absolute top-2 right-2 px-3 py-1 text-sm cursor-pointer"
+ >
+ Copy
+
+
+
+ )}
+ {!templateFiles?.dockerCompose && !templateFiles?.config && (
+
+
No configuration files available for this template.
+
+ )}
+
+ )}
+
+
+ >
+ );
+};
+
+export default TemplateGrid;
\ No newline at end of file
diff --git a/app/src/components/ui/button.tsx b/app/src/components/ui/button.tsx
new file mode 100644
index 000000000..cd0857a00
--- /dev/null
+++ b/app/src/components/ui/button.tsx
@@ -0,0 +1,58 @@
+import * as React from "react"
+import { Slot } from "@radix-ui/react-slot"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "@/lib/utils"
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ {
+ variants: {
+ variant: {
+ default:
+ "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
+ destructive:
+ "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
+ outline:
+ "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
+ secondary:
+ "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
+ ghost: "hover:bg-accent hover:text-accent-foreground",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
+ icon: "size-9",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+function Button({
+ className,
+ variant,
+ size,
+ asChild = false,
+ ...props
+}: React.ComponentProps<"button"> &
+ VariantProps & {
+ asChild?: boolean
+ }) {
+ const Comp = asChild ? Slot : "button"
+
+ return (
+
+ )
+}
+
+export { Button, buttonVariants }
diff --git a/app/src/components/ui/card.tsx b/app/src/components/ui/card.tsx
new file mode 100644
index 000000000..5e960a688
--- /dev/null
+++ b/app/src/components/ui/card.tsx
@@ -0,0 +1,68 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Card({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardContent({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
diff --git a/app/src/components/ui/code-editor.tsx b/app/src/components/ui/code-editor.tsx
new file mode 100644
index 000000000..68ced1811
--- /dev/null
+++ b/app/src/components/ui/code-editor.tsx
@@ -0,0 +1,176 @@
+import { cn } from "@/lib/utils";
+import { json } from "@codemirror/lang-json";
+import { yaml } from "@codemirror/lang-yaml";
+import { StreamLanguage } from "@codemirror/language";
+
+import { properties } from "@codemirror/legacy-modes/mode/properties";
+import { shell } from "@codemirror/legacy-modes/mode/shell";
+import { EditorView } from "@codemirror/view";
+import { githubDark, githubLight } from "@uiw/codemirror-theme-github";
+import CodeMirror, { type ReactCodeMirrorProps } from "@uiw/react-codemirror";
+import {
+ autocompletion,
+ type CompletionContext,
+ type CompletionResult,
+ type Completion,
+} from "@codemirror/autocomplete";
+import { useTheme } from "@/theme-provider";
+// Docker Compose completion options
+const dockerComposeServices = [
+ { label: "services", type: "keyword", info: "Define services" },
+ { label: "version", type: "keyword", info: "Specify compose file version" },
+ { label: "volumes", type: "keyword", info: "Define volumes" },
+ { label: "networks", type: "keyword", info: "Define networks" },
+ { label: "configs", type: "keyword", info: "Define configuration files" },
+ { label: "secrets", type: "keyword", info: "Define secrets" },
+].map((opt) => ({
+ ...opt,
+ apply: (view: EditorView, completion: Completion) => {
+ const insert = `${completion.label}:`;
+ view.dispatch({
+ changes: {
+ from: view.state.selection.main.from,
+ to: view.state.selection.main.to,
+ insert,
+ },
+ selection: { anchor: view.state.selection.main.from + insert.length },
+ });
+ },
+}));
+
+const dockerComposeServiceOptions = [
+ {
+ label: "image",
+ type: "keyword",
+ info: "Specify the image to start the container from",
+ },
+ { label: "build", type: "keyword", info: "Build configuration" },
+ { label: "command", type: "keyword", info: "Override the default command" },
+ { label: "container_name", type: "keyword", info: "Custom container name" },
+ {
+ label: "depends_on",
+ type: "keyword",
+ info: "Express dependency between services",
+ },
+ { label: "environment", type: "keyword", info: "Add environment variables" },
+ {
+ label: "env_file",
+ type: "keyword",
+ info: "Add environment variables from a file",
+ },
+ {
+ label: "expose",
+ type: "keyword",
+ info: "Expose ports without publishing them",
+ },
+ { label: "ports", type: "keyword", info: "Expose ports" },
+ {
+ label: "volumes",
+ type: "keyword",
+ info: "Mount host paths or named volumes",
+ },
+ { label: "restart", type: "keyword", info: "Restart policy" },
+ { label: "networks", type: "keyword", info: "Networks to join" },
+].map((opt) => ({
+ ...opt,
+ apply: (view: EditorView, completion: Completion) => {
+ const insert = `${completion.label}: `;
+ view.dispatch({
+ changes: {
+ from: view.state.selection.main.from,
+ to: view.state.selection.main.to,
+ insert,
+ },
+ selection: { anchor: view.state.selection.main.from + insert.length },
+ });
+ },
+}));
+
+function dockerComposeComplete(
+ context: CompletionContext,
+): CompletionResult | null {
+ const word = context.matchBefore(/\w*/);
+ if (!word) return null;
+
+ if (!word.text && !context.explicit) return null;
+
+ // Check if we're at the root level
+ const line = context.state.doc.lineAt(context.pos);
+ const indentation = /^\s*/.exec(line.text)?.[0].length || 0;
+
+ if (indentation === 0) {
+ return {
+ from: word.from,
+ options: dockerComposeServices,
+ validFor: /^\w*$/,
+ };
+ }
+
+ // If we're inside a service definition
+ if (indentation === 4) {
+ return {
+ from: word.from,
+ options: dockerComposeServiceOptions,
+ validFor: /^\w*$/,
+ };
+ }
+
+ return null;
+}
+
+interface Props extends ReactCodeMirrorProps {
+ wrapperClassName?: string;
+ disabled?: boolean;
+ language?: "yaml" | "json" | "properties" | "shell";
+ lineWrapping?: boolean;
+ lineNumbers?: boolean;
+}
+
+export const CodeEditor = ({
+ className,
+ wrapperClassName,
+ language = "yaml",
+ lineNumbers = true,
+ ...props
+}: Props) => {
+ const { theme } = useTheme();
+ return (
+
+
+ {props.disabled && (
+
+ )}
+
+ );
+};
diff --git a/app/src/components/ui/dialog.tsx b/app/src/components/ui/dialog.tsx
new file mode 100644
index 000000000..1b608b21e
--- /dev/null
+++ b/app/src/components/ui/dialog.tsx
@@ -0,0 +1,133 @@
+import * as React from "react"
+import * as DialogPrimitive from "@radix-ui/react-dialog"
+import { XIcon } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+function Dialog({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogTrigger({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogPortal({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogClose({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DialogOverlay({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DialogContent({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ {children}
+
+
+ Close
+
+
+
+ )
+}
+
+function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function DialogTitle({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DialogDescription({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogOverlay,
+ DialogPortal,
+ DialogTitle,
+ DialogTrigger,
+}
diff --git a/app/src/components/ui/dropdown-menu.tsx b/app/src/components/ui/dropdown-menu.tsx
new file mode 100644
index 000000000..12d7c4587
--- /dev/null
+++ b/app/src/components/ui/dropdown-menu.tsx
@@ -0,0 +1,255 @@
+import * as React from "react"
+import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
+import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+function DropdownMenu({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DropdownMenuPortal({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DropdownMenuTrigger({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DropdownMenuContent({
+ className,
+ sideOffset = 4,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+ )
+}
+
+function DropdownMenuGroup({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DropdownMenuItem({
+ className,
+ inset,
+ variant = "default",
+ ...props
+}: React.ComponentProps & {
+ inset?: boolean
+ variant?: "default" | "destructive"
+}) {
+ return (
+
+ )
+}
+
+function DropdownMenuCheckboxItem({
+ className,
+ children,
+ checked,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+
+
+ {children}
+
+ )
+}
+
+function DropdownMenuRadioGroup({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DropdownMenuRadioItem({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+
+
+ {children}
+
+ )
+}
+
+function DropdownMenuLabel({
+ className,
+ inset,
+ ...props
+}: React.ComponentProps & {
+ inset?: boolean
+}) {
+ return (
+
+ )
+}
+
+function DropdownMenuSeparator({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function DropdownMenuShortcut({
+ className,
+ ...props
+}: React.ComponentProps<"span">) {
+ return (
+
+ )
+}
+
+function DropdownMenuSub({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function DropdownMenuSubTrigger({
+ className,
+ inset,
+ children,
+ ...props
+}: React.ComponentProps & {
+ inset?: boolean
+}) {
+ return (
+
+ {children}
+
+
+ )
+}
+
+function DropdownMenuSubContent({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ DropdownMenu,
+ DropdownMenuPortal,
+ DropdownMenuTrigger,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuLabel,
+ DropdownMenuItem,
+ DropdownMenuCheckboxItem,
+ DropdownMenuRadioGroup,
+ DropdownMenuRadioItem,
+ DropdownMenuSeparator,
+ DropdownMenuShortcut,
+ DropdownMenuSub,
+ DropdownMenuSubTrigger,
+ DropdownMenuSubContent,
+}
diff --git a/app/src/components/ui/input.tsx b/app/src/components/ui/input.tsx
new file mode 100644
index 000000000..4bfe9cc57
--- /dev/null
+++ b/app/src/components/ui/input.tsx
@@ -0,0 +1,21 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Input({ className, type, ...props }: React.ComponentProps<"input">) {
+ return (
+
+ )
+}
+
+export { Input }
diff --git a/app/src/components/ui/sonner.tsx b/app/src/components/ui/sonner.tsx
new file mode 100644
index 000000000..8bfe1d164
--- /dev/null
+++ b/app/src/components/ui/sonner.tsx
@@ -0,0 +1,27 @@
+import { useTheme } from "next-themes"
+import { Toaster as Sonner, ToasterProps } from "sonner"
+
+const Toaster = ({ ...props }: ToasterProps) => {
+ const { theme = "system" } = useTheme()
+
+ return (
+
+ )
+}
+
+export { Toaster }
diff --git a/app/src/index.css b/app/src/index.css
new file mode 100644
index 000000000..88df9da24
--- /dev/null
+++ b/app/src/index.css
@@ -0,0 +1,166 @@
+@import "tailwindcss";
+
+
+@plugin "tailwindcss-animate";
+
+@custom-variant dark (&:is(.dark *));
+
+#root {
+ width: 100%;
+}
+
+:root {
+ font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ --background: oklch(1 0 0);
+ --foreground: oklch(0.145 0 0);
+ --card: oklch(1 0 0);
+ --card-foreground: oklch(0.145 0 0);
+ --popover: oklch(1 0 0);
+ --popover-foreground: oklch(0.145 0 0);
+ --primary: oklch(0.205 0 0);
+ --primary-foreground: oklch(0.985 0 0);
+ --secondary: oklch(0.97 0 0);
+ --secondary-foreground: oklch(0.205 0 0);
+ --muted: oklch(0.97 0 0);
+ --muted-foreground: oklch(0.556 0 0);
+ --accent: oklch(0.97 0 0);
+ --accent-foreground: oklch(0.205 0 0);
+ --destructive: oklch(0.577 0.245 27.325);
+ --destructive-foreground: oklch(0.577 0.245 27.325);
+ --border: oklch(0.922 0 0);
+ --input: oklch(0.922 0 0);
+ --ring: oklch(0.708 0 0);
+ --chart-1: oklch(0.646 0.222 41.116);
+ --chart-2: oklch(0.6 0.118 184.704);
+ --chart-3: oklch(0.398 0.07 227.392);
+ --chart-4: oklch(0.828 0.189 84.429);
+ --chart-5: oklch(0.769 0.188 70.08);
+ --radius: 0.625rem;
+ --sidebar: oklch(0.985 0 0);
+ --sidebar-foreground: oklch(0.145 0 0);
+ --sidebar-primary: oklch(0.205 0 0);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.97 0 0);
+ --sidebar-accent-foreground: oklch(0.205 0 0);
+ --sidebar-border: oklch(0.922 0 0);
+ --sidebar-ring: oklch(0.708 0 0);
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+
+
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
+
+.dark {
+ --background: oklch(0.145 0 0);
+ --foreground: oklch(0.985 0 0);
+ --card: oklch(0.145 0 0);
+ --card-foreground: oklch(0.985 0 0);
+ --popover: oklch(0.145 0 0);
+ --popover-foreground: oklch(0.985 0 0);
+ --primary: oklch(0.985 0 0);
+ --primary-foreground: oklch(0.205 0 0);
+ --secondary: oklch(0.269 0 0);
+ --secondary-foreground: oklch(0.985 0 0);
+ --muted: oklch(0.269 0 0);
+ --muted-foreground: oklch(0.708 0 0);
+ --accent: oklch(0.269 0 0);
+ --accent-foreground: oklch(0.985 0 0);
+ --destructive: oklch(0.396 0.141 25.723);
+ --destructive-foreground: oklch(0.637 0.237 25.331);
+ --border: oklch(0.269 0 0);
+ --input: oklch(0.269 0 0);
+ --ring: oklch(0.439 0 0);
+ --chart-1: oklch(0.488 0.243 264.376);
+ --chart-2: oklch(0.696 0.17 162.48);
+ --chart-3: oklch(0.769 0.188 70.08);
+ --chart-4: oklch(0.627 0.265 303.9);
+ --chart-5: oklch(0.645 0.246 16.439);
+ --sidebar: oklch(0.205 0 0);
+ --sidebar-foreground: oklch(0.985 0 0);
+ --sidebar-primary: oklch(0.488 0.243 264.376);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.269 0 0);
+ --sidebar-accent-foreground: oklch(0.985 0 0);
+ --sidebar-border: oklch(0.269 0 0);
+ --sidebar-ring: oklch(0.439 0 0);
+}
+
+@theme inline {
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --color-card: var(--card);
+ --color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
+ --color-primary: var(--primary);
+ --color-primary-foreground: var(--primary-foreground);
+ --color-secondary: var(--secondary);
+ --color-secondary-foreground: var(--secondary-foreground);
+ --color-muted: var(--muted);
+ --color-muted-foreground: var(--muted-foreground);
+ --color-accent: var(--accent);
+ --color-accent-foreground: var(--accent-foreground);
+ --color-destructive: var(--destructive);
+ --color-destructive-foreground: var(--destructive-foreground);
+ --color-border: var(--border);
+ --color-input: var(--input);
+ --color-ring: var(--ring);
+ --color-chart-1: var(--chart-1);
+ --color-chart-2: var(--chart-2);
+ --color-chart-3: var(--chart-3);
+ --color-chart-4: var(--chart-4);
+ --color-chart-5: var(--chart-5);
+ --radius-sm: calc(var(--radius) - 4px);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-lg: var(--radius);
+ --radius-xl: calc(var(--radius) + 4px);
+ --color-sidebar: var(--sidebar);
+ --color-sidebar-foreground: var(--sidebar-foreground);
+ --color-sidebar-primary: var(--sidebar-primary);
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
+ --color-sidebar-accent: var(--sidebar-accent);
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
+ --color-sidebar-border: var(--sidebar-border);
+ --color-sidebar-ring: var(--sidebar-ring);
+}
+
+@layer base {
+ * {
+ @apply border-border outline-ring/50;
+ }
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/app/src/lib/utils.ts b/app/src/lib/utils.ts
new file mode 100644
index 000000000..d084ccade
--- /dev/null
+++ b/app/src/lib/utils.ts
@@ -0,0 +1,6 @@
+import { type ClassValue, clsx } from "clsx"
+import { twMerge } from "tailwind-merge"
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs))
+}
diff --git a/app/src/main.tsx b/app/src/main.tsx
new file mode 100644
index 000000000..784f7c233
--- /dev/null
+++ b/app/src/main.tsx
@@ -0,0 +1,14 @@
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import "./index.css";
+import App from "./App.tsx";
+import { Toaster } from "./components/ui/sonner.tsx";
+import { ThemeProvider } from "./theme-provider.tsx";
+createRoot(document.getElementById("root")!).render(
+
+
+
+
+
+
+);
diff --git a/app/src/mode-toggle.tsx b/app/src/mode-toggle.tsx
new file mode 100644
index 000000000..75a78f704
--- /dev/null
+++ b/app/src/mode-toggle.tsx
@@ -0,0 +1,37 @@
+import { Moon, Sun } from "lucide-react"
+
+import { Button } from "./components/ui/button"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "./components/ui/dropdown-menu"
+import { useTheme } from "./theme-provider"
+
+export function ModeToggle() {
+ const { setTheme } = useTheme()
+
+ return (
+
+
+
+
+
+ Toggle theme
+
+
+
+ setTheme("light")}>
+ Light
+
+ setTheme("dark")}>
+ Dark
+
+ setTheme("system")}>
+ System
+
+
+
+ )
+}
diff --git a/app/src/theme-provider.tsx b/app/src/theme-provider.tsx
new file mode 100644
index 000000000..d89a82e11
--- /dev/null
+++ b/app/src/theme-provider.tsx
@@ -0,0 +1,73 @@
+import { createContext, useContext, useEffect, useState } from "react"
+
+type Theme = "dark" | "light" | "system"
+
+type ThemeProviderProps = {
+ children: React.ReactNode
+ defaultTheme?: Theme
+ storageKey?: string
+}
+
+type ThemeProviderState = {
+ theme: Theme
+ setTheme: (theme: Theme) => void
+}
+
+const initialState: ThemeProviderState = {
+ theme: "system",
+ setTheme: () => null,
+}
+
+const ThemeProviderContext = createContext(initialState)
+
+export function ThemeProvider({
+ children,
+ defaultTheme = "system",
+ storageKey = "vite-ui-theme",
+ ...props
+}: ThemeProviderProps) {
+ const [theme, setTheme] = useState(
+ () => (localStorage.getItem(storageKey) as Theme) || defaultTheme
+ )
+
+ useEffect(() => {
+ const root = window.document.documentElement
+
+ root.classList.remove("light", "dark")
+
+ if (theme === "system") {
+ const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
+ .matches
+ ? "dark"
+ : "light"
+
+ root.classList.add(systemTheme)
+ return
+ }
+
+ root.classList.add(theme)
+ }, [theme])
+
+ const value = {
+ theme,
+ setTheme: (theme: Theme) => {
+ localStorage.setItem(storageKey, theme)
+ setTheme(theme)
+ },
+ }
+
+ return (
+
+ {children}
+
+ )
+}
+
+export const useTheme = () => {
+ const context = useContext(ThemeProviderContext)
+
+ if (context === undefined)
+ throw new Error("useTheme must be used within a ThemeProvider")
+
+ return context
+}
diff --git a/app/src/vite-env.d.ts b/app/src/vite-env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/app/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/app/tsconfig.app.json b/app/tsconfig.app.json
new file mode 100644
index 000000000..9f553cd17
--- /dev/null
+++ b/app/tsconfig.app.json
@@ -0,0 +1,30 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "include": ["src"]
+}
\ No newline at end of file
diff --git a/app/tsconfig.json b/app/tsconfig.json
new file mode 100644
index 000000000..d320f313c
--- /dev/null
+++ b/app/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "files": [],
+ "references": [
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.node.json" }
+ ],
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["app/src/*"]
+ }
+ }
+}
diff --git a/app/tsconfig.node.json b/app/tsconfig.node.json
new file mode 100644
index 000000000..584284d2c
--- /dev/null
+++ b/app/tsconfig.node.json
@@ -0,0 +1,24 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "app/node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ "target": "ES2022",
+ "lib": ["ES2023"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/app/vite.config.ts b/app/vite.config.ts
new file mode 100644
index 000000000..482c17733
--- /dev/null
+++ b/app/vite.config.ts
@@ -0,0 +1,28 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import path from 'path'
+import tailwindcss from '@tailwindcss/vite'
+import { viteStaticCopy } from 'vite-plugin-static-copy'
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react(), tailwindcss(),
+ viteStaticCopy({
+ targets: [
+ {
+ src: '../blueprints/*',
+ dest: 'blueprints' // raĂz de dist (public root)
+ },
+ {
+ src: '../meta.json',
+ dest: '' // raĂz de dist
+ }
+ ]
+ })
+
+ ],
+ resolve: {
+ alias: {
+ '@': path.resolve(__dirname, './src'),
+ },
+ },
+})
diff --git a/blueprints/activepieces/activepieces.svg b/blueprints/activepieces/activepieces.svg
new file mode 100644
index 000000000..dcf0a52b7
--- /dev/null
+++ b/blueprints/activepieces/activepieces.svg
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/activepieces/docker-compose.yml b/blueprints/activepieces/docker-compose.yml
new file mode 100644
index 000000000..a5511e7fa
--- /dev/null
+++ b/blueprints/activepieces/docker-compose.yml
@@ -0,0 +1,64 @@
+version: "3.8"
+
+services:
+ activepieces:
+ image: activepieces/activepieces:0.35.0
+ restart: unless-stopped
+
+ depends_on:
+ postgres:
+ condition: service_healthy
+ redis:
+ condition: service_healthy
+ environment:
+ AP_ENGINE_EXECUTABLE_PATH: dist/packages/engine/main.js
+ AP_API_KEY: ${AP_API_KEY}
+ AP_ENCRYPTION_KEY: ${AP_ENCRYPTION_KEY}
+ AP_JWT_SECRET: ${AP_JWT_SECRET}
+ AP_ENVIRONMENT: prod
+ AP_FRONTEND_URL: https://${AP_HOST}
+ AP_WEBHOOK_TIMEOUT_SECONDS: 30
+ AP_TRIGGER_DEFAULT_POLL_INTERVAL: 5
+ AP_POSTGRES_DATABASE: activepieces
+ AP_POSTGRES_HOST: postgres
+ AP_POSTGRES_PORT: 5432
+ AP_POSTGRES_USERNAME: activepieces
+ AP_POSTGRES_PASSWORD: ${AP_POSTGRES_PASSWORD}
+ AP_EXECUTION_MODE: UNSANDBOXED
+ AP_REDIS_HOST: redis
+ AP_REDIS_PORT: 6379
+ AP_SANDBOX_RUN_TIME_SECONDS: 600
+ AP_TELEMETRY_ENABLED: "false"
+ AP_TEMPLATES_SOURCE_URL: https://cloud.activepieces.com/api/v1/flow-templates
+
+ postgres:
+ image: postgres:14
+ restart: unless-stopped
+
+ environment:
+ POSTGRES_DB: activepieces
+ POSTGRES_PASSWORD: ${AP_POSTGRES_PASSWORD}
+ POSTGRES_USER: activepieces
+ volumes:
+ - postgres_data:/var/lib/postgresql/data
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U activepieces -d activepieces"]
+ interval: 30s
+ timeout: 30s
+ retries: 3
+
+ redis:
+ image: redis:7
+ restart: unless-stopped
+
+ volumes:
+ - redis_data:/data
+ healthcheck:
+ test: ["CMD", "redis-cli", "ping"]
+ interval: 30s
+ timeout: 30s
+ retries: 3
+
+volumes:
+ postgres_data:
+ redis_data:
\ No newline at end of file
diff --git a/blueprints/activepieces/template.yml b/blueprints/activepieces/template.yml
new file mode 100644
index 000000000..c30eeafb8
--- /dev/null
+++ b/blueprints/activepieces/template.yml
@@ -0,0 +1,21 @@
+variables:
+ main_domain: ${domain}
+ api_key: ${password:32}
+ encryption_key: ${password:32}
+ jwt_secret: ${password:32}
+ postgres_password: ${password:32}
+
+config:
+ domains:
+ - serviceName: activepieces
+ port: 80
+ host: ${main_domain}
+
+ env:
+ - AP_HOST=${main_domain}
+ - AP_API_KEY=${api_key}
+ - AP_ENCRYPTION_KEY=${encryption_key}
+ - AP_JWT_SECRET=${jwt_secret}
+ - AP_POSTGRES_PASSWORD=${postgres_password}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/actualbudget/actualbudget.png b/blueprints/actualbudget/actualbudget.png
new file mode 100644
index 000000000..fd539fe0c
Binary files /dev/null and b/blueprints/actualbudget/actualbudget.png differ
diff --git a/blueprints/actualbudget/docker-compose.yml b/blueprints/actualbudget/docker-compose.yml
new file mode 100644
index 000000000..388a9f0b6
--- /dev/null
+++ b/blueprints/actualbudget/docker-compose.yml
@@ -0,0 +1,12 @@
+services:
+ actualbudget:
+ image: docker.io/actualbudget/actual-server:latest
+ environment:
+ # See all options at https://actualbudget.org/docs/config
+ - ACTUAL_PORT=5006
+ volumes:
+ - actual-data:/data
+ restart: unless-stopped
+
+volumes:
+ actual-data:
diff --git a/blueprints/actualbudget/template.yml b/blueprints/actualbudget/template.yml
new file mode 100644
index 000000000..2df55777f
--- /dev/null
+++ b/blueprints/actualbudget/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: actualbudget
+ port: 5006
+ host: ${main_domain}
+
+ env: []
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/alist/alist.svg b/blueprints/alist/alist.svg
new file mode 100644
index 000000000..37d5fdcd9
--- /dev/null
+++ b/blueprints/alist/alist.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/alist/docker-compose.yml b/blueprints/alist/docker-compose.yml
new file mode 100644
index 000000000..9ff67c943
--- /dev/null
+++ b/blueprints/alist/docker-compose.yml
@@ -0,0 +1,14 @@
+version: '3.3'
+services:
+ alist:
+ image: xhofe/alist:v3.41.0
+ volumes:
+ - alist-data:/opt/alist/data
+ environment:
+ - PUID=0
+ - PGID=0
+ - UMASK=022
+ restart: unless-stopped
+
+volumes:
+ alist-data:
\ No newline at end of file
diff --git a/blueprints/alist/template.yml b/blueprints/alist/template.yml
new file mode 100644
index 000000000..56102d2a2
--- /dev/null
+++ b/blueprints/alist/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: alist
+ port: 5244
+ host: ${main_domain}
+
+ env: []
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/answer/answer.png b/blueprints/answer/answer.png
new file mode 100644
index 000000000..3fca604d4
Binary files /dev/null and b/blueprints/answer/answer.png differ
diff --git a/blueprints/answer/docker-compose.yml b/blueprints/answer/docker-compose.yml
new file mode 100644
index 000000000..2b9fc3440
--- /dev/null
+++ b/blueprints/answer/docker-compose.yml
@@ -0,0 +1,30 @@
+services:
+ answer:
+ image: apache/answer:1.4.1
+ ports:
+ - '80'
+ restart: on-failure
+ volumes:
+ - answer-data:/data
+ depends_on:
+ db:
+ condition: service_healthy
+ db:
+ image: postgres:16
+ restart: always
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
+ interval: 5s
+ timeout: 5s
+ retries: 5
+
+ volumes:
+ - db-data:/var/lib/postgresql/data
+ environment:
+ POSTGRES_DB: answer
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: postgres
+
+volumes:
+ answer-data:
+ db-data:
diff --git a/blueprints/answer/template.yml b/blueprints/answer/template.yml
new file mode 100644
index 000000000..a7c749d97
--- /dev/null
+++ b/blueprints/answer/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+ service_hash: ${hash:32}
+
+config:
+ domains:
+ - serviceName: answer
+ port: 9080
+ host: ${main_domain}
+
+ env:
+ - ANSWER_HOST=http://${main_domain}
+ - SERVICE_HASH=${service_hash}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/appsmith/appsmith.png b/blueprints/appsmith/appsmith.png
new file mode 100644
index 000000000..02b0e15a9
Binary files /dev/null and b/blueprints/appsmith/appsmith.png differ
diff --git a/blueprints/appsmith/docker-compose.yml b/blueprints/appsmith/docker-compose.yml
new file mode 100644
index 000000000..f520ee362
--- /dev/null
+++ b/blueprints/appsmith/docker-compose.yml
@@ -0,0 +1,6 @@
+version: "3.8"
+services:
+ appsmith:
+ image: index.docker.io/appsmith/appsmith-ee:v1.29
+ volumes:
+ - ../files/stacks:/appsmith-stacks
diff --git a/blueprints/appsmith/template.yml b/blueprints/appsmith/template.yml
new file mode 100644
index 000000000..706df33be
--- /dev/null
+++ b/blueprints/appsmith/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: appsmith
+ port: 80
+ host: ${main_domain}
+
+ env: []
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/appwrite/appwrite.svg b/blueprints/appwrite/appwrite.svg
new file mode 100644
index 000000000..2034a812a
--- /dev/null
+++ b/blueprints/appwrite/appwrite.svg
@@ -0,0 +1,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/appwrite/docker-compose.yml b/blueprints/appwrite/docker-compose.yml
new file mode 100644
index 000000000..163cb3d03
--- /dev/null
+++ b/blueprints/appwrite/docker-compose.yml
@@ -0,0 +1,887 @@
+version: "3.8"
+
+x-logging: &x-logging
+ logging:
+ driver: "json-file"
+ options:
+ max-file: "5"
+ max-size: "10m"
+
+services:
+ appwrite:
+ image: appwrite/appwrite:1.6.0
+ container_name: appwrite
+ <<: *x-logging
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ labels:
+ - traefik.enable=true
+ - traefik.constraint-label-stack=appwrite
+ volumes:
+ - appwrite-uploads:/storage/uploads:rw
+ - appwrite-cache:/storage/cache:rw
+ - appwrite-config:/storage/config:rw
+ - appwrite-certificates:/storage/certificates:rw
+ - appwrite-functions:/storage/functions:rw
+ depends_on:
+ - mariadb
+ - redis
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_LOCALE
+ - _APP_CONSOLE_WHITELIST_ROOT
+ - _APP_CONSOLE_WHITELIST_EMAILS
+ - _APP_CONSOLE_SESSION_ALERTS
+ - _APP_CONSOLE_WHITELIST_IPS
+ - _APP_CONSOLE_HOSTNAMES
+ - _APP_SYSTEM_EMAIL_NAME
+ - _APP_SYSTEM_EMAIL_ADDRESS
+ - _APP_EMAIL_SECURITY
+ - _APP_SYSTEM_RESPONSE_FORMAT
+ - _APP_OPTIONS_ABUSE
+ - _APP_OPTIONS_ROUTER_PROTECTION
+ - _APP_OPTIONS_FORCE_HTTPS
+ - _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS
+ - _APP_OPENSSL_KEY_V1
+ - _APP_DOMAIN
+ - _APP_DOMAIN_TARGET
+ - _APP_DOMAIN_FUNCTIONS
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_SMTP_HOST
+ - _APP_SMTP_PORT
+ - _APP_SMTP_SECURE
+ - _APP_SMTP_USERNAME
+ - _APP_SMTP_PASSWORD
+ - _APP_USAGE_STATS
+ - _APP_STORAGE_LIMIT
+ - _APP_STORAGE_PREVIEW_LIMIT
+ - _APP_STORAGE_ANTIVIRUS
+ - _APP_STORAGE_ANTIVIRUS_HOST
+ - _APP_STORAGE_ANTIVIRUS_PORT
+ - _APP_STORAGE_DEVICE
+ - _APP_STORAGE_S3_ACCESS_KEY
+ - _APP_STORAGE_S3_SECRET
+ - _APP_STORAGE_S3_REGION
+ - _APP_STORAGE_S3_BUCKET
+ - _APP_STORAGE_DO_SPACES_ACCESS_KEY
+ - _APP_STORAGE_DO_SPACES_SECRET
+ - _APP_STORAGE_DO_SPACES_REGION
+ - _APP_STORAGE_DO_SPACES_BUCKET
+ - _APP_STORAGE_BACKBLAZE_ACCESS_KEY
+ - _APP_STORAGE_BACKBLAZE_SECRET
+ - _APP_STORAGE_BACKBLAZE_REGION
+ - _APP_STORAGE_BACKBLAZE_BUCKET
+ - _APP_STORAGE_LINODE_ACCESS_KEY
+ - _APP_STORAGE_LINODE_SECRET
+ - _APP_STORAGE_LINODE_REGION
+ - _APP_STORAGE_LINODE_BUCKET
+ - _APP_STORAGE_WASABI_ACCESS_KEY
+ - _APP_STORAGE_WASABI_SECRET
+ - _APP_STORAGE_WASABI_REGION
+ - _APP_STORAGE_WASABI_BUCKET
+ - _APP_FUNCTIONS_SIZE_LIMIT
+ - _APP_FUNCTIONS_TIMEOUT
+ - _APP_FUNCTIONS_BUILD_TIMEOUT
+ - _APP_FUNCTIONS_CPUS
+ - _APP_FUNCTIONS_MEMORY
+ - _APP_FUNCTIONS_RUNTIMES
+ - _APP_EXECUTOR_SECRET
+ - _APP_EXECUTOR_HOST
+ - _APP_LOGGING_CONFIG
+ - _APP_MAINTENANCE_INTERVAL
+ - _APP_MAINTENANCE_DELAY
+ - _APP_MAINTENANCE_RETENTION_EXECUTION
+ - _APP_MAINTENANCE_RETENTION_CACHE
+ - _APP_MAINTENANCE_RETENTION_ABUSE
+ - _APP_MAINTENANCE_RETENTION_AUDIT
+ - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
+ - _APP_MAINTENANCE_RETENTION_SCHEDULES
+ - _APP_SMS_PROVIDER
+ - _APP_SMS_FROM
+ - _APP_GRAPHQL_MAX_BATCH_SIZE
+ - _APP_GRAPHQL_MAX_COMPLEXITY
+ - _APP_GRAPHQL_MAX_DEPTH
+ - _APP_VCS_GITHUB_APP_NAME
+ - _APP_VCS_GITHUB_PRIVATE_KEY
+ - _APP_VCS_GITHUB_APP_ID
+ - _APP_VCS_GITHUB_WEBHOOK_SECRET
+ - _APP_VCS_GITHUB_CLIENT_SECRET
+ - _APP_VCS_GITHUB_CLIENT_ID
+ - _APP_MIGRATIONS_FIREBASE_CLIENT_ID
+ - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
+ - _APP_ASSISTANT_OPENAI_API_KEY
+
+ appwrite-console:
+ image: appwrite/console:5.0.12
+ container_name: appwrite-console
+ <<: *x-logging
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ labels:
+ - "traefik.enable=true"
+ - "traefik.constraint-label-stack=appwrite"
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_LOCALE
+ - _APP_CONSOLE_WHITELIST_ROOT
+ - _APP_CONSOLE_WHITELIST_EMAILS
+ - _APP_CONSOLE_SESSION_ALERTS
+ - _APP_CONSOLE_WHITELIST_IPS
+ - _APP_CONSOLE_HOSTNAMES
+ - _APP_SYSTEM_EMAIL_NAME
+ - _APP_SYSTEM_EMAIL_ADDRESS
+ - _APP_EMAIL_SECURITY
+ - _APP_SYSTEM_RESPONSE_FORMAT
+ - _APP_OPTIONS_ABUSE
+ - _APP_OPTIONS_ROUTER_PROTECTION
+ - _APP_OPTIONS_FORCE_HTTPS
+ - _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS
+ - _APP_OPENSSL_KEY_V1
+ - _APP_DOMAIN
+ - _APP_DOMAIN_TARGET
+ - _APP_DOMAIN_FUNCTIONS
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_SMTP_HOST
+ - _APP_SMTP_PORT
+ - _APP_SMTP_SECURE
+ - _APP_SMTP_USERNAME
+ - _APP_SMTP_PASSWORD
+ - _APP_USAGE_STATS
+ - _APP_STORAGE_LIMIT
+ - _APP_STORAGE_PREVIEW_LIMIT
+ - _APP_STORAGE_ANTIVIRUS
+ - _APP_STORAGE_ANTIVIRUS_HOST
+ - _APP_STORAGE_ANTIVIRUS_PORT
+ - _APP_STORAGE_DEVICE
+ - _APP_STORAGE_S3_ACCESS_KEY
+ - _APP_STORAGE_S3_SECRET
+ - _APP_STORAGE_S3_REGION
+ - _APP_STORAGE_S3_BUCKET
+ - _APP_STORAGE_DO_SPACES_ACCESS_KEY
+ - _APP_STORAGE_DO_SPACES_SECRET
+ - _APP_STORAGE_DO_SPACES_REGION
+ - _APP_STORAGE_DO_SPACES_BUCKET
+ - _APP_STORAGE_BACKBLAZE_ACCESS_KEY
+ - _APP_STORAGE_BACKBLAZE_SECRET
+ - _APP_STORAGE_BACKBLAZE_REGION
+ - _APP_STORAGE_BACKBLAZE_BUCKET
+ - _APP_STORAGE_LINODE_ACCESS_KEY
+ - _APP_STORAGE_LINODE_SECRET
+ - _APP_STORAGE_LINODE_REGION
+ - _APP_STORAGE_LINODE_BUCKET
+ - _APP_STORAGE_WASABI_ACCESS_KEY
+ - _APP_STORAGE_WASABI_SECRET
+ - _APP_STORAGE_WASABI_REGION
+ - _APP_STORAGE_WASABI_BUCKET
+
+ appwrite-realtime:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: realtime
+ container_name: appwrite-realtime
+ <<: *x-logging
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - mariadb
+ - redis
+ labels:
+ - "traefik.enable=true"
+ - "traefik.constraint-label-stack=appwrite"
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPTIONS_ABUSE
+ - _APP_OPTIONS_ROUTER_PROTECTION
+ - _APP_OPENSSL_KEY_V1
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_USAGE_STATS
+ - _APP_LOGGING_CONFIG
+
+ appwrite-worker-audits:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-audits
+ <<: *x-logging
+ container_name: appwrite-worker-audits
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ - mariadb
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_LOGGING_CONFIG
+
+ appwrite-worker-webhooks:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-webhooks
+ <<: *x-logging
+ container_name: appwrite-worker-webhooks
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ - mariadb
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_EMAIL_SECURITY
+ - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_LOGGING_CONFIG
+
+ appwrite-worker-deletes:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-deletes
+ <<: *x-logging
+ container_name: appwrite-worker-deletes
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ - mariadb
+ volumes:
+ - appwrite-uploads:/storage/uploads:rw
+ - appwrite-cache:/storage/cache:rw
+ - appwrite-functions:/storage/functions:rw
+ - appwrite-builds:/storage/builds:rw
+ - appwrite-certificates:/storage/certificates:rw
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_STORAGE_DEVICE
+ - _APP_STORAGE_S3_ACCESS_KEY
+ - _APP_STORAGE_S3_SECRET
+ - _APP_STORAGE_S3_REGION
+ - _APP_STORAGE_S3_BUCKET
+ - _APP_STORAGE_DO_SPACES_ACCESS_KEY
+ - _APP_STORAGE_DO_SPACES_SECRET
+ - _APP_STORAGE_DO_SPACES_REGION
+ - _APP_STORAGE_DO_SPACES_BUCKET
+ - _APP_STORAGE_BACKBLAZE_ACCESS_KEY
+ - _APP_STORAGE_BACKBLAZE_SECRET
+ - _APP_STORAGE_BACKBLAZE_REGION
+ - _APP_STORAGE_BACKBLAZE_BUCKET
+ - _APP_STORAGE_LINODE_ACCESS_KEY
+ - _APP_STORAGE_LINODE_SECRET
+ - _APP_STORAGE_LINODE_REGION
+ - _APP_STORAGE_LINODE_BUCKET
+ - _APP_STORAGE_WASABI_ACCESS_KEY
+ - _APP_STORAGE_WASABI_SECRET
+ - _APP_STORAGE_WASABI_REGION
+ - _APP_STORAGE_WASABI_BUCKET
+ - _APP_LOGGING_CONFIG
+ - _APP_EXECUTOR_SECRET
+ - _APP_EXECUTOR_HOST
+ - _APP_MAINTENANCE_RETENTION_ABUSE
+ - _APP_MAINTENANCE_RETENTION_AUDIT
+ - _APP_MAINTENANCE_RETENTION_EXECUTION
+
+ appwrite-worker-databases:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-databases
+ <<: *x-logging
+ container_name: appwrite-worker-databases
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ - mariadb
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_LOGGING_CONFIG
+
+ appwrite-worker-builds:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-builds
+ <<: *x-logging
+ container_name: appwrite-worker-builds
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ - mariadb
+ volumes:
+ - appwrite-functions:/storage/functions:rw
+ - appwrite-builds:/storage/builds:rw
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_EXECUTOR_SECRET
+ - _APP_EXECUTOR_HOST
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_LOGGING_CONFIG
+ - _APP_VCS_GITHUB_APP_NAME
+ - _APP_VCS_GITHUB_PRIVATE_KEY
+ - _APP_VCS_GITHUB_APP_ID
+ - _APP_FUNCTIONS_TIMEOUT
+ - _APP_FUNCTIONS_BUILD_TIMEOUT
+ - _APP_FUNCTIONS_CPUS
+ - _APP_FUNCTIONS_MEMORY
+ - _APP_FUNCTIONS_SIZE_LIMIT
+ - _APP_OPTIONS_FORCE_HTTPS
+ - _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS
+ - _APP_DOMAIN
+ - _APP_STORAGE_DEVICE
+ - _APP_STORAGE_S3_ACCESS_KEY
+ - _APP_STORAGE_S3_SECRET
+ - _APP_STORAGE_S3_REGION
+ - _APP_STORAGE_S3_BUCKET
+ - _APP_STORAGE_DO_SPACES_ACCESS_KEY
+ - _APP_STORAGE_DO_SPACES_SECRET
+ - _APP_STORAGE_DO_SPACES_REGION
+ - _APP_STORAGE_DO_SPACES_BUCKET
+ - _APP_STORAGE_BACKBLAZE_ACCESS_KEY
+ - _APP_STORAGE_BACKBLAZE_SECRET
+ - _APP_STORAGE_BACKBLAZE_REGION
+ - _APP_STORAGE_BACKBLAZE_BUCKET
+ - _APP_STORAGE_LINODE_ACCESS_KEY
+ - _APP_STORAGE_LINODE_SECRET
+ - _APP_STORAGE_LINODE_REGION
+ - _APP_STORAGE_LINODE_BUCKET
+ - _APP_STORAGE_WASABI_ACCESS_KEY
+ - _APP_STORAGE_WASABI_SECRET
+ - _APP_STORAGE_WASABI_REGION
+ - _APP_STORAGE_WASABI_BUCKET
+
+ appwrite-worker-certificates:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-certificates
+ <<: *x-logging
+ container_name: appwrite-worker-certificates
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ - mariadb
+ volumes:
+ - appwrite-config:/storage/config:rw
+ - appwrite-certificates:/storage/certificates:rw
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_DOMAIN
+ - _APP_DOMAIN_TARGET
+ - _APP_DOMAIN_FUNCTIONS
+ - _APP_EMAIL_CERTIFICATES
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_LOGGING_CONFIG
+
+ appwrite-worker-functions:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-functions
+ <<: *x-logging
+ container_name: appwrite-worker-functions
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ - mariadb
+ - openruntimes-executor
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_DOMAIN
+ - _APP_OPTIONS_FORCE_HTTPS
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_FUNCTIONS_TIMEOUT
+ - _APP_FUNCTIONS_BUILD_TIMEOUT
+ - _APP_FUNCTIONS_CPUS
+ - _APP_FUNCTIONS_MEMORY
+ - _APP_EXECUTOR_SECRET
+ - _APP_EXECUTOR_HOST
+ - _APP_USAGE_STATS
+ - _APP_DOCKER_HUB_USERNAME
+ - _APP_DOCKER_HUB_PASSWORD
+ - _APP_LOGGING_CONFIG
+
+ appwrite-worker-mails:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-mails
+ <<: *x-logging
+ container_name: appwrite-worker-mails
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_SYSTEM_EMAIL_NAME
+ - _APP_SYSTEM_EMAIL_ADDRESS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_SMTP_HOST
+ - _APP_SMTP_PORT
+ - _APP_SMTP_SECURE
+ - _APP_SMTP_USERNAME
+ - _APP_SMTP_PASSWORD
+ - _APP_LOGGING_CONFIG
+
+ appwrite-worker-messaging:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-messaging
+ container_name: appwrite-worker-messaging
+ <<: *x-logging
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ volumes:
+ - appwrite-uploads:/storage/uploads:rw
+ depends_on:
+ - redis
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_LOGGING_CONFIG
+ - _APP_SMS_FROM
+ - _APP_SMS_PROVIDER
+ - _APP_STORAGE_DEVICE
+ - _APP_STORAGE_S3_ACCESS_KEY
+ - _APP_STORAGE_S3_SECRET
+ - _APP_STORAGE_S3_REGION
+ - _APP_STORAGE_S3_BUCKET
+ - _APP_STORAGE_DO_SPACES_ACCESS_KEY
+ - _APP_STORAGE_DO_SPACES_SECRET
+ - _APP_STORAGE_DO_SPACES_REGION
+ - _APP_STORAGE_DO_SPACES_BUCKET
+ - _APP_STORAGE_BACKBLAZE_ACCESS_KEY
+ - _APP_STORAGE_BACKBLAZE_SECRET
+ - _APP_STORAGE_BACKBLAZE_REGION
+ - _APP_STORAGE_BACKBLAZE_BUCKET
+ - _APP_STORAGE_LINODE_ACCESS_KEY
+ - _APP_STORAGE_LINODE_SECRET
+ - _APP_STORAGE_LINODE_REGION
+ - _APP_STORAGE_LINODE_BUCKET
+ - _APP_STORAGE_WASABI_ACCESS_KEY
+ - _APP_STORAGE_WASABI_SECRET
+ - _APP_STORAGE_WASABI_REGION
+ - _APP_STORAGE_WASABI_BUCKET
+
+ appwrite-worker-migrations:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-migrations
+ <<: *x-logging
+ container_name: appwrite-worker-migrations
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - mariadb
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_DOMAIN
+ - _APP_DOMAIN_TARGET
+ - _APP_EMAIL_SECURITY
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_LOGGING_CONFIG
+ - _APP_MIGRATIONS_FIREBASE_CLIENT_ID
+ - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
+
+ appwrite-task-maintenance:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: maintenance
+ <<: *x-logging
+ container_name: appwrite-task-maintenance
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_DOMAIN
+ - _APP_DOMAIN_TARGET
+ - _APP_DOMAIN_FUNCTIONS
+ - _APP_OPENSSL_KEY_V1
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_MAINTENANCE_INTERVAL
+ - _APP_MAINTENANCE_RETENTION_EXECUTION
+ - _APP_MAINTENANCE_RETENTION_CACHE
+ - _APP_MAINTENANCE_RETENTION_ABUSE
+ - _APP_MAINTENANCE_RETENTION_AUDIT
+ - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
+ - _APP_MAINTENANCE_RETENTION_SCHEDULES
+
+ appwrite-worker-usage:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-usage
+ container_name: appwrite-worker-usage
+ <<: *x-logging
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ - mariadb
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_USAGE_STATS
+ - _APP_LOGGING_CONFIG
+ - _APP_USAGE_AGGREGATION_INTERVAL
+
+ appwrite-worker-usage-dump:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: worker-usage-dump
+ container_name: appwrite-worker-usage-dump
+ <<: *x-logging
+ networks:
+ - dokploy-network
+ depends_on:
+ - redis
+ - mariadb
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_USAGE_STATS
+ - _APP_LOGGING_CONFIG
+ - _APP_USAGE_AGGREGATION_INTERVAL
+
+ appwrite-task-scheduler-functions:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: schedule-functions
+ container_name: appwrite-task-scheduler-functions
+ <<: *x-logging
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - mariadb
+ - redis
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+
+ appwrite-task-scheduler-executions:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: schedule-executions
+ container_name: appwrite-task-scheduler-executions
+ <<: *x-logging
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - mariadb
+ - redis
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+
+ appwrite-task-scheduler-messages:
+ image: appwrite/appwrite:1.6.0
+ entrypoint: schedule-messages
+ container_name: appwrite-task-scheduler-messages
+ <<: *x-logging
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ depends_on:
+ - mariadb
+ - redis
+ environment:
+ - _APP_ENV
+ - _APP_WORKER_PER_CORE
+ - _APP_OPENSSL_KEY_V1
+ - _APP_REDIS_HOST
+ - _APP_REDIS_PORT
+ - _APP_REDIS_USER
+ - _APP_REDIS_PASS
+ - _APP_DB_HOST
+ - _APP_DB_PORT
+ - _APP_DB_SCHEMA
+ - _APP_DB_USER
+ - _APP_DB_PASS
+
+ appwrite-assistant:
+ image: appwrite/assistant:0.4.0
+ container_name: appwrite-assistant
+ <<: *x-logging
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ environment:
+ - _APP_ASSISTANT_OPENAI_API_KEY
+
+ openruntimes-executor:
+ container_name: openruntimes-executor
+ hostname: exc1
+ <<: *x-logging
+ restart: unless-stopped
+ stop_signal: SIGINT
+ image: openruntimes/executor:0.6.11
+ networks:
+ - dokploy-network
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - appwrite-builds:/storage/builds:rw
+ - appwrite-functions:/storage/functions:rw
+ - /tmp:/tmp:rw
+ environment:
+ - OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_FUNCTIONS_INACTIVE_THRESHOLD
+ - OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_FUNCTIONS_MAINTENANCE_INTERVAL
+ - OPR_EXECUTOR_NETWORK=$_APP_FUNCTIONS_RUNTIMES_NETWORK
+ - OPR_EXECUTOR_DOCKER_HUB_USERNAME=$_APP_DOCKER_HUB_USERNAME
+ - OPR_EXECUTOR_DOCKER_HUB_PASSWORD=$_APP_DOCKER_HUB_PASSWORD
+ - OPR_EXECUTOR_ENV=$_APP_ENV
+ - OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES
+ - OPR_EXECUTOR_SECRET=$_APP_EXECUTOR_SECRET
+ - OPR_EXECUTOR_LOGGING_CONFIG=$_APP_LOGGING_CONFIG
+ - OPR_EXECUTOR_STORAGE_DEVICE=$_APP_STORAGE_DEVICE
+ - OPR_EXECUTOR_STORAGE_S3_ACCESS_KEY=$_APP_STORAGE_S3_ACCESS_KEY
+ - OPR_EXECUTOR_STORAGE_S3_SECRET=$_APP_STORAGE_S3_SECRET
+ - OPR_EXECUTOR_STORAGE_S3_REGION=$_APP_STORAGE_S3_REGION
+ - OPR_EXECUTOR_STORAGE_S3_BUCKET=$_APP_STORAGE_S3_BUCKET
+ - OPR_EXECUTOR_STORAGE_DO_SPACES_ACCESS_KEY=$_APP_STORAGE_DO_SPACES_ACCESS_KEY
+ - OPR_EXECUTOR_STORAGE_DO_SPACES_SECRET=$_APP_STORAGE_DO_SPACES_SECRET
+ - OPR_EXECUTOR_STORAGE_DO_SPACES_REGION=$_APP_STORAGE_DO_SPACES_REGION
+ - OPR_EXECUTOR_STORAGE_DO_SPACES_BUCKET=$_APP_STORAGE_DO_SPACES_BUCKET
+ - OPR_EXECUTOR_STORAGE_BACKBLAZE_ACCESS_KEY=$_APP_STORAGE_BACKBLAZE_ACCESS_KEY
+ - OPR_EXECUTOR_STORAGE_BACKBLAZE_SECRET=$_APP_STORAGE_BACKBLAZE_SECRET
+ - OPR_EXECUTOR_STORAGE_BACKBLAZE_REGION=$_APP_STORAGE_BACKBLAZE_REGION
+ - OPR_EXECUTOR_STORAGE_BACKBLAZE_BUCKET=$_APP_STORAGE_BACKBLAZE_BUCKET
+ - OPR_EXECUTOR_STORAGE_LINODE_ACCESS_KEY=$_APP_STORAGE_LINODE_ACCESS_KEY
+ - OPR_EXECUTOR_STORAGE_LINODE_SECRET=$_APP_STORAGE_LINODE_SECRET
+ - OPR_EXECUTOR_STORAGE_LINODE_REGION=$_APP_STORAGE_LINODE_REGION
+ - OPR_EXECUTOR_STORAGE_LINODE_BUCKET=$_APP_STORAGE_LINODE_BUCKET
+ - OPR_EXECUTOR_STORAGE_WASABI_ACCESS_KEY=$_APP_STORAGE_WASABI_ACCESS_KEY
+ - OPR_EXECUTOR_STORAGE_WASABI_SECRET=$_APP_STORAGE_WASABI_SECRET
+ - OPR_EXECUTOR_STORAGE_WASABI_REGION=$_APP_STORAGE_WASABI_REGION
+ - OPR_EXECUTOR_STORAGE_WASABI_BUCKET=$_APP_STORAGE_WASABI_BUCKET
+
+ mariadb:
+ image: mariadb:10.11
+ container_name: appwrite-mariadb
+ <<: *x-logging
+ restart: unless-stopped
+ networks:
+ - dokploy-network
+ volumes:
+ - appwrite-mariadb:/var/lib/mysql:rw
+ environment:
+ - MYSQL_ROOT_PASSWORD=${_APP_DB_ROOT_PASS}
+ - MYSQL_DATABASE=${_APP_DB_SCHEMA}
+ - MYSQL_USER=${_APP_DB_USER}
+ - MYSQL_PASSWORD=${_APP_DB_PASS}
+ - MARIADB_AUTO_UPGRADE=1
+ command: "mysqld --innodb-flush-method=fsync"
+
+ redis:
+ image: redis:7.2.4-alpine
+ container_name: appwrite-redis
+ <<: *x-logging
+ restart: unless-stopped
+ command: >
+ redis-server
+ --maxmemory 512mb
+ --maxmemory-policy allkeys-lru
+ --maxmemory-samples 5
+ networks:
+ - dokploy-network
+ volumes:
+ - appwrite-redis:/data:rw
+
+# Uncomment and configure if ClamAV is needed
+# clamav:
+# image: appwrite/clamav:1.2.0
+# container_name: appwrite-clamav
+# restart: unless-stopped
+# networks:
+# - dokploy-network
+# volumes:
+# - appwrite-uploads:/storage/uploads
+
+volumes:
+ appwrite-mariadb:
+ appwrite-redis:
+ appwrite-cache:
+ appwrite-uploads:
+ appwrite-certificates:
+ appwrite-functions:
+ appwrite-builds:
+ appwrite-config:
+
+networks:
+ dokploy-network:
+ external: true
diff --git a/blueprints/appwrite/template.yml b/blueprints/appwrite/template.yml
new file mode 100644
index 000000000..c86eb8a86
--- /dev/null
+++ b/blueprints/appwrite/template.yml
@@ -0,0 +1,139 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: appwrite
+ port: 80
+ host: ${main_domain}
+ path: /
+ - serviceName: appwrite-console
+ port: 80
+ host: ${main_domain}
+ path: /console
+ - serviceName: appwrite-realtime
+ port: 80
+ host: ${main_domain}
+ path: /v1/realtime
+
+ env:
+ - _APP_ENV=production
+ - _APP_LOCALE=en
+ - _APP_OPTIONS_ABUSE=enabled
+ - _APP_OPTIONS_FORCE_HTTPS=disabled
+ - _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS=disabled
+ - _APP_OPTIONS_ROUTER_PROTECTION=disabled
+ - _APP_OPENSSL_KEY_V1=your-secret-key
+ - _APP_DOMAIN=${main_domain}
+ - _APP_DOMAIN_FUNCTIONS=${main_domain}
+ - _APP_DOMAIN_TARGET=${main_domain}
+ - _APP_CONSOLE_WHITELIST_ROOT=enabled
+ - _APP_CONSOLE_WHITELIST_EMAILS=
+ - _APP_CONSOLE_WHITELIST_IPS=
+ - _APP_CONSOLE_HOSTNAMES=
+ - _APP_SYSTEM_EMAIL_NAME=Appwrite
+ - _APP_SYSTEM_EMAIL_ADDRESS=noreply@appwrite.io
+ - _APP_SYSTEM_TEAM_EMAIL=team@appwrite.io
+ - _APP_SYSTEM_RESPONSE_FORMAT=
+ - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS=certs@appwrite.io
+ - _APP_EMAIL_SECURITY=
+ - _APP_EMAIL_CERTIFICATES=
+ - _APP_USAGE_STATS=enabled
+ - _APP_LOGGING_PROVIDER=
+ - _APP_LOGGING_CONFIG=
+ - _APP_USAGE_AGGREGATION_INTERVAL=30
+ - _APP_USAGE_TIMESERIES_INTERVAL=30
+ - _APP_USAGE_DATABASE_INTERVAL=900
+ - _APP_WORKER_PER_CORE=6
+ - _APP_CONSOLE_SESSION_ALERTS=disabled
+ - _APP_REDIS_HOST=redis
+ - _APP_REDIS_PORT=6379
+ - _APP_REDIS_USER=
+ - _APP_REDIS_PASS=
+ - _APP_DB_HOST=mariadb
+ - _APP_DB_PORT=3306
+ - _APP_DB_SCHEMA=appwrite
+ - _APP_DB_USER=user
+ - _APP_DB_PASS=password
+ - _APP_DB_ROOT_PASS=rootsecretpassword
+ - _APP_INFLUXDB_HOST=influxdb
+ - _APP_INFLUXDB_PORT=8086
+ - _APP_STATSD_HOST=telegraf
+ - _APP_STATSD_PORT=8125
+ - _APP_SMTP_HOST=
+ - _APP_SMTP_PORT=
+ - _APP_SMTP_SECURE=
+ - _APP_SMTP_USERNAME=
+ - _APP_SMTP_PASSWORD=
+ - _APP_SMS_PROVIDER=
+ - _APP_SMS_FROM=
+ - _APP_STORAGE_LIMIT=30000000
+ - _APP_STORAGE_PREVIEW_LIMIT=20000000
+ - _APP_STORAGE_ANTIVIRUS=disabled
+ - _APP_STORAGE_ANTIVIRUS_HOST=clamav
+ - _APP_STORAGE_ANTIVIRUS_PORT=3310
+ - _APP_STORAGE_DEVICE=local
+ - _APP_STORAGE_S3_ACCESS_KEY=
+ - _APP_STORAGE_S3_SECRET=
+ - _APP_STORAGE_S3_REGION=us-east-1
+ - _APP_STORAGE_S3_BUCKET=
+ - _APP_STORAGE_DO_SPACES_ACCESS_KEY=
+ - _APP_STORAGE_DO_SPACES_SECRET=
+ - _APP_STORAGE_DO_SPACES_REGION=us-east-1
+ - _APP_STORAGE_DO_SPACES_BUCKET=
+ - _APP_STORAGE_BACKBLAZE_ACCESS_KEY=
+ - _APP_STORAGE_BACKBLAZE_SECRET=
+ - _APP_STORAGE_BACKBLAZE_REGION=us-west-004
+ - _APP_STORAGE_BACKBLAZE_BUCKET=
+ - _APP_STORAGE_LINODE_ACCESS_KEY=
+ - _APP_STORAGE_LINODE_SECRET=
+ - _APP_STORAGE_LINODE_REGION=eu-central-1
+ - _APP_STORAGE_LINODE_BUCKET=
+ - _APP_STORAGE_WASABI_ACCESS_KEY=
+ - _APP_STORAGE_WASABI_SECRET=
+ - _APP_STORAGE_WASABI_REGION=eu-central-1
+ - _APP_STORAGE_WASABI_BUCKET=
+ - _APP_FUNCTIONS_SIZE_LIMIT=30000000
+ - _APP_FUNCTIONS_BUILD_SIZE_LIMIT=2000000000
+ - _APP_FUNCTIONS_TIMEOUT=900
+ - _APP_FUNCTIONS_BUILD_TIMEOUT=900
+ - _APP_FUNCTIONS_CONTAINERS=10
+ - _APP_FUNCTIONS_CPUS=0
+ - _APP_FUNCTIONS_MEMORY=0
+ - _APP_FUNCTIONS_MEMORY_SWAP=0
+ - _APP_FUNCTIONS_RUNTIMES=node-16.0,php-8.0,python-3.9,ruby-3.0
+ - _APP_EXECUTOR_SECRET=your-secret-key
+ - _APP_EXECUTOR_HOST=http://exc1/v1
+ - _APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes
+ - _APP_FUNCTIONS_ENVS=node-16.0,php-7.4,python-3.9,ruby-3.0
+ - _APP_FUNCTIONS_INACTIVE_THRESHOLD=60
+ - DOCKERHUB_PULL_USERNAME=
+ - DOCKERHUB_PULL_PASSWORD=
+ - DOCKERHUB_PULL_EMAIL=
+ - OPEN_RUNTIMES_NETWORK=appwrite_runtimes
+ - _APP_FUNCTIONS_RUNTIMES_NETWORK=runtimes
+ - _APP_DOCKER_HUB_USERNAME=
+ - _APP_DOCKER_HUB_PASSWORD=
+ - _APP_FUNCTIONS_MAINTENANCE_INTERVAL=3600
+ - _APP_VCS_GITHUB_APP_NAME=
+ - _APP_VCS_GITHUB_PRIVATE_KEY=
+ - _APP_VCS_GITHUB_APP_ID=
+ - _APP_VCS_GITHUB_CLIENT_ID=
+ - _APP_VCS_GITHUB_CLIENT_SECRET=
+ - _APP_VCS_GITHUB_WEBHOOK_SECRET=
+ - _APP_MAINTENANCE_INTERVAL=86400
+ - _APP_MAINTENANCE_DELAY=0
+ - _APP_MAINTENANCE_RETENTION_CACHE=2592000
+ - _APP_MAINTENANCE_RETENTION_EXECUTION=1209600
+ - _APP_MAINTENANCE_RETENTION_AUDIT=1209600
+ - _APP_MAINTENANCE_RETENTION_ABUSE=86400
+ - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000
+ - _APP_MAINTENANCE_RETENTION_SCHEDULES=86400
+ - _APP_GRAPHQL_MAX_BATCH_SIZE=10
+ - _APP_GRAPHQL_MAX_COMPLEXITY=250
+ - _APP_GRAPHQL_MAX_DEPTH=3
+ - _APP_MIGRATIONS_FIREBASE_CLIENT_ID=
+ - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET=
+ - _APP_ASSISTANT_OPENAI_API_KEY=
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/aptabase/aptabase.svg b/blueprints/aptabase/aptabase.svg
new file mode 100644
index 000000000..3cb71ecfa
--- /dev/null
+++ b/blueprints/aptabase/aptabase.svg
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/blueprints/aptabase/docker-compose.yml b/blueprints/aptabase/docker-compose.yml
new file mode 100644
index 000000000..dfde1caef
--- /dev/null
+++ b/blueprints/aptabase/docker-compose.yml
@@ -0,0 +1,49 @@
+services:
+ aptabase_db:
+ image: postgres:15-alpine
+ restart: always
+ volumes:
+ - db-data:/var/lib/postgresql/data
+ environment:
+ POSTGRES_USER: aptabase
+ POSTGRES_PASSWORD: sTr0NGp4ssw0rd
+
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U aptabase"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+ aptabase_events_db:
+ image: clickhouse/clickhouse-server:23.8.16.16-alpine
+ restart: always
+ volumes:
+ - events-db-data:/var/lib/clickhouse
+ environment:
+ CLICKHOUSE_USER: aptabase
+ CLICKHOUSE_PASSWORD: sTr0NGp4ssw0rd
+ ulimits:
+ nofile:
+ soft: 262144
+ hard: 262144
+
+ healthcheck:
+ test: ["CMD-SHELL", "curl -f http://localhost:8123 || exit 1"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+ aptabase:
+ image: ghcr.io/aptabase/aptabase:main
+ restart: always
+ environment:
+ BASE_URL: http://${APTABASE_HOST}
+ AUTH_SECRET: ${AUTH_SECRET}
+ DATABASE_URL: Server=aptabase_db;Port=5432;User Id=aptabase;Password=sTr0NGp4ssw0rd;Database=aptabase
+ CLICKHOUSE_URL: Host=aptabase_events_db;Port=8123;Username=aptabase;Password=sTr0NGp4ssw0rd
+
+volumes:
+ db-data:
+ driver: local
+ events-db-data:
+ driver: local
diff --git a/blueprints/aptabase/template.yml b/blueprints/aptabase/template.yml
new file mode 100644
index 000000000..14717467a
--- /dev/null
+++ b/blueprints/aptabase/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+ auth_secret: ${base64:32}
+
+config:
+ domains:
+ - serviceName: aptabase
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ - APTABASE_HOST=${main_domain}
+ - AUTH_SECRET=${auth_secret}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/baserow/baserow.webp b/blueprints/baserow/baserow.webp
new file mode 100644
index 000000000..3e825f7a5
Binary files /dev/null and b/blueprints/baserow/baserow.webp differ
diff --git a/blueprints/baserow/docker-compose.yml b/blueprints/baserow/docker-compose.yml
new file mode 100644
index 000000000..db588e83a
--- /dev/null
+++ b/blueprints/baserow/docker-compose.yml
@@ -0,0 +1,10 @@
+version: "3.8"
+services:
+ baserow:
+ image: baserow/baserow:1.25.2
+ environment:
+ BASEROW_PUBLIC_URL: "http://${BASEROW_HOST}"
+ volumes:
+ - baserow_data:/baserow/data
+volumes:
+ baserow_data:
diff --git a/blueprints/baserow/template.yml b/blueprints/baserow/template.yml
new file mode 100644
index 000000000..0aa124043
--- /dev/null
+++ b/blueprints/baserow/template.yml
@@ -0,0 +1,13 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: baserow
+ port: 80
+ host: ${main_domain}
+
+ env:
+ - BASEROW_HOST=${main_domain}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/blender/blender.svg b/blueprints/blender/blender.svg
new file mode 100644
index 000000000..e59079f5b
--- /dev/null
+++ b/blueprints/blender/blender.svg
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/blender/docker-compose.yml b/blueprints/blender/docker-compose.yml
new file mode 100644
index 000000000..893f3deea
--- /dev/null
+++ b/blueprints/blender/docker-compose.yml
@@ -0,0 +1,26 @@
+version: "3.8"
+
+services:
+ blender:
+ image: lscr.io/linuxserver/blender:latest
+ runtime: nvidia
+ deploy:
+ resources:
+ reservations:
+ devices:
+ - driver: nvidia
+ count: all
+ capabilities:
+ - gpu
+ environment:
+ - NVIDIA_VISIBLE_DEVICES=all
+ - NVIDIA_DRIVER_CAPABILITIES=all
+ - PUID=1000
+ - PGID=1000
+ - TZ=Etc/UTC
+ - SUBFOLDER=/ #optional
+ ports:
+ - 3000
+ - 3001
+ restart: unless-stopped
+ shm_size: 1gb
diff --git a/blueprints/blender/template.yml b/blueprints/blender/template.yml
new file mode 100644
index 000000000..b4703f91b
--- /dev/null
+++ b/blueprints/blender/template.yml
@@ -0,0 +1,18 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: blender
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - PUID=1000
+ - PGID=1000
+ - TZ=Etc/UTC
+ - SUBFOLDER=/
+ - NVIDIA_VISIBLE_DEVICES=all
+ - NVIDIA_DRIVER_CAPABILITIES=all
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/browserless/browserless.svg b/blueprints/browserless/browserless.svg
new file mode 100644
index 000000000..35023f7d9
--- /dev/null
+++ b/blueprints/browserless/browserless.svg
@@ -0,0 +1,13 @@
+
+ favicon
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/browserless/docker-compose.yml b/blueprints/browserless/docker-compose.yml
new file mode 100644
index 000000000..11d6d95f6
--- /dev/null
+++ b/blueprints/browserless/docker-compose.yml
@@ -0,0 +1,16 @@
+services:
+ browserless:
+ image: ghcr.io/browserless/chromium:v2.23.0
+ environment:
+ TOKEN: ${BROWSERLESS_TOKEN}
+ expose:
+ - 3000
+ healthcheck:
+ test:
+ - CMD
+ - curl
+ - '-f'
+ - 'http://127.0.0.1:3000/docs'
+ interval: 2s
+ timeout: 10s
+ retries: 15
diff --git a/blueprints/browserless/template.yml b/blueprints/browserless/template.yml
new file mode 100644
index 000000000..a2999ffc1
--- /dev/null
+++ b/blueprints/browserless/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+ browserless_token: ${password:16}
+
+config:
+ domains:
+ - serviceName: browserless
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - BROWERLESS_HOST=${main_domain}
+ - BROWSERLESS_TOKEN=${browserless_token}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/budibase/budibase.svg b/blueprints/budibase/budibase.svg
new file mode 100644
index 000000000..26d09cc97
--- /dev/null
+++ b/blueprints/budibase/budibase.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/budibase/docker-compose.yml b/blueprints/budibase/docker-compose.yml
new file mode 100644
index 000000000..d1d6744af
--- /dev/null
+++ b/blueprints/budibase/docker-compose.yml
@@ -0,0 +1,192 @@
+services:
+ apps:
+ image: budibase.docker.scarf.sh/budibase/apps:3.2.25
+ restart: unless-stopped
+
+ environment:
+ SELF_HOSTED: 1
+ LOG_LEVEL: info
+ PORT: 4002
+ INTERNAL_API_KEY: ${BB_INTERNAL_API_KEY}
+ API_ENCRYPTION_KEY: ${BB_API_ENCRYPTION_KEY}
+ JWT_SECRET: ${BB_JWT_SECRET}
+ MINIO_ACCESS_KEY: ${BB_MINIO_ACCESS_KEY}
+ MINIO_SECRET_KEY: ${BB_MINIO_SECRET_KEY}
+ MINIO_URL: http://minio:9000
+ REDIS_URL: redis:6379
+ REDIS_PASSWORD: ${BB_REDIS_PASSWORD}
+ WORKER_URL: http://worker:4003
+ COUCH_DB_USERNAME: budibase
+ COUCH_DB_PASSWORD: ${BB_COUCHDB_PASSWORD}
+ COUCH_DB_URL: http://budibase:${BB_COUCHDB_PASSWORD}@couchdb:5984
+ BUDIBASE_ENVIRONMENT: ${BUDIBASE_ENVIRONMENT:-PRODUCTION}
+ ENABLE_ANALYTICS: ${ENABLE_ANALYTICS:-true}
+ BB_ADMIN_USER_EMAIL: ''
+ BB_ADMIN_USER_PASSWORD: ''
+ depends_on:
+ worker:
+ condition: service_healthy
+ redis:
+ condition: service_healthy
+ healthcheck:
+ test:
+ - CMD
+ - wget
+ - '--spider'
+ - '-qO-'
+ - 'http://localhost:4002/health'
+ interval: 15s
+ timeout: 15s
+ retries: 5
+ start_period: 10s
+ worker:
+ image: budibase.docker.scarf.sh/budibase/worker:3.2.25
+ restart: unless-stopped
+
+ environment:
+ SELF_HOSTED: 1
+ LOG_LEVEL: info
+ PORT: 4003
+ CLUSTER_PORT: 10000
+ INTERNAL_API_KEY: ${BB_INTERNAL_API_KEY}
+ API_ENCRYPTION_KEY: ${BB_API_ENCRYPTION_KEY}
+ JWT_SECRET: ${BB_JWT_SECRET}
+ MINIO_ACCESS_KEY: ${BB_MINIO_ACCESS_KEY}
+ MINIO_SECRET_KEY: ${BB_MINIO_SECRET_KEY}
+ APPS_URL: http://apps:4002
+ MINIO_URL: http://minio:9000
+ REDIS_URL: redis:6379
+ REDIS_PASSWORD: ${BB_REDIS_PASSWORD}
+ COUCH_DB_USERNAME: budibase
+ COUCH_DB_PASSWORD: ${BB_COUCHDB_PASSWORD}
+ COUCH_DB_URL: http://budibase:${BB_COUCHDB_PASSWORD}@couchdb:5984
+ BUDIBASE_ENVIRONMENT: ${BUDIBASE_ENVIRONMENT:-PRODUCTION}
+ ENABLE_ANALYTICS: ${ENABLE_ANALYTICS:-true}
+ depends_on:
+ redis:
+ condition: service_healthy
+ minio:
+ condition: service_healthy
+ healthcheck:
+ test:
+ - CMD
+ - wget
+ - '--spider'
+ - '-qO-'
+ - 'http://localhost:4003/health'
+ interval: 15s
+ timeout: 15s
+ retries: 5
+ start_period: 10s
+ minio:
+ image: minio/minio:RELEASE.2024-11-07T00-52-20Z
+ restart: unless-stopped
+
+ volumes:
+ - 'minio_data:/data'
+ environment:
+ MINIO_ROOT_USER: ${BB_MINIO_ACCESS_KEY}
+ MINIO_ROOT_PASSWORD: ${BB_MINIO_SECRET_KEY}
+ MINIO_BROWSER: off
+ command: 'server /data --console-address ":9001"'
+ healthcheck:
+ test:
+ - CMD
+ - curl
+ - '-f'
+ - 'http://localhost:9000/minio/health/live'
+ interval: 30s
+ timeout: 20s
+ retries: 3
+ proxy:
+ image: budibase/proxy:3.2.25
+ restart: unless-stopped
+
+ environment:
+ PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND: 10
+ PROXY_RATE_LIMIT_API_PER_SECOND: 20
+ APPS_UPSTREAM_URL: http://apps:4002
+ WORKER_UPSTREAM_URL: http://worker:4003
+ MINIO_UPSTREAM_URL: http://minio:9000
+ COUCHDB_UPSTREAM_URL: http://couchdb:5984
+ WATCHTOWER_UPSTREAM_URL: http://watchtower:8080
+ RESOLVER: 127.0.0.11
+ depends_on:
+ minio:
+ condition: service_healthy
+ worker:
+ condition: service_healthy
+ apps:
+ condition: service_healthy
+ couchdb:
+ condition: service_healthy
+ healthcheck:
+ test:
+ - CMD
+ - curl
+ - '-f'
+ - 'http://localhost:10000/'
+ interval: 15s
+ timeout: 15s
+ retries: 5
+ start_period: 10s
+ couchdb:
+ image: budibase/couchdb:v3.3.3
+ restart: unless-stopped
+
+ environment:
+ COUCHDB_USER: budibase
+ COUCHDB_PASSWORD: ${BB_COUCHDB_PASSWORD}
+ TARGETBUILD: docker-compose
+ healthcheck:
+ test:
+ - CMD
+ - curl
+ - '-f'
+ - 'http://localhost:5984/'
+ interval: 15s
+ timeout: 15s
+ retries: 5
+ start_period: 10s
+ volumes:
+ - 'couchdb3_data:/opt/couchdb/data'
+ redis:
+ image: redis:7.2-alpine
+
+ restart: unless-stopped
+ command: 'redis-server --requirepass "${BB_REDIS_PASSWORD}"'
+ volumes:
+ - 'redis_data:/data'
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - '-a'
+ - ${BB_REDIS_PASSWORD}
+ - ping
+ interval: 15s
+ timeout: 15s
+ retries: 5
+ start_period: 10s
+ watchtower:
+ restart: unless-stopped
+
+ image: containrrr/watchtower:1.7.1
+ volumes:
+ - '/var/run/docker.sock:/var/run/docker.sock'
+ command: '--debug --http-api-update bbapps bbworker bbproxy'
+ environment:
+ WATCHTOWER_HTTP_API: true
+ WATCHTOWER_HTTP_API_TOKEN: ${BB_WATCHTOWER_PASSWORD}
+ WATCHTOWER_CLEANUP: true
+ labels:
+ - com.centurylinklabs.watchtower.enable=false
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ minio_data:
+ couchdb3_data:
+ redis_data:
\ No newline at end of file
diff --git a/blueprints/budibase/template.yml b/blueprints/budibase/template.yml
new file mode 100644
index 000000000..29641fd4d
--- /dev/null
+++ b/blueprints/budibase/template.yml
@@ -0,0 +1,29 @@
+variables:
+ main_domain: ${domain}
+ api_key: ${password:32}
+ encryption_key: ${password:32}
+ jwt_secret: ${password:32}
+ couchdb_password: ${password:32}
+ redis_password: ${password:32}
+ minio_access_key: ${password:32}
+ minio_secret_key: ${password:32}
+ watchtower_password: ${password:32}
+
+config:
+ domains:
+ - serviceName: proxy
+ port: 10000
+ host: ${main_domain}
+
+ env:
+ - BB_HOST=${main_domain}
+ - BB_INTERNAL_API_KEY=${api_key}
+ - BB_API_ENCRYPTION_KEY=${encryption_key}
+ - BB_JWT_SECRET=${jwt_secret}
+ - BB_COUCHDB_PASSWORD=${couchdb_password}
+ - BB_REDIS_PASSWORD=${redis_password}
+ - BB_WATCHTOWER_PASSWORD=${watchtower_password}
+ - BB_MINIO_ACCESS_KEY=${minio_access_key}
+ - BB_MINIO_SECRET_KEY=${minio_secret_key}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/calcom/calcom.jpg b/blueprints/calcom/calcom.jpg
new file mode 100644
index 000000000..0f7da95d1
Binary files /dev/null and b/blueprints/calcom/calcom.jpg differ
diff --git a/blueprints/calcom/docker-compose.yml b/blueprints/calcom/docker-compose.yml
new file mode 100644
index 000000000..a309a1da4
--- /dev/null
+++ b/blueprints/calcom/docker-compose.yml
@@ -0,0 +1,25 @@
+services:
+ postgres:
+ image: postgres:16-alpine
+
+ volumes:
+ - calcom-data:/var/lib/postgresql/data
+ environment:
+ - POSTGRES_USER=postgres
+ - POSTGRES_PASSWORD=password
+ - POSTGRES_DB=db
+ - DATABASE_URL=postgres://postgres:password@postgres:5432/db
+
+ calcom:
+ image: calcom/cal.com:v2.7.6
+ depends_on:
+ - postgres
+ environment:
+ - NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
+ - CALENDSO_ENCRYPTION_KEY=${CALENDSO_ENCRYPTION_KEY}
+ - DATABASE_URL=postgres://postgres:password@postgres:5432/db
+ - NEXT_PUBLIC_WEBAPP_URL=http://${CALCOM_HOST}
+ - NEXTAUTH_URL=http://${CALCOM_HOST}/api/auth
+
+volumes:
+ calcom-data:
diff --git a/blueprints/calcom/template.yml b/blueprints/calcom/template.yml
new file mode 100644
index 000000000..5ea19afbb
--- /dev/null
+++ b/blueprints/calcom/template.yml
@@ -0,0 +1,17 @@
+variables:
+ main_domain: ${domain}
+ calcom_encryption_key: ${base64:32}
+ nextauth_secret: ${base64:32}
+
+config:
+ domains:
+ - serviceName: calcom
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - CALCOM_HOST=${main_domain}
+ - NEXTAUTH_SECRET=${nextauth_secret}
+ - CALENDSO_ENCRYPTION_KEY=${calcom_encryption_key}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/chatwoot/chatwoot.svg b/blueprints/chatwoot/chatwoot.svg
new file mode 100644
index 000000000..56c9a7b8f
--- /dev/null
+++ b/blueprints/chatwoot/chatwoot.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/blueprints/chatwoot/docker-compose.yml b/blueprints/chatwoot/docker-compose.yml
new file mode 100644
index 000000000..b24ca0b56
--- /dev/null
+++ b/blueprints/chatwoot/docker-compose.yml
@@ -0,0 +1,74 @@
+version: '3'
+
+x-base-config: &base-config
+ image: chatwoot/chatwoot:v3.14.1
+ volumes:
+ - chatwoot-storage:/app/storage
+ networks:
+ - dokploy-network
+ environment:
+ - FRONTEND_URL=${FRONTEND_URL}
+ - SECRET_KEY_BASE=${SECRET_KEY_BASE}
+ - RAILS_ENV=${RAILS_ENV}
+ - NODE_ENV=${NODE_ENV}
+ - INSTALLATION_ENV=${INSTALLATION_ENV}
+ - RAILS_LOG_TO_STDOUT=${RAILS_LOG_TO_STDOUT}
+ - LOG_LEVEL=${LOG_LEVEL}
+ - DEFAULT_LOCALE=${DEFAULT_LOCALE}
+ - POSTGRES_HOST=${POSTGRES_HOST}
+ - POSTGRES_PORT=${POSTGRES_PORT}
+ - POSTGRES_DATABASE=${POSTGRES_DATABASE}
+ - POSTGRES_USERNAME=${POSTGRES_USERNAME}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+ - REDIS_URL=${REDIS_URL}
+ - ENABLE_ACCOUNT_SIGNUP=${ENABLE_ACCOUNT_SIGNUP}
+ - ACTIVE_STORAGE_SERVICE=${ACTIVE_STORAGE_SERVICE}
+
+services:
+ chatwoot-rails:
+ <<: *base-config
+ depends_on:
+ chatwoot-postgres:
+ condition: service_started
+ chatwoot-redis:
+ condition: service_started
+ entrypoint: docker/entrypoints/rails.sh
+ command: ['bundle', 'exec', 'sh', '-c', 'rails db:chatwoot_prepare && rails s -p 3000 -b 0.0.0.0']
+ restart: always
+
+ chatwoot-sidekiq:
+ <<: *base-config
+ depends_on:
+ chatwoot-postgres:
+ condition: service_started
+ chatwoot-redis:
+ condition: service_started
+ command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml']
+ restart: always
+
+ chatwoot-postgres:
+ image: postgres:12
+ restart: always
+ volumes:
+ - chatwoot-postgres-data:/var/lib/postgresql/data
+
+ environment:
+ - POSTGRES_DB=${POSTGRES_DATABASE}
+ - POSTGRES_USER=${POSTGRES_USERNAME}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+
+ chatwoot-redis:
+ image: redis:alpine
+ restart: always
+ volumes:
+ - chatwoot-redis-data:/data
+
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ chatwoot-storage:
+ chatwoot-postgres-data:
+ chatwoot-redis-data:
\ No newline at end of file
diff --git a/blueprints/chatwoot/template.yml b/blueprints/chatwoot/template.yml
new file mode 100644
index 000000000..ac706235a
--- /dev/null
+++ b/blueprints/chatwoot/template.yml
@@ -0,0 +1,30 @@
+variables:
+ main_domain: ${domain}
+ secret_key_base: ${base64:64}
+ postgres_password: ${password}
+
+config:
+ domains:
+ - serviceName: chatwoot-rails
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - FRONTEND_URL=http://${main_domain}
+ - SECRET_KEY_BASE=${secret_key_base}
+ - RAILS_ENV=production
+ - NODE_ENV=production
+ - INSTALLATION_ENV=docker
+ - RAILS_LOG_TO_STDOUT=true
+ - LOG_LEVEL=info
+ - DEFAULT_LOCALE=en
+ - POSTGRES_HOST=chatwoot-postgres
+ - POSTGRES_PORT=5432
+ - POSTGRES_DATABASE=chatwoot
+ - POSTGRES_USERNAME=postgres
+ - POSTGRES_PASSWORD=${postgres_password}
+ - REDIS_URL=redis://chatwoot-redis:6379
+ - ENABLE_ACCOUNT_SIGNUP=false
+ - ACTIVE_STORAGE_SERVICE=local
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/checkmate/checkmate.png b/blueprints/checkmate/checkmate.png
new file mode 100644
index 000000000..759269ba8
Binary files /dev/null and b/blueprints/checkmate/checkmate.png differ
diff --git a/blueprints/checkmate/docker-compose.yml b/blueprints/checkmate/docker-compose.yml
new file mode 100644
index 000000000..7a5fc8984
--- /dev/null
+++ b/blueprints/checkmate/docker-compose.yml
@@ -0,0 +1,42 @@
+services:
+ client:
+ image: bluewaveuptime/uptime_client:latest
+ restart: always
+ environment:
+ UPTIME_APP_API_BASE_URL: "http://${DOMAIN}/api/v1"
+ ports:
+ - 80
+ - 443
+ depends_on:
+ - server
+
+ server:
+ image: bluewaveuptime/uptime_server:latest
+ restart: always
+ ports:
+ - 5000
+ depends_on:
+ - redis
+ - mongodb
+ environment:
+ - DB_CONNECTION_STRING=mongodb://mongodb:27017/uptime_db
+ - REDIS_HOST=redis
+
+ # volumes:
+ # - /var/run/docker.sock:/var/run/docker.sock:ro
+ redis:
+ image: bluewaveuptime/uptime_redis:latest
+ restart: always
+ ports:
+ - 6379
+ volumes:
+ - ../files/redis/data:/data
+
+ mongodb:
+ image: bluewaveuptime/uptime_database_mongo:latest
+ restart: always
+ volumes:
+ - ../files/mongo/data:/data/db
+ command: ["mongod", "--quiet"]
+ ports:
+ - 27017
diff --git a/blueprints/checkmate/template.yml b/blueprints/checkmate/template.yml
new file mode 100644
index 000000000..fb9b72049
--- /dev/null
+++ b/blueprints/checkmate/template.yml
@@ -0,0 +1,13 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: client
+ port: 80
+ host: ${main_domain}
+
+ env:
+ - DOMAIN=${main_domain}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/cloudflared/cloudflared.svg b/blueprints/cloudflared/cloudflared.svg
new file mode 100644
index 000000000..5be105f51
--- /dev/null
+++ b/blueprints/cloudflared/cloudflared.svg
@@ -0,0 +1,33 @@
+
+
+
\ No newline at end of file
diff --git a/blueprints/cloudflared/docker-compose.yml b/blueprints/cloudflared/docker-compose.yml
new file mode 100644
index 000000000..d9fc27419
--- /dev/null
+++ b/blueprints/cloudflared/docker-compose.yml
@@ -0,0 +1,18 @@
+services:
+ cloudflared:
+ image: 'cloudflare/cloudflared:latest'
+ environment:
+ # Don't forget to set this in your Dokploy Environment
+ - 'TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}'
+ network_mode: host
+ restart: unless-stopped
+ command: [
+ "tunnel",
+
+ # More tunnel run parameters here:
+ # https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/configure-tunnels/tunnel-run-parameters/
+ "--no-autoupdate",
+ #"--protocol", "http2",
+
+ "run"
+ ]
diff --git a/blueprints/cloudflared/template.yml b/blueprints/cloudflared/template.yml
new file mode 100644
index 000000000..277fe8d19
--- /dev/null
+++ b/blueprints/cloudflared/template.yml
@@ -0,0 +1,9 @@
+variables: {}
+
+config:
+ domains: []
+
+ env:
+ - CLOUDFLARE_TUNNEL_TOKEN=""
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/coder/coder.svg b/blueprints/coder/coder.svg
new file mode 100644
index 000000000..56d2f77c3
--- /dev/null
+++ b/blueprints/coder/coder.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blueprints/coder/docker-compose.yml b/blueprints/coder/docker-compose.yml
new file mode 100644
index 000000000..875c7ae81
--- /dev/null
+++ b/blueprints/coder/docker-compose.yml
@@ -0,0 +1,37 @@
+services:
+ coder:
+ image: ghcr.io/coder/coder:v2.15.3
+
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ group_add:
+ - "998"
+ depends_on:
+ db:
+ condition: service_healthy
+ environment:
+ - CODER_ACCESS_URL
+ - CODER_HTTP_ADDRESS
+ - CODER_PG_CONNECTION_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db/${POSTGRES_DB}?sslmode=disable
+
+ db:
+ image: postgres:17
+
+ environment:
+ - POSTGRES_PASSWORD
+ - POSTGRES_USER
+ - POSTGRES_DB
+ healthcheck:
+ test:
+ [
+ "CMD-SHELL",
+ "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}",
+ ]
+ interval: 5s
+ timeout: 5s
+ retries: 5
+ volumes:
+ - db_coder_data:/var/lib/postgresql/data
+
+volumes:
+ db_coder_data:
\ No newline at end of file
diff --git a/blueprints/coder/template.yml b/blueprints/coder/template.yml
new file mode 100644
index 000000000..cd230caec
--- /dev/null
+++ b/blueprints/coder/template.yml
@@ -0,0 +1,18 @@
+variables:
+ main_domain: ${domain}
+ postgres_password: ${password}
+
+config:
+ domains:
+ - serviceName: coder
+ port: 7080
+ host: ${main_domain}
+
+ env:
+ - CODER_ACCESS_URL=
+ - CODER_HTTP_ADDRESS=0.0.0.0:7080
+ - POSTGRES_DB=coder
+ - POSTGRES_USER=coder
+ - POSTGRES_PASSWORD=${postgres_password}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/conduit/conduit.svg b/blueprints/conduit/conduit.svg
new file mode 100644
index 000000000..aa7a352c1
--- /dev/null
+++ b/blueprints/conduit/conduit.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/conduit/docker-compose.yml b/blueprints/conduit/docker-compose.yml
new file mode 100644
index 000000000..f2f1fb340
--- /dev/null
+++ b/blueprints/conduit/docker-compose.yml
@@ -0,0 +1,31 @@
+# From Conduit's official documentation: https://docs.conduit.rs/deploying/docker.html#docker-compose
+version: '3'
+
+services:
+ homeserver:
+ image: registry.gitlab.com/famedly/conduit/matrix-conduit:v0.9.0
+ restart: unless-stopped
+ volumes:
+ - db:/var/lib/matrix-conduit/
+ networks:
+ - dokploy-network
+ environment:
+ CONDUIT_SERVER_NAME: ${MATRIX_SUBDOMAIN}
+ CONDUIT_DATABASE_PATH: /var/lib/matrix-conduit/
+ CONDUIT_DATABASE_BACKEND: rocksdb
+ CONDUIT_PORT: 6167
+ CONDUIT_MAX_REQUEST_SIZE: 20000000 # in bytes, ~20 MB
+ CONDUIT_ALLOW_REGISTRATION: 'true'
+ #CONDUIT_REGISTRATION_TOKEN: '' # require password for registration
+ CONDUIT_ALLOW_FEDERATION: 'true'
+ CONDUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
+ CONDUIT_TRUSTED_SERVERS: '["matrix.org"]'
+ #CONDUIT_MAX_CONCURRENT_REQUESTS: 100
+ CONDUIT_ADDRESS: 0.0.0.0
+ CONDUIT_CONFIG: '' # Ignore this
+volumes:
+ db:
+
+networks:
+ dokploy-network:
+ external: true
diff --git a/blueprints/conduit/template.yml b/blueprints/conduit/template.yml
new file mode 100644
index 000000000..c279a0e04
--- /dev/null
+++ b/blueprints/conduit/template.yml
@@ -0,0 +1,13 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: homeserver
+ port: 6167
+ host: ${main_domain}
+
+ env:
+ - MATRIX_SUBDOMAIN=${main_domain}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/conduwuit/conduwuit.svg b/blueprints/conduwuit/conduwuit.svg
new file mode 100644
index 000000000..162a3d9e3
--- /dev/null
+++ b/blueprints/conduwuit/conduwuit.svg
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
diff --git a/blueprints/conduwuit/docker-compose.yml b/blueprints/conduwuit/docker-compose.yml
new file mode 100644
index 000000000..7945d6c97
--- /dev/null
+++ b/blueprints/conduwuit/docker-compose.yml
@@ -0,0 +1,48 @@
+# conduwuit
+# https://conduwuit.puppyirl.gay/deploying/docker-compose.yml
+
+services:
+ homeserver:
+ image: girlbossceo/conduwuit:latest
+ restart: unless-stopped
+ ports:
+ - 8448:6167
+ volumes:
+ - db:/var/lib/conduwuit
+ #- ./conduwuit.toml:/etc/conduwuit.toml
+ environment:
+ # Edit this in your Dokploy Environment
+ CONDUWUIT_SERVER_NAME: ${CONDUWUIT_SERVER_NAME}
+
+ CONDUWUIT_DATABASE_PATH: /var/lib/conduwuit
+ CONDUWUIT_PORT: 6167
+ CONDUWUIT_MAX_REQUEST_SIZE: 20000000 # in bytes, ~20 MB
+
+ CONDUWUIT_ALLOW_REGISTRATION: 'true'
+ CONDUWUIT_REGISTRATION_TOKEN: ${CONDUWUIT_REGISTRATION_TOKEN}
+
+ CONDUWUIT_ALLOW_FEDERATION: 'true'
+ CONDUWUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
+ CONDUWUIT_TRUSTED_SERVERS: '["matrix.org"]'
+ #CONDUWUIT_LOG: warn,state_res=warn
+ CONDUWUIT_ADDRESS: 0.0.0.0
+
+ # Uncomment if you mapped config toml in volumes
+ #CONDUWUIT_CONFIG: '/etc/conduwuit.toml'
+
+ ### Uncomment if you want to use your own Element-Web App.
+ ### Note: You need to provide a config.json for Element and you also need a second
+ ### Domain or Subdomain for the communication between Element and conduwuit
+ ### Config-Docs: https://github.com/vector-im/element-web/blob/develop/docs/config.md
+ # element-web:
+ # image: vectorim/element-web:latest
+ # restart: unless-stopped
+ # ports:
+ # - 8009:80
+ # volumes:
+ # - ./element_config.json:/app/config.json
+ # depends_on:
+ # - homeserver
+
+volumes:
+ db:
diff --git a/blueprints/conduwuit/template.yml b/blueprints/conduwuit/template.yml
new file mode 100644
index 000000000..96295e8cb
--- /dev/null
+++ b/blueprints/conduwuit/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+ registration_token: ${password:20}
+
+config:
+ domains:
+ - serviceName: homeserver
+ port: 6167
+ host: ${main_domain}
+
+ env:
+ - CONDUWUIT_SERVER_NAME=${main_domain}
+ - CONDUWUIT_REGISTRATION_TOKEN=${registration_token}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/convex/convex.svg b/blueprints/convex/convex.svg
new file mode 100644
index 000000000..8622c4c07
--- /dev/null
+++ b/blueprints/convex/convex.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/blueprints/convex/docker-compose.yml b/blueprints/convex/docker-compose.yml
new file mode 100644
index 000000000..12e2b5ada
--- /dev/null
+++ b/blueprints/convex/docker-compose.yml
@@ -0,0 +1,37 @@
+services:
+ backend:
+ image: ghcr.io/get-convex/convex-backend:6c974d219776b753cd23d26f4a296629ff7c2cad
+ ports:
+ - "${PORT:-3210}:3210"
+ - "${SITE_PROXY_PORT:-3211}:3211"
+ volumes:
+ - data:/convex/data
+ environment:
+ - INSTANCE_NAME=${INSTANCE_NAME:-}
+ - INSTANCE_SECRET=${INSTANCE_SECRET:-}
+ - CONVEX_RELEASE_VERSION_DEV=${CONVEX_RELEASE_VERSION_DEV:-}
+ - ACTIONS_USER_TIMEOUT_SECS=${ACTIONS_USER_TIMEOUT_SECS:-}
+ - CONVEX_CLOUD_ORIGIN=${CONVEX_CLOUD_ORIGIN:-http://127.0.0.1:3210}
+ - CONVEX_SITE_ORIGIN=${CONVEX_SITE_ORIGIN:-http://127.0.0.1:3211}
+ - DATABASE_URL=${DATABASE_URL:-}
+ - DISABLE_BEACON=${DISABLE_BEACON:-}
+ - REDACT_LOGS_TO_CLIENT=${REDACT_LOGS_TO_CLIENT:-}
+ - RUST_LOG=${RUST_LOG:-info}
+ - RUST_BACKTRACE=${RUST_BACKTRACE:-}
+ healthcheck:
+ test: curl -f http://localhost:3210/version
+ interval: 5s
+ start_period: 5s
+
+ dashboard:
+ image: ghcr.io/get-convex/convex-dashboard:4499dd4fd7f2148687a7774599c613d052950f46
+ ports:
+ - "${DASHBOARD_PORT:-6791}:6791"
+ environment:
+ - NEXT_PUBLIC_DEPLOYMENT_URL=${NEXT_PUBLIC_DEPLOYMENT_URL:-http://127.0.0.1:3210}
+ depends_on:
+ backend:
+ condition: service_healthy
+
+volumes:
+ data:
diff --git a/blueprints/convex/template.yml b/blueprints/convex/template.yml
new file mode 100644
index 000000000..4f39ce5ff
--- /dev/null
+++ b/blueprints/convex/template.yml
@@ -0,0 +1,23 @@
+variables:
+ dashboard_domain: ${domain}
+ backend_domain: ${domain}
+ actions_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: dashboard
+ port: 6791
+ host: ${dashboard_domain}
+ - serviceName: backend
+ port: 3210
+ host: ${backend_domain}
+ - serviceName: backend
+ port: 3211
+ host: ${actions_domain}
+
+ env:
+ - NEXT_PUBLIC_DEPLOYMENT_URL=http://${backend_domain}
+ - CONVEX_CLOUD_ORIGIN=http://${backend_domain}
+ - CONVEX_SITE_ORIGIN=http://${actions_domain}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/couchdb/couchdb.png b/blueprints/couchdb/couchdb.png
new file mode 100644
index 000000000..7dc4cc4af
Binary files /dev/null and b/blueprints/couchdb/couchdb.png differ
diff --git a/blueprints/couchdb/docker-compose.yml b/blueprints/couchdb/docker-compose.yml
new file mode 100644
index 000000000..cb00bf69d
--- /dev/null
+++ b/blueprints/couchdb/docker-compose.yml
@@ -0,0 +1,17 @@
+version: '3.8'
+
+services:
+ couchdb:
+ image: couchdb:latest
+ ports:
+ - '5984'
+ volumes:
+ - couchdb-data:/opt/couchdb/data
+ environment:
+ - COUCHDB_USER=${COUCHDB_USER}
+ - COUCHDB_PASSWORD=${COUCHDB_PASSWORD}
+ restart: unless-stopped
+
+volumes:
+ couchdb-data:
+ driver: local
diff --git a/blueprints/couchdb/template.yml b/blueprints/couchdb/template.yml
new file mode 100644
index 000000000..1e90152f4
--- /dev/null
+++ b/blueprints/couchdb/template.yml
@@ -0,0 +1,16 @@
+variables:
+ main_domain: ${domain}
+ username: ${password:16}
+ password: ${password:32}
+
+config:
+ domains:
+ - serviceName: couchdb
+ port: 5984
+ host: ${main_domain}
+
+ env:
+ - COUCHDB_USER=${username}
+ - COUCHDB_PASSWORD=${password}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/datalens/datalens.svg b/blueprints/datalens/datalens.svg
new file mode 100644
index 000000000..64954e313
--- /dev/null
+++ b/blueprints/datalens/datalens.svg
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/datalens/docker-compose.yml b/blueprints/datalens/docker-compose.yml
new file mode 100644
index 000000000..94839e04b
--- /dev/null
+++ b/blueprints/datalens/docker-compose.yml
@@ -0,0 +1,96 @@
+services:
+ pg-compeng:
+ image: postgres:16-alpine
+ restart: always
+ environment:
+ POSTGRES_PASSWORD: "postgres"
+ POSTGRES_DB: postgres
+ POSTGRES_USER: postgres
+
+ control-api:
+ image: ghcr.io/datalens-tech/datalens-control-api:0.2192.0
+ restart: always
+ environment:
+ BI_API_UWSGI_WORKERS_COUNT: 4
+ CONNECTOR_AVAILABILITY_VISIBLE: "clickhouse,postgres,chyt,ydb,mysql,greenplum,mssql,appmetrica_api,metrika_api"
+ RQE_FORCE_OFF: 1
+ DL_CRY_ACTUAL_KEY_ID: key_1
+ DL_CRY_KEY_VAL_ID_key_1: "h1ZpilcYLYRdWp7Nk8X1M1kBPiUi8rdjz9oBfHyUKIk="
+ RQE_SECRET_KEY: ""
+ US_HOST: "http://us:8083"
+ US_MASTER_TOKEN: "fake-us-master-token"
+ depends_on:
+ - us
+
+ data-api:
+ container_name: datalens-data-api
+ image: ghcr.io/datalens-tech/datalens-data-api:0.2192.0
+ restart: always
+ environment:
+ GUNICORN_WORKERS_COUNT: 5
+ RQE_FORCE_OFF: 1
+ CACHES_ON: 0
+ MUTATIONS_CACHES_ON: 0
+ RQE_SECRET_KEY: ""
+ DL_CRY_ACTUAL_KEY_ID: key_1
+ DL_CRY_KEY_VAL_ID_key_1: "h1ZpilcYLYRdWp7Nk8X1M1kBPiUi8rdjz9oBfHyUKIk="
+ BI_COMPENG_PG_ON: 1
+ BI_COMPENG_PG_URL: "postgresql://postgres:postgres@pg-compeng:5432/postgres"
+ US_HOST: "http://us:8083"
+ US_MASTER_TOKEN: "fake-us-master-token"
+ depends_on:
+ - us
+ - pg-compeng
+
+ pg-us:
+ container_name: datalens-pg-us
+ image: postgres:16-alpine
+ restart: always
+ environment:
+ POSTGRES_DB: us-db-ci_purgeable
+ POSTGRES_USER: us
+ POSTGRES_PASSWORD: us
+ volumes:
+ - ${VOLUME_US:-./metadata}:/var/lib/postgresql/data
+
+ us:
+ image: ghcr.io/datalens-tech/datalens-us:0.310.0
+ restart: always
+ depends_on:
+ - pg-us
+ environment:
+ APP_INSTALLATION: "opensource"
+ APP_ENV: "prod"
+ MASTER_TOKEN: "fake-us-master-token"
+ POSTGRES_DSN_LIST: ${METADATA_POSTGRES_DSN_LIST:-postgres://us:us@pg-us:5432/us-db-ci_purgeable}
+ SKIP_INSTALL_DB_EXTENSIONS: ${METADATA_SKIP_INSTALL_DB_EXTENSIONS:-0}
+ USE_DEMO_DATA: ${USE_DEMO_DATA:-0}
+ HC: ${HC:-0}
+ NODE_EXTRA_CA_CERTS: /certs/root.crt
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
+ volumes:
+ - ./certs:/certs
+
+ datalens:
+ image: ghcr.io/datalens-tech/datalens-ui:0.2601.0
+ restart: always
+ ports:
+ - ${UI_PORT:-8080}:8080
+ depends_on:
+ - us
+ - control-api
+ - data-api
+ environment:
+ APP_MODE: "full"
+ APP_ENV: "production"
+ APP_INSTALLATION: "opensource"
+ AUTH_POLICY: "disabled"
+ US_ENDPOINT: "http://us:8083"
+ BI_API_ENDPOINT: "http://control-api:8080"
+ BI_DATA_ENDPOINT: "http://data-api:8080"
+ US_MASTER_TOKEN: "fake-us-master-token"
+ NODE_EXTRA_CA_CERTS: "/usr/local/share/ca-certificates/cert.pem"
+ HC: ${HC:-0}
+ YANDEX_MAP_ENABLED: ${YANDEX_MAP_ENABLED:-0}
+ YANDEX_MAP_TOKEN: ${YANDEX_MAP_TOKEN:-0}
diff --git a/blueprints/datalens/template.yml b/blueprints/datalens/template.yml
new file mode 100644
index 000000000..d2d7a8c00
--- /dev/null
+++ b/blueprints/datalens/template.yml
@@ -0,0 +1,13 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: datalens
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ - HC=1
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/directus/directus.jpg b/blueprints/directus/directus.jpg
new file mode 100644
index 000000000..a6f550627
Binary files /dev/null and b/blueprints/directus/directus.jpg differ
diff --git a/blueprints/directus/docker-compose.yml b/blueprints/directus/docker-compose.yml
new file mode 100644
index 000000000..52e64baf6
--- /dev/null
+++ b/blueprints/directus/docker-compose.yml
@@ -0,0 +1,64 @@
+services:
+ database:
+ image: postgis/postgis:13-master
+ volumes:
+ - directus_database:/var/lib/postgresql/data
+
+ environment:
+ POSTGRES_USER: "directus"
+ POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
+ POSTGRES_DB: "directus"
+ healthcheck:
+ test: ["CMD", "pg_isready", "--host=localhost", "--username=directus"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ start_interval: 5s
+ start_period: 30s
+
+ cache:
+ image: redis:6
+ healthcheck:
+ test: ["CMD-SHELL", "[ $$(redis-cli ping) = 'PONG' ]"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ start_interval: 5s
+ start_period: 30s
+
+
+ directus:
+ image: directus/directus:11.0.2
+ ports:
+ - 8055
+ volumes:
+ - directus_uploads:/directus/uploads
+ - directus_extensions:/directus/extensions
+ depends_on:
+ database:
+ condition: service_healthy
+ cache:
+ condition: service_healthy
+ environment:
+ SECRET: ${DIRECTUS_SECRET}
+
+ DB_CLIENT: "pg"
+ DB_HOST: "database"
+ DB_PORT: "5432"
+ DB_DATABASE: "directus"
+ DB_USER: "directus"
+ DB_PASSWORD: ${DATABASE_PASSWORD}
+
+ CACHE_ENABLED: "true"
+ CACHE_AUTO_PURGE: "true"
+ CACHE_STORE: "redis"
+ REDIS: "redis://cache:6379"
+
+ # After first successful login, remove the admin email/password env. variables below
+ # as these will now be stored in the database.
+ ADMIN_EMAIL: "admin@example.com"
+ ADMIN_PASSWORD: "d1r3ctu5"
+volumes:
+ directus_uploads:
+ directus_extensions:
+ directus_database:
\ No newline at end of file
diff --git a/blueprints/directus/template.yml b/blueprints/directus/template.yml
new file mode 100644
index 000000000..93899ec3f
--- /dev/null
+++ b/blueprints/directus/template.yml
@@ -0,0 +1,16 @@
+variables:
+ main_domain: ${domain}
+ directus_secret: ${base64:64}
+ database_password: ${password}
+
+config:
+ domains:
+ - serviceName: directus
+ port: 8055
+ host: ${main_domain}
+
+ env:
+ - DATABASE_PASSWORD=${database_password}
+ - DIRECTUS_SECRET=${directus_secret}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/discord-tickets/discord-tickets.png b/blueprints/discord-tickets/discord-tickets.png
new file mode 100644
index 000000000..030c3a4ca
Binary files /dev/null and b/blueprints/discord-tickets/discord-tickets.png differ
diff --git a/blueprints/discord-tickets/docker-compose.yml b/blueprints/discord-tickets/docker-compose.yml
new file mode 100644
index 000000000..f797a77b0
--- /dev/null
+++ b/blueprints/discord-tickets/docker-compose.yml
@@ -0,0 +1,54 @@
+version: "3.8"
+
+services:
+ tickets-postgres:
+ image: mysql:8
+ restart: unless-stopped
+
+ volumes:
+ - tickets-mysql-data:/var/lib/mysql
+ environment:
+ MYSQL_DATABASE: ${MYSQL_DATABASE}
+ MYSQL_PASSWORD: ${MYSQL_PASSWORD}
+ MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
+ MYSQL_USER: ${MYSQL_USER}
+ healthcheck:
+ test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u${MYSQL_USER}", "-p${MYSQL_PASSWORD}"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+ tickets-app:
+ image: eartharoid/discord-tickets:4.0.21
+ depends_on:
+ tickets-postgres:
+ condition: service_healthy
+ restart: unless-stopped
+
+ volumes:
+ - tickets-app-data:/home/container/user
+ - /etc/timezone:/etc/timezone:ro
+ - /etc/localtime:/etc/localtime:ro
+ tty: true
+ stdin_open: true
+ environment:
+ DB_CONNECTION_URL: mysql://${MYSQL_USER}:${MYSQL_PASSWORD}@tickets-postgres/${MYSQL_DATABASE}
+ DISCORD_SECRET: ${DISCORD_SECRET}
+ DISCORD_TOKEN: ${DISCORD_TOKEN}
+ ENCRYPTION_KEY: ${ENCRYPTION_KEY}
+ DB_PROVIDER: mysql
+ HTTP_EXTERNAL: https://${TICKETS_HOST}
+ HTTP_HOST: 0.0.0.0
+ HTTP_PORT: 8169
+ HTTP_TRUST_PROXY: "true"
+ PUBLIC_BOT: "false"
+ PUBLISH_COMMANDS: "true"
+ SUPER: ${SUPER_USERS}
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ tickets-mysql-data:
+ tickets-app-data:
\ No newline at end of file
diff --git a/blueprints/discord-tickets/template.yml b/blueprints/discord-tickets/template.yml
new file mode 100644
index 000000000..bc5d95c1a
--- /dev/null
+++ b/blueprints/discord-tickets/template.yml
@@ -0,0 +1,27 @@
+variables:
+ main_domain: ${domain}
+ mysql_password: ${password}
+ mysql_root_password: ${password}
+ mysql_user: tickets
+ mysql_database: tickets
+ encryption_key: ${password:48}
+
+config:
+ domains:
+ - serviceName: tickets-app
+ port: 8169
+ host: ${main_domain}
+
+ env:
+ - TICKETS_HOST=${main_domain}
+ - MYSQL_DATABASE=${mysql_database}
+ - MYSQL_PASSWORD=${mysql_password}
+ - MYSQL_ROOT_PASSWORD=${mysql_root_password}
+ - MYSQL_USER=${mysql_user}
+ - ENCRYPTION_KEY=${encryption_key}
+ - "# Follow the guide at: https://discordtickets.app/self-hosting/installation/docker/#creating-the-discord-application"
+ - DISCORD_SECRET=
+ - DISCORD_TOKEN=
+ - SUPER_USERS=YOUR_DISCORD_USER_ID
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/discourse/discourse.svg b/blueprints/discourse/discourse.svg
new file mode 100644
index 000000000..4cbb8c87b
--- /dev/null
+++ b/blueprints/discourse/discourse.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/discourse/docker-compose.yml b/blueprints/discourse/docker-compose.yml
new file mode 100644
index 000000000..2b938b855
--- /dev/null
+++ b/blueprints/discourse/docker-compose.yml
@@ -0,0 +1,90 @@
+version: '3.7'
+
+services:
+ discourse-db:
+ image: docker.io/bitnami/postgresql:17
+
+ volumes:
+ - discourse-postgresql-data:/bitnami/postgresql
+ environment:
+ POSTGRESQL_USERNAME: bn_discourse
+ POSTGRESQL_PASSWORD: ${POSTGRES_PASSWORD}
+ POSTGRESQL_DATABASE: bitnami_discourse
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U bn_discourse -d bitnami_discourse"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ restart: unless-stopped
+
+ discourse-redis:
+ image: docker.io/bitnami/redis:7.4
+
+ volumes:
+ - discourse-redis-data:/bitnami/redis
+ environment:
+ REDIS_PASSWORD: ${REDIS_PASSWORD}
+ healthcheck:
+ test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ restart: unless-stopped
+
+ discourse-app:
+ image: docker.io/bitnami/discourse:3.3.2
+
+ volumes:
+ - discourse-data:/bitnami/discourse
+ depends_on:
+ discourse-db:
+ condition: service_healthy
+ discourse-redis:
+ condition: service_healthy
+ environment:
+ DISCOURSE_HOST: ${DISCOURSE_HOST}
+ DISCOURSE_DATABASE_HOST: discourse-db
+ DISCOURSE_DATABASE_PORT_NUMBER: 5432
+ DISCOURSE_DATABASE_USER: bn_discourse
+ DISCOURSE_DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
+ DISCOURSE_DATABASE_NAME: bitnami_discourse
+ DISCOURSE_REDIS_HOST: discourse-redis
+ DISCOURSE_REDIS_PORT_NUMBER: 6379
+ DISCOURSE_REDIS_PASSWORD: ${REDIS_PASSWORD}
+ # Optional: Configure SMTP for email delivery
+ # DISCOURSE_SMTP_HOST: ${SMTP_HOST}
+ # DISCOURSE_SMTP_PORT: ${SMTP_PORT}
+ # DISCOURSE_SMTP_USER: ${SMTP_USER}
+ # DISCOURSE_SMTP_PASSWORD: ${SMTP_PASSWORD}
+ restart: unless-stopped
+
+ discourse-sidekiq:
+ image: docker.io/bitnami/discourse:3.3.2
+
+ volumes:
+ - discourse-sidekiq-data:/bitnami/discourse
+ depends_on:
+ - discourse-app
+ command: /opt/bitnami/scripts/discourse-sidekiq/run.sh
+ environment:
+ DISCOURSE_HOST: ${DISCOURSE_HOST}
+ DISCOURSE_DATABASE_HOST: discourse-db
+ DISCOURSE_DATABASE_PORT_NUMBER: 5432
+ DISCOURSE_DATABASE_USER: bn_discourse
+ DISCOURSE_DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
+ DISCOURSE_DATABASE_NAME: bitnami_discourse
+ DISCOURSE_REDIS_HOST: discourse-redis
+ DISCOURSE_REDIS_PORT_NUMBER: 6379
+ DISCOURSE_REDIS_PASSWORD: ${REDIS_PASSWORD}
+ # Optional: Configure SMTP for email delivery
+ # DISCOURSE_SMTP_HOST: ${SMTP_HOST}
+ # DISCOURSE_SMTP_PORT: ${SMTP_PORT}
+ # DISCOURSE_SMTP_USER: ${SMTP_USER}
+ # DISCOURSE_SMTP_PASSWORD: ${SMTP_PASSWORD}
+ restart: unless-stopped
+
+volumes:
+ discourse-postgresql-data:
+ discourse-redis-data:
+ discourse-data:
+ discourse-sidekiq-data:
\ No newline at end of file
diff --git a/blueprints/discourse/template.yml b/blueprints/discourse/template.yml
new file mode 100644
index 000000000..565b0bec7
--- /dev/null
+++ b/blueprints/discourse/template.yml
@@ -0,0 +1,22 @@
+variables:
+ main_domain: ${domain}
+ postgres_password: ${password}
+ redis_password: ${password}
+
+config:
+ domains:
+ - serviceName: discourse-app
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - DISCOURSE_HOST=${main_domain}
+ - POSTGRES_PASSWORD=${postgres_password}
+ - REDIS_PASSWORD=${redis_password}
+ - # Optional: Configure SMTP for email delivery
+ - # SMTP_HOST=smtp.example.com
+ - # SMTP_PORT=587
+ - # SMTP_USER=your_smtp_user
+ - # SMTP_PASSWORD=your_smtp_password
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/docmost/docker-compose.yml b/blueprints/docmost/docker-compose.yml
new file mode 100644
index 000000000..b5995594b
--- /dev/null
+++ b/blueprints/docmost/docker-compose.yml
@@ -0,0 +1,44 @@
+version: "3"
+
+services:
+ docmost:
+ image: docmost/docmost:0.4.1
+ depends_on:
+ - db
+ - redis
+ environment:
+ - APP_URL
+ - APP_SECRET
+ - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public
+ - REDIS_URL=redis://redis:6379
+ restart: unless-stopped
+
+ volumes:
+ - docmost:/app/data/storage
+
+ db:
+ image: postgres:16-alpine
+ environment:
+ - POSTGRES_DB
+ - POSTGRES_USER
+ - POSTGRES_PASSWORD
+ restart: unless-stopped
+
+ volumes:
+ - db_docmost_data:/var/lib/postgresql/data
+
+ redis:
+ image: redis:7.2-alpine
+ restart: unless-stopped
+
+ volumes:
+ - redis_docmost_data:/data
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ docmost:
+ db_docmost_data:
+ redis_docmost_data:
\ No newline at end of file
diff --git a/blueprints/docmost/docmost.png b/blueprints/docmost/docmost.png
new file mode 100644
index 000000000..9bc8d2103
Binary files /dev/null and b/blueprints/docmost/docmost.png differ
diff --git a/blueprints/docmost/template.yml b/blueprints/docmost/template.yml
new file mode 100644
index 000000000..5aaebf000
--- /dev/null
+++ b/blueprints/docmost/template.yml
@@ -0,0 +1,19 @@
+variables:
+ main_domain: ${domain}
+ postgres_password: ${password}
+ app_secret: ${password}
+
+config:
+ domains:
+ - serviceName: docmost
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - POSTGRES_DB=docmost
+ - POSTGRES_USER=docmost
+ - POSTGRES_PASSWORD=${postgres_password}
+ - APP_URL=http://${main_domain}:3000
+ - APP_SECRET=${app_secret}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/documenso/docker-compose.yml b/blueprints/documenso/docker-compose.yml
new file mode 100644
index 000000000..9b8e8ed87
--- /dev/null
+++ b/blueprints/documenso/docker-compose.yml
@@ -0,0 +1,42 @@
+version: "3.8"
+services:
+ postgres:
+ image: postgres:16
+
+ volumes:
+ - documenso-data:/var/lib/postgresql/data
+ environment:
+ - POSTGRES_USER=documenso
+ - POSTGRES_PASSWORD=password
+ - POSTGRES_DB=documenso
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U documenso"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ start_period: 10s
+
+ documenso:
+ image: documenso/documenso:v1.5.6-rc.2
+ depends_on:
+ postgres:
+ condition: service_healthy
+ environment:
+ - PORT=${DOCUMENSO_PORT}
+ - NEXTAUTH_URL=http://${DOCUMENSO_HOST}
+ - NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
+ - NEXT_PRIVATE_ENCRYPTION_KEY=${NEXT_PRIVATE_ENCRYPTION_KEY}
+ - NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY=${NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY}
+ - NEXT_PUBLIC_WEBAPP_URL=http://${DOCUMENSO_HOST}
+ - NEXT_PRIVATE_DATABASE_URL=postgres://documenso:password@postgres:5432/documenso
+ - NEXT_PRIVATE_DIRECT_DATABASE_URL=postgres://documenso:password@postgres:5432/documenso
+ - NEXT_PUBLIC_UPLOAD_TRANSPORT=database
+ - NEXT_PRIVATE_SMTP_TRANSPORT=smtp-auth
+ - NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=/opt/documenso/cert.p12
+ ports:
+ - ${DOCUMENSO_PORT}
+ volumes:
+ - /opt/documenso/cert.p12:/opt/documenso/cert.p12
+
+volumes:
+ documenso-data:
diff --git a/blueprints/documenso/documenso.png b/blueprints/documenso/documenso.png
new file mode 100644
index 000000000..cb4765fcf
Binary files /dev/null and b/blueprints/documenso/documenso.png differ
diff --git a/blueprints/documenso/template.yml b/blueprints/documenso/template.yml
new file mode 100644
index 000000000..7cf744e27
--- /dev/null
+++ b/blueprints/documenso/template.yml
@@ -0,0 +1,20 @@
+variables:
+ main_domain: ${domain}
+ nextauth_secret: ${base64:32}
+ encryption_key: ${password:32}
+ secondary_encryption_key: ${password:64}
+
+config:
+ domains:
+ - serviceName: documenso
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - DOCUMENSO_HOST=${main_domain}
+ - DOCUMENSO_PORT=3000
+ - NEXTAUTH_SECRET=${nextauth_secret}
+ - NEXT_PRIVATE_ENCRYPTION_KEY=${encryption_key}
+ - NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY=${secondary_encryption_key}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/doublezero/docker-compose.yml b/blueprints/doublezero/docker-compose.yml
new file mode 100644
index 000000000..352470334
--- /dev/null
+++ b/blueprints/doublezero/docker-compose.yml
@@ -0,0 +1,19 @@
+services:
+ doublezero:
+ restart: always
+ image: liltechnomancer/double-zero:0.2.1
+ volumes:
+ - db-data:/var/lib/doublezero/data
+ environment:
+ AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
+ AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
+ AWS_REGION: ${AWS_REGION}
+ SQS_URL: ${SQS_URL}
+ SYSTEM_EMAIL: ${SYSTEM_EMAIL}
+ SECRET_KEY_BASE: ${SECRET_KEY_BASE}
+ PHX_HOST: ${DOUBLEZERO_HOST}
+ DATABASE_PATH: ./00.db
+
+volumes:
+ db-data:
+ driver: local
diff --git a/blueprints/doublezero/doublezero.svg b/blueprints/doublezero/doublezero.svg
new file mode 100644
index 000000000..e28cbeb09
--- /dev/null
+++ b/blueprints/doublezero/doublezero.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/blueprints/doublezero/template.yml b/blueprints/doublezero/template.yml
new file mode 100644
index 000000000..c6582de1c
--- /dev/null
+++ b/blueprints/doublezero/template.yml
@@ -0,0 +1,21 @@
+variables:
+ main_domain: ${domain}
+ secret_key_base: ${base64:64}
+
+config:
+ domains:
+ - serviceName: doublezero
+ port: 4000
+ host: ${main_domain}
+
+ env:
+ - DOUBLEZERO_HOST=${main_domain}
+ - DOUBLEZERO_PORT=4000
+ - SECRET_KEY_BASE=${secret_key_base}
+ - AWS_ACCESS_KEY_ID=your-aws-access-key
+ - AWS_SECRET_ACCESS_KEY=your-aws-secret-key
+ - AWS_REGION=your-aws-region
+ - SQS_URL=your-aws-sqs-url
+ - SYSTEM_EMAIL=
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/drawio/docker-compose.yml b/blueprints/drawio/docker-compose.yml
new file mode 100644
index 000000000..a7d7b578d
--- /dev/null
+++ b/blueprints/drawio/docker-compose.yml
@@ -0,0 +1,59 @@
+version: '3'
+services:
+ plantuml-server:
+ image: plantuml/plantuml-server
+ ports:
+ - "8080"
+
+ volumes:
+ - fonts_volume:/usr/share/fonts/drawio
+ image-export:
+ image: jgraph/export-server
+ ports:
+ - "8000"
+
+ volumes:
+ - fonts_volume:/usr/share/fonts/drawio
+ environment:
+ - DRAWIO_BASE_URL=${DRAWIO_BASE_URL}
+ drawio:
+ image: jgraph/drawio:24.7.17
+ ports:
+ - "8080"
+ links:
+ - plantuml-server:plantuml-server
+ - image-export:image-export
+ depends_on:
+ - plantuml-server
+ - image-export
+
+ environment:
+ RAWIO_SELF_CONTAINED: 1
+ DRAWIO_USE_HTTP: 1
+ PLANTUML_URL: http://plantuml-server:8080/
+ EXPORT_URL: http://image-export:8000/
+ DRAWIO_BASE_URL: ${DRAWIO_BASE_URL}
+ DRAWIO_SERVER_URL: ${DRAWIO_SERVER_URL}
+ DRAWIO_CSP_HEADER: ${DRAWIO_CSP_HEADER}
+ DRAWIO_VIEWER_URL: ${DRAWIO_VIEWER_URL}
+ DRAWIO_LIGHTBOX_URL: ${DRAWIO_LIGHTBOX_URL}
+ DRAWIO_CONFIG: ${DRAWIO_CONFIG}
+ DRAWIO_GOOGLE_CLIENT_ID: ${DRAWIO_GOOGLE_CLIENT_ID}
+ DRAWIO_GOOGLE_APP_ID: ${DRAWIO_GOOGLE_APP_ID}
+ DRAWIO_GOOGLE_CLIENT_SECRET: ${DRAWIO_GOOGLE_CLIENT_SECRET}
+ DRAWIO_GOOGLE_VIEWER_CLIENT_ID: ${DRAWIO_GOOGLE_VIEWER_CLIENT_ID}
+ DRAWIO_GOOGLE_VIEWER_APP_ID: ${DRAWIO_GOOGLE_VIEWER_APP_ID}
+ DRAWIO_GOOGLE_VIEWER_CLIENT_SECRET: ${DRAWIO_GOOGLE_VIEWER_CLIENT_SECRET}
+ DRAWIO_MSGRAPH_CLIENT_ID: ${DRAWIO_MSGRAPH_CLIENT_ID}
+ DRAWIO_MSGRAPH_CLIENT_SECRET: ${DRAWIO_MSGRAPH_CLIENT_SECRET}
+ DRAWIO_MSGRAPH_TENANT_ID: ${DRAWIO_MSGRAPH_TENANT_ID}
+ DRAWIO_GITLAB_ID: ${DRAWIO_GITLAB_ID}
+ DRAWIO_GITLAB_SECRET: ${DRAWIO_GITLAB_SECRET}
+ DRAWIO_GITLAB_URL: ${DRAWIO_GITLAB_URL}
+ DRAWIO_CLOUD_CONVERT_APIKEY: ${DRAWIO_CLOUD_CONVERT_APIKEY}
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ fonts_volume:
\ No newline at end of file
diff --git a/blueprints/drawio/drawio.svg b/blueprints/drawio/drawio.svg
new file mode 100644
index 000000000..079095282
--- /dev/null
+++ b/blueprints/drawio/drawio.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/drawio/template.yml b/blueprints/drawio/template.yml
new file mode 100644
index 000000000..6ce0ec85f
--- /dev/null
+++ b/blueprints/drawio/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: drawio
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ - DRAWIO_HOST=${main_domain}
+ - DRAWIO_BASE_URL=https://${main_domain}
+ - DRAWIO_SERVER_URL=https://${main_domain}/
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/elastic-search/docker-compose.yml b/blueprints/elastic-search/docker-compose.yml
new file mode 100644
index 000000000..929006ff1
--- /dev/null
+++ b/blueprints/elastic-search/docker-compose.yml
@@ -0,0 +1,34 @@
+version: '3.8'
+
+services:
+ elasticsearch:
+ image: docker.elastic.co/elasticsearch/elasticsearch:8.10.2
+ container_name: elasticsearch
+ environment:
+ - discovery.type=single-node
+ - xpack.security.enabled=false
+ - bootstrap.memory_lock=true
+ - ES_JAVA_OPTS=-Xms512m -Xmx512m
+ ulimits:
+ memlock:
+ soft: -1
+ hard: -1
+ ports:
+ - "9200"
+ volumes:
+ - es_data:/usr/share/elasticsearch/data
+
+ kibana:
+ image: docker.elastic.co/kibana/kibana:8.10.2
+ container_name: kibana
+ environment:
+ - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
+ ports:
+ - "5601"
+ depends_on:
+ - elasticsearch
+
+volumes:
+ es_data:
+ driver: local
+
\ No newline at end of file
diff --git a/blueprints/elastic-search/elasticsearch.svg b/blueprints/elastic-search/elasticsearch.svg
new file mode 100644
index 000000000..b95507cd5
--- /dev/null
+++ b/blueprints/elastic-search/elasticsearch.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blueprints/elastic-search/template.yml b/blueprints/elastic-search/template.yml
new file mode 100644
index 000000000..c6065a9e9
--- /dev/null
+++ b/blueprints/elastic-search/template.yml
@@ -0,0 +1,16 @@
+variables:
+ main_domain: ${domain}
+ api_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: kibana
+ port: 5601
+ host: ${main_domain}
+ - serviceName: elasticsearch
+ port: 9200
+ host: ${api_domain}
+
+ env: []
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/erpnext/docker-compose.yml b/blueprints/erpnext/docker-compose.yml
new file mode 100644
index 000000000..28cd8f6ab
--- /dev/null
+++ b/blueprints/erpnext/docker-compose.yml
@@ -0,0 +1,354 @@
+x-custom-image: &custom_image
+ image: ${IMAGE_NAME:-docker.io/frappe/erpnext}:${VERSION:-version-15}
+ pull_policy: ${PULL_POLICY:-always}
+ deploy:
+ restart_policy:
+ condition: always
+
+services:
+ backend:
+ <<: *custom_image
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - '0.0.0.0:8000'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+
+ frontend:
+ <<: *custom_image
+ command:
+ - nginx-entrypoint.sh
+ depends_on:
+ backend:
+ condition: service_started
+ required: true
+ websocket:
+ condition: service_started
+ required: true
+ environment:
+ BACKEND: backend:8000
+ FRAPPE_SITE_NAME_HEADER: ${FRAPPE_SITE_NAME_HEADER:-$$host}
+ SOCKETIO: websocket:9000
+ UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1
+ UPSTREAM_REAL_IP_HEADER: X-Forwarded-For
+ UPSTREAM_REAL_IP_RECURSIVE: "off"
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+
+ networks:
+ - bench-network
+
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - '0.0.0.0:8080'
+ interval: 2s
+ timeout: 30s
+ retries: 30
+
+ queue-default:
+ <<: *custom_image
+ command:
+ - bench
+ - worker
+ - --queue
+ - default
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+
+ queue-long:
+ <<: *custom_image
+ command:
+ - bench
+ - worker
+ - --queue
+ - long
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+
+ queue-short:
+ <<: *custom_image
+ command:
+ - bench
+ - worker
+ - --queue
+ - short
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+
+ scheduler:
+ <<: *custom_image
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ command:
+ - bench
+ - schedule
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ websocket:
+ <<: *custom_image
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - '0.0.0.0:9000'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ command:
+ - node
+ - /home/frappe/frappe-bench/apps/frappe/socketio.js
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ configurator:
+ <<: *custom_image
+ deploy:
+ mode: replicated
+ replicas: ${CONFIGURE:-0}
+ restart_policy:
+ condition: none
+ entrypoint: ["bash", "-c"]
+ command:
+ - >
+ [[ $${REGENERATE_APPS_TXT} == "1" ]] && ls -1 apps > sites/apps.txt;
+ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && exit 0;
+ bench set-config -g db_host $$DB_HOST;
+ bench set-config -gp db_port $$DB_PORT;
+ bench set-config -g redis_cache "redis://$$REDIS_CACHE";
+ bench set-config -g redis_queue "redis://$$REDIS_QUEUE";
+ bench set-config -g redis_socketio "redis://$$REDIS_QUEUE";
+ bench set-config -gp socketio_port $$SOCKETIO_PORT;
+ environment:
+ DB_HOST: "${DB_HOST:-db}"
+ DB_PORT: "3306"
+ REDIS_CACHE: redis-cache:6379
+ REDIS_QUEUE: redis-queue:6379
+ SOCKETIO_PORT: "9000"
+ REGENERATE_APPS_TXT: "${REGENERATE_APPS_TXT:-0}"
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ create-site:
+ <<: *custom_image
+ deploy:
+ mode: replicated
+ replicas: ${CREATE_SITE:-0}
+ restart_policy:
+ condition: none
+ entrypoint: ["bash", "-c"]
+ command:
+ - >
+ wait-for-it -t 120 $$DB_HOST:$$DB_PORT;
+ wait-for-it -t 120 redis-cache:6379;
+ wait-for-it -t 120 redis-queue:6379;
+ export start=`date +%s`;
+ until [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && \
+ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_cache // empty"` ]] && \
+ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_queue // empty"` ]];
+ do
+ echo "Waiting for sites/common_site_config.json to be created";
+ sleep 5;
+ if (( `date +%s`-start > 120 )); then
+ echo "could not find sites/common_site_config.json with required keys";
+ exit 1
+ fi
+ done;
+ echo "sites/common_site_config.json found";
+ [[ -d "sites/${SITE_NAME}" ]] && echo "${SITE_NAME} already exists" && exit 0;
+ bench new-site --mariadb-user-host-login-scope='%' --admin-password=$${ADMIN_PASSWORD} --db-root-username=root --db-root-password=$${DB_ROOT_PASSWORD} $${INSTALL_APP_ARGS} $${SITE_NAME};
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ environment:
+ SITE_NAME: ${SITE_NAME}
+ ADMIN_PASSWORD: ${ADMIN_PASSWORD}
+ DB_HOST: ${DB_HOST:-db}
+ DB_PORT: "${DB_PORT:-3306}"
+ DB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
+ INSTALL_APP_ARGS: ${INSTALL_APP_ARGS}
+ networks:
+ - bench-network
+
+ migration:
+ <<: *custom_image
+ deploy:
+ mode: replicated
+ replicas: ${MIGRATE:-0}
+ restart_policy:
+ condition: none
+ entrypoint: ["bash", "-c"]
+ command:
+ - >
+ curl -f http://${SITE_NAME}:8080/api/method/ping || echo "Site busy" && exit 0;
+ bench --site all set-config -p maintenance_mode 1;
+ bench --site all set-config -p pause_scheduler 1;
+ bench --site all migrate;
+ bench --site all set-config -p maintenance_mode 0;
+ bench --site all set-config -p pause_scheduler 0;
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ db:
+ image: mariadb:10.6
+ deploy:
+ mode: replicated
+ replicas: ${ENABLE_DB:-0}
+ restart_policy:
+ condition: always
+ healthcheck:
+ test: mysqladmin ping -h localhost --password=${DB_ROOT_PASSWORD}
+ interval: 1s
+ retries: 20
+ command:
+ - --character-set-server=utf8mb4
+ - --collation-server=utf8mb4_unicode_ci
+ - --skip-character-set-client-handshake
+ - --skip-innodb-read-only-compressed
+ environment:
+ - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
+ - MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
+ volumes:
+ - db-data:/var/lib/mysql
+ networks:
+ - bench-network
+
+ redis-cache:
+ deploy:
+ restart_policy:
+ condition: always
+ image: redis:6.2-alpine
+ volumes:
+ - redis-cache-data:/data
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ interval: 5s
+ timeout: 5s
+ retries: 3
+
+ redis-queue:
+ deploy:
+ restart_policy:
+ condition: always
+ image: redis:6.2-alpine
+ volumes:
+ - redis-queue-data:/data
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ interval: 5s
+ timeout: 5s
+ retries: 3
+
+ redis-socketio:
+ deploy:
+ restart_policy:
+ condition: always
+ image: redis:6.2-alpine
+ volumes:
+ - redis-socketio-data:/data
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ interval: 5s
+ timeout: 5s
+ retries: 3
+
+volumes:
+ db-data:
+ redis-cache-data:
+ redis-queue-data:
+ redis-socketio-data:
+ sites:
+ driver_opts:
+ type: "${SITE_VOLUME_TYPE}"
+ o: "${SITE_VOLUME_OPTS}"
+ device: "${SITE_VOLUME_DEV}"
+
+networks:
+ bench-network:
\ No newline at end of file
diff --git a/blueprints/erpnext/erpnext.svg b/blueprints/erpnext/erpnext.svg
new file mode 100644
index 000000000..d699ea2ad
--- /dev/null
+++ b/blueprints/erpnext/erpnext.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/blueprints/erpnext/template.yml b/blueprints/erpnext/template.yml
new file mode 100644
index 000000000..61b26eb1c
--- /dev/null
+++ b/blueprints/erpnext/template.yml
@@ -0,0 +1,27 @@
+variables:
+ main_domain: ${domain}
+ db_root_password: ${password:32}
+ admin_password: ${password:32}
+
+config:
+ domains:
+ - serviceName: frontend
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ - SITE_NAME=${main_domain}
+ - ADMIN_PASSWORD=${admin_password}
+ - DB_ROOT_PASSWORD=${db_root_password}
+ - MIGRATE=1
+ - ENABLE_DB=1
+ - DB_HOST=db
+ - CREATE_SITE=1
+ - CONFIGURE=1
+ - REGENERATE_APPS_TXT=1
+ - INSTALL_APP_ARGS=--install-app erpnext
+ - IMAGE_NAME=docker.io/frappe/erpnext
+ - VERSION=version-15
+ - FRAPPE_SITE_NAME_HEADER=
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/evolutionapi/docker-compose.yml b/blueprints/evolutionapi/docker-compose.yml
new file mode 100644
index 000000000..d4803de1c
--- /dev/null
+++ b/blueprints/evolutionapi/docker-compose.yml
@@ -0,0 +1,58 @@
+services:
+ evolution-api:
+ image: atendai/evolution-api:v2.1.2
+ restart: always
+ volumes:
+ - evolution-instances:/evolution/instances
+
+ environment:
+ - SERVER_URL=${SERVER_URL}
+ - AUTHENTICATION_TYPE=${AUTHENTICATION_TYPE}
+ - AUTHENTICATION_API_KEY=${AUTHENTICATION_API_KEY}
+ - AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=${AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES}
+ - LANGUAGE=${LANGUAGE}
+ - CONFIG_SESSION_PHONE_CLIENT=${CONFIG_SESSION_PHONE_CLIENT}
+ - CONFIG_SESSION_PHONE_NAME=${CONFIG_SESSION_PHONE_NAME}
+ - TELEMETRY=${TELEMETRY}
+ - TELEMETRY_URL=${TELEMETRY_URL}
+ - DATABASE_ENABLED=${DATABASE_ENABLED}
+ - DATABASE_PROVIDER=${DATABASE_PROVIDER}
+ - DATABASE_CONNECTION_URI=${DATABASE_CONNECTION_URI}
+ - DATABASE_SAVE_DATA_INSTANCE=${DATABASE_SAVE_DATA_INSTANCE}
+ - DATABASE_SAVE_DATA_NEW_MESSAGE=${DATABASE_SAVE_DATA_NEW_MESSAGE}
+ - DATABASE_SAVE_MESSAGE_UPDATE=${DATABASE_SAVE_MESSAGE_UPDATE}
+ - DATABASE_SAVE_DATA_CONTACTS=${DATABASE_SAVE_DATA_CONTACTS}
+ - DATABASE_SAVE_DATA_CHATS=${DATABASE_SAVE_DATA_CHATS}
+ - DATABASE_SAVE_DATA_LABELS=${DATABASE_SAVE_DATA_LABELS}
+ - DATABASE_SAVE_DATA_HISTORIC=${DATABASE_SAVE_DATA_HISTORIC}
+ - CACHE_REDIS_ENABLED=${CACHE_REDIS_ENABLED}
+ - CACHE_REDIS_URI=${CACHE_REDIS_URI}
+ - CACHE_REDIS_PREFIX_KEY=${CACHE_REDIS_PREFIX_KEY}
+ - CACHE_REDIS_SAVE_INSTANCES=${CACHE_REDIS_SAVE_INSTANCES}
+
+ evolution-postgres:
+ image: postgres:16-alpine
+ restart: always
+ volumes:
+ - evolution-postgres-data:/var/lib/postgresql/data
+
+ environment:
+ - POSTGRES_DB=${POSTGRES_DATABASE}
+ - POSTGRES_USER=${POSTGRES_USERNAME}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+
+ evolution-redis:
+ image: redis:alpine
+ restart: always
+ volumes:
+ - evolution-redis-data:/data
+
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ evolution-instances:
+ evolution-postgres-data:
+ evolution-redis-data:
\ No newline at end of file
diff --git a/blueprints/evolutionapi/evolutionapi.png b/blueprints/evolutionapi/evolutionapi.png
new file mode 100644
index 000000000..bd9b3850a
Binary files /dev/null and b/blueprints/evolutionapi/evolutionapi.png differ
diff --git a/blueprints/evolutionapi/template.yml b/blueprints/evolutionapi/template.yml
new file mode 100644
index 000000000..fdac9edc5
--- /dev/null
+++ b/blueprints/evolutionapi/template.yml
@@ -0,0 +1,40 @@
+variables:
+ main_domain: ${domain}
+ api_key: ${base64:64}
+ postgres_password: ${password}
+
+config:
+ domains:
+ - serviceName: evolution-api
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ - SERVER_URL=https://${main_domain}
+ - AUTHENTICATION_TYPE=apikey
+ - AUTHENTICATION_API_KEY=${api_key}
+ - AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
+ - LANGUAGE=en
+ - CONFIG_SESSION_PHONE_CLIENT=Evolution API
+ - CONFIG_SESSION_PHONE_NAME=Chrome
+ - TELEMETRY=false
+ - TELEMETRY_URL=
+ - POSTGRES_DATABASE=evolution
+ - POSTGRES_USERNAME=postgresql
+ - POSTGRES_PASSWORD=${postgres_password}
+ - DATABASE_ENABLED=true
+ - DATABASE_PROVIDER=postgresql
+ - DATABASE_CONNECTION_URI=postgres://postgresql:${postgres_password}@evolution-postgres:5432/evolution
+ - DATABASE_SAVE_DATA_INSTANCE=true
+ - DATABASE_SAVE_DATA_NEW_MESSAGE=true
+ - DATABASE_SAVE_MESSAGE_UPDATE=true
+ - DATABASE_SAVE_DATA_CONTACTS=true
+ - DATABASE_SAVE_DATA_CHATS=true
+ - DATABASE_SAVE_DATA_LABELS=true
+ - DATABASE_SAVE_DATA_HISTORIC=true
+ - CACHE_REDIS_ENABLED=true
+ - CACHE_REDIS_URI=redis://evolution-redis:6379
+ - CACHE_REDIS_PREFIX_KEY=evolution
+ - CACHE_REDIS_SAVE_INSTANCES=true
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/excalidraw/docker-compose.yml b/blueprints/excalidraw/docker-compose.yml
new file mode 100644
index 000000000..3cf2fb1d1
--- /dev/null
+++ b/blueprints/excalidraw/docker-compose.yml
@@ -0,0 +1,6 @@
+version: "3.8"
+
+services:
+ excalidraw:
+
+ image: excalidraw/excalidraw:latest
diff --git a/blueprints/excalidraw/excalidraw.jpg b/blueprints/excalidraw/excalidraw.jpg
new file mode 100644
index 000000000..5c92a30c7
Binary files /dev/null and b/blueprints/excalidraw/excalidraw.jpg differ
diff --git a/blueprints/excalidraw/template.yml b/blueprints/excalidraw/template.yml
new file mode 100644
index 000000000..8648aed9b
--- /dev/null
+++ b/blueprints/excalidraw/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: excalidraw
+ port: 80
+ host: ${main_domain}
+
+ env: []
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/filebrowser/docker-compose.yml b/blueprints/filebrowser/docker-compose.yml
new file mode 100644
index 000000000..10c119091
--- /dev/null
+++ b/blueprints/filebrowser/docker-compose.yml
@@ -0,0 +1,14 @@
+services:
+ filebrowser:
+ image: hurlenko/filebrowser
+ volumes:
+ - filebrowser-data:/data
+ - filebrowser-config:/config
+ environment:
+ - FB_BASEURL=${FB_BASEURL}
+ restart: always
+
+volumes:
+ filebrowser-data:
+ filebrowser-config:
+
\ No newline at end of file
diff --git a/blueprints/filebrowser/filebrowser.svg b/blueprints/filebrowser/filebrowser.svg
new file mode 100644
index 000000000..5e78eccff
--- /dev/null
+++ b/blueprints/filebrowser/filebrowser.svg
@@ -0,0 +1,147 @@
+
+image/svg+xml
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/filebrowser/template.yml b/blueprints/filebrowser/template.yml
new file mode 100644
index 000000000..34e7eb387
--- /dev/null
+++ b/blueprints/filebrowser/template.yml
@@ -0,0 +1,13 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: filebrowser
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ - FB_BASEURL=/filebrowser
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/formbricks/docker-compose.yml b/blueprints/formbricks/docker-compose.yml
new file mode 100644
index 000000000..ad1dcbcff
--- /dev/null
+++ b/blueprints/formbricks/docker-compose.yml
@@ -0,0 +1,37 @@
+x-environment: &environment
+ environment:
+ WEBAPP_URL: ${WEBAPP_URL}
+ NEXTAUTH_URL: ${NEXTAUTH_URL}
+ DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/formbricks?schema=public"
+ NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
+ ENCRYPTION_KEY: ${ENCRYPTION_KEY}
+ CRON_SECRET: ${CRON_SECRET}
+ EMAIL_VERIFICATION_DISABLED: 1
+ PASSWORD_RESET_DISABLED: 1
+ S3_FORCE_PATH_STYLE: 0
+
+services:
+ postgres:
+ restart: always
+ image: pgvector/pgvector:pg17
+ volumes:
+ - postgres:/var/lib/postgresql/data
+ environment:
+ - POSTGRES_PASSWORD=postgres
+
+
+ formbricks:
+ restart: always
+ image: ghcr.io/formbricks/formbricks:v3.1.3
+ depends_on:
+ - postgres
+ ports:
+ - 3000
+ volumes:
+ - ../files/uploads:/home/nextjs/apps/web/uploads/
+ <<: *environment
+
+volumes:
+ postgres:
+ driver: local
+ uploads:
diff --git a/blueprints/formbricks/formbricks.png b/blueprints/formbricks/formbricks.png
new file mode 100644
index 000000000..2bf1ca1fb
Binary files /dev/null and b/blueprints/formbricks/formbricks.png differ
diff --git a/blueprints/formbricks/template.yml b/blueprints/formbricks/template.yml
new file mode 100644
index 000000000..6572770b1
--- /dev/null
+++ b/blueprints/formbricks/template.yml
@@ -0,0 +1,20 @@
+variables:
+ main_domain: ${domain}
+ secret_base: ${base64:64}
+ encryption_key: ${base64:48}
+ cron_secret: ${base64:32}
+
+config:
+ domains:
+ - serviceName: formbricks
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - WEBAPP_URL=http://${main_domain}
+ - NEXTAUTH_URL=http://${main_domain}
+ - NEXTAUTH_SECRET=${secret_base}
+ - ENCRYPTION_KEY=${encryption_key}
+ - CRON_SECRET=${cron_secret}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/frappe-hr/docker-compose.yml b/blueprints/frappe-hr/docker-compose.yml
new file mode 100644
index 000000000..a7ce9b262
--- /dev/null
+++ b/blueprints/frappe-hr/docker-compose.yml
@@ -0,0 +1,354 @@
+x-custom-image: &custom_image
+ image: ${IMAGE_NAME:-ghcr.io/frappe/hrms}:${VERSION:-version-15}
+ pull_policy: ${PULL_POLICY:-always}
+ deploy:
+ restart_policy:
+ condition: always
+
+services:
+ backend:
+ <<: *custom_image
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - '0.0.0.0:8000'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+
+ frontend:
+ <<: *custom_image
+ command:
+ - nginx-entrypoint.sh
+ depends_on:
+ backend:
+ condition: service_started
+ required: true
+ websocket:
+ condition: service_started
+ required: true
+ environment:
+ BACKEND: backend:8000
+ FRAPPE_SITE_NAME_HEADER: ${FRAPPE_SITE_NAME_HEADER:-$$host}
+ SOCKETIO: websocket:9000
+ UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1
+ UPSTREAM_REAL_IP_HEADER: X-Forwarded-For
+ UPSTREAM_REAL_IP_RECURSIVE: "off"
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+
+ networks:
+ - bench-network
+
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - '0.0.0.0:8080'
+ interval: 2s
+ timeout: 30s
+ retries: 30
+
+ queue-default:
+ <<: *custom_image
+ command:
+ - bench
+ - worker
+ - --queue
+ - default
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+
+ queue-long:
+ <<: *custom_image
+ command:
+ - bench
+ - worker
+ - --queue
+ - long
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+
+ queue-short:
+ <<: *custom_image
+ command:
+ - bench
+ - worker
+ - --queue
+ - short
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+
+ scheduler:
+ <<: *custom_image
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - 'redis-queue:6379'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ command:
+ - bench
+ - schedule
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ websocket:
+ <<: *custom_image
+ healthcheck:
+ test:
+ - CMD
+ - wait-for-it
+ - '0.0.0.0:9000'
+ interval: 2s
+ timeout: 10s
+ retries: 30
+ command:
+ - node
+ - /home/frappe/frappe-bench/apps/frappe/socketio.js
+ depends_on:
+ configurator:
+ condition: service_completed_successfully
+ required: true
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ configurator:
+ <<: *custom_image
+ deploy:
+ mode: replicated
+ replicas: ${CONFIGURE:-0}
+ restart_policy:
+ condition: none
+ entrypoint: ["bash", "-c"]
+ command:
+ - >
+ [[ $${REGENERATE_APPS_TXT} == "1" ]] && ls -1 apps > sites/apps.txt;
+ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && exit 0;
+ bench set-config -g db_host $$DB_HOST;
+ bench set-config -gp db_port $$DB_PORT;
+ bench set-config -g redis_cache "redis://$$REDIS_CACHE";
+ bench set-config -g redis_queue "redis://$$REDIS_QUEUE";
+ bench set-config -g redis_socketio "redis://$$REDIS_QUEUE";
+ bench set-config -gp socketio_port $$SOCKETIO_PORT;
+ environment:
+ DB_HOST: "${DB_HOST:-db}"
+ DB_PORT: "3306"
+ REDIS_CACHE: redis-cache:6379
+ REDIS_QUEUE: redis-queue:6379
+ SOCKETIO_PORT: "9000"
+ REGENERATE_APPS_TXT: "${REGENERATE_APPS_TXT:-0}"
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ create-site:
+ <<: *custom_image
+ deploy:
+ mode: replicated
+ replicas: ${CREATE_SITE:-0}
+ restart_policy:
+ condition: none
+ entrypoint: ["bash", "-c"]
+ command:
+ - >
+ wait-for-it -t 120 $$DB_HOST:$$DB_PORT;
+ wait-for-it -t 120 redis-cache:6379;
+ wait-for-it -t 120 redis-queue:6379;
+ export start=`date +%s`;
+ until [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && \
+ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_cache // empty"` ]] && \
+ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_queue // empty"` ]];
+ do
+ echo "Waiting for sites/common_site_config.json to be created";
+ sleep 5;
+ if (( `date +%s`-start > 120 )); then
+ echo "could not find sites/common_site_config.json with required keys";
+ exit 1
+ fi
+ done;
+ echo "sites/common_site_config.json found";
+ [[ -d "sites/${SITE_NAME}" ]] && echo "${SITE_NAME} already exists" && exit 0;
+ bench new-site --mariadb-user-host-login-scope='%' --admin-password=$${ADMIN_PASSWORD} --db-root-username=root --db-root-password=$${DB_ROOT_PASSWORD} $${INSTALL_APP_ARGS} $${SITE_NAME};
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ environment:
+ SITE_NAME: ${SITE_NAME}
+ ADMIN_PASSWORD: ${ADMIN_PASSWORD}
+ DB_HOST: ${DB_HOST:-db}
+ DB_PORT: "${DB_PORT:-3306}"
+ DB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
+ INSTALL_APP_ARGS: ${INSTALL_APP_ARGS}
+ networks:
+ - bench-network
+
+ migration:
+ <<: *custom_image
+ deploy:
+ mode: replicated
+ replicas: ${MIGRATE:-0}
+ restart_policy:
+ condition: none
+ entrypoint: ["bash", "-c"]
+ command:
+ - >
+ curl -f http://${SITE_NAME}:8080/api/method/ping || echo "Site busy" && exit 0;
+ bench --site all set-config -p maintenance_mode 1;
+ bench --site all set-config -p pause_scheduler 1;
+ bench --site all migrate;
+ bench --site all set-config -p maintenance_mode 0;
+ bench --site all set-config -p pause_scheduler 0;
+ volumes:
+ - sites:/home/frappe/frappe-bench/sites
+ networks:
+ - bench-network
+
+ db:
+ image: mariadb:10.6
+ deploy:
+ mode: replicated
+ replicas: ${ENABLE_DB:-0}
+ restart_policy:
+ condition: always
+ healthcheck:
+ test: mysqladmin ping -h localhost --password=${DB_ROOT_PASSWORD}
+ interval: 1s
+ retries: 20
+ command:
+ - --character-set-server=utf8mb4
+ - --collation-server=utf8mb4_unicode_ci
+ - --skip-character-set-client-handshake
+ - --skip-innodb-read-only-compressed
+ environment:
+ - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
+ - MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
+ volumes:
+ - db-data:/var/lib/mysql
+ networks:
+ - bench-network
+
+ redis-cache:
+ deploy:
+ restart_policy:
+ condition: always
+ image: redis:6.2-alpine
+ volumes:
+ - redis-cache-data:/data
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ interval: 5s
+ timeout: 5s
+ retries: 3
+
+ redis-queue:
+ deploy:
+ restart_policy:
+ condition: always
+ image: redis:6.2-alpine
+ volumes:
+ - redis-queue-data:/data
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ interval: 5s
+ timeout: 5s
+ retries: 3
+
+ redis-socketio:
+ deploy:
+ restart_policy:
+ condition: always
+ image: redis:6.2-alpine
+ volumes:
+ - redis-socketio-data:/data
+ networks:
+ - bench-network
+ healthcheck:
+ test:
+ - CMD
+ - redis-cli
+ - ping
+ interval: 5s
+ timeout: 5s
+ retries: 3
+
+volumes:
+ db-data:
+ redis-cache-data:
+ redis-queue-data:
+ redis-socketio-data:
+ sites:
+ driver_opts:
+ type: "${SITE_VOLUME_TYPE}"
+ o: "${SITE_VOLUME_OPTS}"
+ device: "${SITE_VOLUME_DEV}"
+
+networks:
+ bench-network:
\ No newline at end of file
diff --git a/blueprints/frappe-hr/frappe-hr.svg b/blueprints/frappe-hr/frappe-hr.svg
new file mode 100644
index 000000000..4cbf51641
--- /dev/null
+++ b/blueprints/frappe-hr/frappe-hr.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/blueprints/frappe-hr/template.yml b/blueprints/frappe-hr/template.yml
new file mode 100644
index 000000000..b5c8f9d96
--- /dev/null
+++ b/blueprints/frappe-hr/template.yml
@@ -0,0 +1,27 @@
+variables:
+ main_domain: ${domain}
+ db_root_password: ${password:32}
+ admin_password: ${password:32}
+
+config:
+ domains:
+ - serviceName: frontend
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ - SITE_NAME=${main_domain}
+ - ADMIN_PASSWORD=${admin_password}
+ - DB_ROOT_PASSWORD=${db_root_password}
+ - MIGRATE=1
+ - ENABLE_DB=1
+ - DB_HOST=db
+ - CREATE_SITE=1
+ - CONFIGURE=1
+ - REGENERATE_APPS_TXT=1
+ - INSTALL_APP_ARGS=--install-app hrms
+ - IMAGE_NAME=ghcr.io/frappe/hrms
+ - VERSION=version-15
+ - FRAPPE_SITE_NAME_HEADER=
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/ghost/docker-compose.yml b/blueprints/ghost/docker-compose.yml
new file mode 100644
index 000000000..33c47f7f8
--- /dev/null
+++ b/blueprints/ghost/docker-compose.yml
@@ -0,0 +1,28 @@
+version: "3.8"
+services:
+ ghost:
+ image: ghost:5-alpine
+ restart: always
+ environment:
+ database__client: mysql
+ database__connection__host: db
+ database__connection__user: root
+ database__connection__password: example
+ database__connection__database: ghost
+ url: http://${GHOST_HOST}
+
+ volumes:
+ - ghost:/var/lib/ghost/content
+
+ db:
+ image: mysql:8.0
+ restart: always
+
+ environment:
+ MYSQL_ROOT_PASSWORD: example
+ volumes:
+ - db:/var/lib/mysql
+
+volumes:
+ ghost:
+ db:
diff --git a/blueprints/ghost/ghost.jpeg b/blueprints/ghost/ghost.jpeg
new file mode 100644
index 000000000..9bfefe838
Binary files /dev/null and b/blueprints/ghost/ghost.jpeg differ
diff --git a/blueprints/ghost/template.yml b/blueprints/ghost/template.yml
new file mode 100644
index 000000000..f85f423c2
--- /dev/null
+++ b/blueprints/ghost/template.yml
@@ -0,0 +1,13 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: ghost
+ port: 2368
+ host: ${main_domain}
+
+ env:
+ - GHOST_HOST=${main_domain}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/gitea/docker-compose.yml b/blueprints/gitea/docker-compose.yml
new file mode 100644
index 000000000..5127224cd
--- /dev/null
+++ b/blueprints/gitea/docker-compose.yml
@@ -0,0 +1,35 @@
+version: "3.8"
+services:
+ gitea:
+ image: gitea/gitea:1.22.3
+ environment:
+ - USER_UID=${USER_UID}
+ - USER_GID=${USER_GID}
+ - GITEA__database__DB_TYPE=postgres
+ - GITEA__database__HOST=db:5432
+ - GITEA__database__NAME=gitea
+ - GITEA__database__USER=gitea
+ - GITEA__database__PASSWD=gitea
+ restart: always
+
+ volumes:
+ - gitea_server:/data
+ - /etc/timezone:/etc/timezone:ro
+ - /etc/localtime:/etc/localtime:ro
+ depends_on:
+ - db
+
+ db:
+ image: postgres:17
+ restart: always
+ environment:
+ - POSTGRES_USER=gitea
+ - POSTGRES_PASSWORD=gitea
+ - POSTGRES_DB=gitea
+
+ volumes:
+ - gitea_db:/var/lib/postgresql/data
+
+volumes:
+ gitea_db:
+ gitea_server:
\ No newline at end of file
diff --git a/blueprints/gitea/gitea.png b/blueprints/gitea/gitea.png
new file mode 100644
index 000000000..5dacd7735
Binary files /dev/null and b/blueprints/gitea/gitea.png differ
diff --git a/blueprints/gitea/template.yml b/blueprints/gitea/template.yml
new file mode 100644
index 000000000..2a0107e93
--- /dev/null
+++ b/blueprints/gitea/template.yml
@@ -0,0 +1,14 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: gitea
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - USER_UID=1000
+ - USER_GID=1000
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/glance/docker-compose.yml b/blueprints/glance/docker-compose.yml
new file mode 100644
index 000000000..ace8bc940
--- /dev/null
+++ b/blueprints/glance/docker-compose.yml
@@ -0,0 +1,11 @@
+services:
+ glance:
+ image: glanceapp/glance
+ volumes:
+ - ../files/app/config/:/app/config
+ - ../files/app/assets:/app/assets
+ # Optionally, also mount docker socket if you want to use the docker containers widget
+ # - /var/run/docker.sock:/var/run/docker.sock:ro
+ ports:
+ - 8080
+ env_file: .env
\ No newline at end of file
diff --git a/blueprints/glance/glance.png b/blueprints/glance/glance.png
new file mode 100644
index 000000000..54fc41311
Binary files /dev/null and b/blueprints/glance/glance.png differ
diff --git a/blueprints/glance/template.yml b/blueprints/glance/template.yml
new file mode 100644
index 000000000..e570fe386
--- /dev/null
+++ b/blueprints/glance/template.yml
@@ -0,0 +1,93 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: glance
+ port: 8080
+ host: ${main_domain}
+
+ env: []
+
+ mounts:
+ - filePath: /app/config/glance.yml
+ content: |
+ branding:
+ hide-footer: true
+ logo-text: P
+
+ pages:
+ - name: Home
+ columns:
+ - size: small
+ widgets:
+ - type: calendar
+
+ - type: releases
+ show-source-icon: true
+ repositories:
+ - Dokploy/dokploy
+ - n8n-io/n8n
+ - Budibase/budibase
+ - home-assistant/core
+ - tidbyt/pixlet
+
+ - type: twitch-channels
+ channels:
+ - nmplol
+ - extraemily
+ - qtcinderella
+ - ludwig
+ - timthetatman
+ - mizkif
+
+ - size: full
+ widgets:
+ - type: hacker-news
+
+ - type: videos
+ style: grid-cards
+ channels:
+ - UC3GzdWYwUYI1ACxuP9Nm-eg
+ - UCGbg3DjQdcqWwqOLHpYHXIg
+ - UC24RSoLcjiNZbQcT54j5l7Q
+ limit: 3
+
+ - type: rss
+ limit: 10
+ collapse-after: 3
+ cache: 3h
+ feeds:
+ - url: https://daringfireball.net/feeds/main
+ title: Daring Fireball
+
+ - size: small
+ widgets:
+ - type: weather
+ location: Gansevoort, New York, United States
+ show-area-name: false
+ units: imperial
+ hour-format: 12h
+
+ - type: markets
+ markets:
+ - symbol: SPY
+ name: S&P 500
+ - symbol: VOO
+ name: Vanguard
+ - symbol: BTC-USD
+ name: Bitcoin
+ - symbol: ETH-USD
+ name: Etherium
+ - symbol: NVDA
+ name: NVIDIA
+ - symbol: AAPL
+ name: Apple
+ - symbol: MSFT
+ name: Microsoft
+ - symbol: GOOGL
+ name: Google
+ - symbol: AMD
+ name: AMD
+ - symbol: TSLA
+ name: Tesla
\ No newline at end of file
diff --git a/blueprints/glitchtip/docker-compose.yml b/blueprints/glitchtip/docker-compose.yml
new file mode 100644
index 000000000..f47742f01
--- /dev/null
+++ b/blueprints/glitchtip/docker-compose.yml
@@ -0,0 +1,55 @@
+x-environment: &default-environment
+ DATABASE_URL: postgres://postgres:postgres@postgres:5432/postgres
+ SECRET_KEY: ${SECRET_KEY}
+ PORT: ${GLITCHTIP_PORT}
+ EMAIL_URL: consolemail://
+ GLITCHTIP_DOMAIN: http://${GLITCHTIP_HOST}
+ DEFAULT_FROM_EMAIL: email@glitchtip.com
+ CELERY_WORKER_AUTOSCALE: "1,3"
+ CELERY_WORKER_MAX_TASKS_PER_CHILD: "10000"
+
+x-depends_on: &default-depends_on
+ - postgres
+ - redis
+
+services:
+ postgres:
+ image: postgres:16
+ environment:
+ POSTGRES_HOST_AUTH_METHOD: "trust"
+ restart: unless-stopped
+ volumes:
+ - pg-data:/var/lib/postgresql/data
+
+ redis:
+ image: redis
+ restart: unless-stopped
+
+ web:
+ image: glitchtip/glitchtip:v4.0
+ depends_on: *default-depends_on
+ ports:
+ - ${GLITCHTIP_PORT}
+ environment: *default-environment
+ restart: unless-stopped
+ volumes:
+ - uploads:/code/uploads
+ worker:
+ image: glitchtip/glitchtip:v4.0
+ command: ./bin/run-celery-with-beat.sh
+ depends_on: *default-depends_on
+ environment: *default-environment
+ restart: unless-stopped
+ volumes:
+ - uploads:/code/uploads
+
+ migrate:
+ image: glitchtip/glitchtip:v4.0
+ depends_on: *default-depends_on
+ command: "./manage.py migrate"
+ environment: *default-environment
+
+
+volumes:
+ pg-data:
+ uploads:
diff --git a/blueprints/glitchtip/glitchtip.png b/blueprints/glitchtip/glitchtip.png
new file mode 100644
index 000000000..866317528
Binary files /dev/null and b/blueprints/glitchtip/glitchtip.png differ
diff --git a/blueprints/glitchtip/template.yml b/blueprints/glitchtip/template.yml
new file mode 100644
index 000000000..5a6a28012
--- /dev/null
+++ b/blueprints/glitchtip/template.yml
@@ -0,0 +1,16 @@
+variables:
+ main_domain: ${domain}
+ secret_key: ${base64:32}
+
+config:
+ domains:
+ - serviceName: web
+ port: 8000
+ host: ${main_domain}
+
+ env:
+ - GLITCHTIP_HOST=${main_domain}
+ - GLITCHTIP_PORT=8000
+ - SECRET_KEY=${secret_key}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/glpi/docker-compose.yml b/blueprints/glpi/docker-compose.yml
new file mode 100644
index 000000000..fa732fa36
--- /dev/null
+++ b/blueprints/glpi/docker-compose.yml
@@ -0,0 +1,26 @@
+services:
+ glpi-mysql:
+ image: mysql:9.1.0
+ restart: always
+ volumes:
+ - glpi-mysql-data:/var/lib/mysql
+
+
+ glpi-web:
+ image: elestio/glpi:10.0.16
+ restart: always
+ volumes:
+ - /etc/timezone:/etc/timezone:ro
+ - /etc/localtime:/etc/localtime:ro
+ - glpi-www-data:/var/www/html/glpi
+ environment:
+ - TIMEZONE=Europe/Brussels
+
+
+volumes:
+ glpi-mysql-data:
+ glpi-www-data:
+
+networks:
+ dokploy-network:
+ external: true
\ No newline at end of file
diff --git a/blueprints/glpi/glpi.webp b/blueprints/glpi/glpi.webp
new file mode 100644
index 000000000..8d69cd297
Binary files /dev/null and b/blueprints/glpi/glpi.webp differ
diff --git a/blueprints/glpi/template.yml b/blueprints/glpi/template.yml
new file mode 100644
index 000000000..0891e9924
--- /dev/null
+++ b/blueprints/glpi/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: glpi-web
+ port: 80
+ host: ${main_domain}
+
+ env: []
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/gotenberg/docker-compose.yml b/blueprints/gotenberg/docker-compose.yml
new file mode 100644
index 000000000..02bbacb7c
--- /dev/null
+++ b/blueprints/gotenberg/docker-compose.yml
@@ -0,0 +1,18 @@
+services:
+ gotenberg:
+ image: gotenberg/gotenberg:latest
+ environment:
+ # NOTE: requires the --api-enable-basic-auth option in "command"
+ # make sure to also change the credentials in Dokploy environment
+ GOTENBERG_API_BASIC_AUTH_USERNAME: ${GOTENBERG_API_BASIC_AUTH_USERNAME}
+ GOTENBERG_API_BASIC_AUTH_PASSWORD: ${GOTENBERG_API_BASIC_AUTH_PASSWORD}
+ command: [
+ "gotenberg",
+ # See the full list of options at https://gotenberg.dev/docs/configuration
+
+ # Examples:
+ "--api-enable-basic-auth"
+ #"--api-timeout=60s",
+ #"--chromium-auto-start"
+ ]
+ restart: unless-stopped
\ No newline at end of file
diff --git a/blueprints/gotenberg/gotenberg.png b/blueprints/gotenberg/gotenberg.png
new file mode 100644
index 000000000..5db2c6f85
Binary files /dev/null and b/blueprints/gotenberg/gotenberg.png differ
diff --git a/blueprints/gotenberg/template.yml b/blueprints/gotenberg/template.yml
new file mode 100644
index 000000000..d94c03fdb
--- /dev/null
+++ b/blueprints/gotenberg/template.yml
@@ -0,0 +1,16 @@
+variables:
+ main_domain: ${domain}
+ username: gotenberg
+ password: changethis
+
+config:
+ domains:
+ - serviceName: gotenberg
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - GOTENBERG_API_BASIC_AUTH_USERNAME=${username}
+ - GOTENBERG_API_BASIC_AUTH_PASSWORD=${password}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/grafana/docker-compose.yml b/blueprints/grafana/docker-compose.yml
new file mode 100644
index 000000000..9d913c17f
--- /dev/null
+++ b/blueprints/grafana/docker-compose.yml
@@ -0,0 +1,9 @@
+version: "3.8"
+services:
+ grafana:
+ image: grafana/grafana-enterprise:9.5.20
+ restart: unless-stopped
+ volumes:
+ - grafana-storage:/var/lib/grafana
+volumes:
+ grafana-storage: {}
diff --git a/blueprints/grafana/grafana.svg b/blueprints/grafana/grafana.svg
new file mode 100644
index 000000000..54be1e2f1
--- /dev/null
+++ b/blueprints/grafana/grafana.svg
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/grafana/template.yml b/blueprints/grafana/template.yml
new file mode 100644
index 000000000..0fa704f83
--- /dev/null
+++ b/blueprints/grafana/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: grafana
+ port: 3000
+ host: ${main_domain}
+
+ env: []
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/heyform/docker-compose.yml b/blueprints/heyform/docker-compose.yml
new file mode 100644
index 000000000..ec7e02fc1
--- /dev/null
+++ b/blueprints/heyform/docker-compose.yml
@@ -0,0 +1,48 @@
+services:
+ heyform:
+ image: heyform/community-edition:latest
+ restart: always
+ volumes:
+ # Persist uploaded images
+ - heyform-data:/app/static/upload
+ depends_on:
+ - mongo
+ - redis
+ ports:
+ - 8000
+ env_file:
+ - .env
+ environment:
+ MONGO_URI: 'mongodb://mongo:27017/heyform'
+ REDIS_HOST: redis
+ REDIS_PORT: 6379
+ networks:
+ - heyform-network
+
+ mongo:
+ image: percona/percona-server-mongodb:4.4
+ restart: always
+ networks:
+ - heyform-network
+ volumes:
+ # Persist MongoDB data
+ - mongo-data:/data/db
+
+ redis:
+ image: redis
+ restart: always
+ command: "redis-server --appendonly yes"
+ networks:
+ - heyform-network
+ volumes:
+ # Persist KeyDB data
+ - redis-data:/data
+
+networks:
+ heyform-network:
+ driver: bridge
+
+volumes:
+ heyform-data:
+ mongo-data:
+ redis-data:
diff --git a/blueprints/heyform/heyform.svg b/blueprints/heyform/heyform.svg
new file mode 100644
index 000000000..e1e34e615
--- /dev/null
+++ b/blueprints/heyform/heyform.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/blueprints/heyform/template.yml b/blueprints/heyform/template.yml
new file mode 100644
index 000000000..ae3471984
--- /dev/null
+++ b/blueprints/heyform/template.yml
@@ -0,0 +1,17 @@
+variables:
+ main_domain: ${domain}
+ session_key: ${base64:64}
+ form_encryption_key: ${base64:64}
+
+config:
+ domains:
+ - serviceName: heyform
+ port: 8000
+ host: ${main_domain}
+
+ env:
+ - APP_HOMEPAGE_URL=http://${main_domain}
+ - SESSION_KEY=${session_key}
+ - FORM_ENCRYPTION_KEY=${form_encryption_key}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/hi-events/docker-compose.yml b/blueprints/hi-events/docker-compose.yml
new file mode 100644
index 000000000..cce45fecf
--- /dev/null
+++ b/blueprints/hi-events/docker-compose.yml
@@ -0,0 +1,44 @@
+services:
+ all-in-one:
+ image: daveearley/hi.events-all-in-one:v0.8.0-beta.1
+ restart: always
+ environment:
+ - VITE_FRONTEND_URL=https://${DOMAIN}
+ - APP_FRONTEND_URL=https://${DOMAIN}
+ - VITE_API_URL_CLIENT=https://${DOMAIN}/api
+ - VITE_API_URL_SERVER=http://localhost:80/api
+ - VITE_STRIPE_PUBLISHABLE_KEY
+ - LOG_CHANNEL=stderr
+ - QUEUE_CONNECTION=sync
+ - MAIL_MAILER=array
+ - APP_KEY
+ - JWT_SECRET
+ - FILESYSTEM_PUBLIC_DISK=public
+ - FILESYSTEM_PRIVATE_DISK=local
+ - APP_CDN_URL=https://${DOMAIN}/storage
+ - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
+ - MAIL_MAILER
+ - MAIL_HOST
+ - MAIL_PORT
+ - MAIL_FROM_ADDRESS
+ - MAIL_FROM_NAME
+ depends_on:
+ - postgres
+
+ postgres:
+ image: elestio/postgres:16
+ restart: always
+
+ environment:
+ - POSTGRES_DB
+ - POSTGRES_USER
+ - POSTGRES_PASSWORD
+ volumes:
+ - pg_hi-events_data:/var/lib/postgresql/data
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ pg_hi-events_data:
\ No newline at end of file
diff --git a/blueprints/hi-events/hi-events.svg b/blueprints/hi-events/hi-events.svg
new file mode 100644
index 000000000..0e373509b
--- /dev/null
+++ b/blueprints/hi-events/hi-events.svg
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/hi-events/template.yml b/blueprints/hi-events/template.yml
new file mode 100644
index 000000000..7ae0c8741
--- /dev/null
+++ b/blueprints/hi-events/template.yml
@@ -0,0 +1,27 @@
+variables:
+ main_domain: ${domain}
+ postgres_password: ${password}
+ jwt_secret: ${password}
+ app_key: ${password}
+
+config:
+ domains:
+ - serviceName: all-in-one
+ port: 80
+ host: ${main_domain}
+
+ env:
+ - DOMAIN=${main_domain}
+ - POSTGRES_DB=hievents
+ - POSTGRES_USER=hievents
+ - POSTGRES_PASSWORD=${postgres_password}
+ - VITE_STRIPE_PUBLISHABLE_KEY=
+ - APP_KEY=${app_key}
+ - JWT_SECRET=${jwt_secret}
+ - MAIL_MAILER=
+ - MAIL_HOST=
+ - MAIL_PORT=
+ - MAIL_FROM_ADDRESS=
+ - MAIL_FROM_NAME=
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/hoarder/docker-compose.yml b/blueprints/hoarder/docker-compose.yml
new file mode 100644
index 000000000..93e594697
--- /dev/null
+++ b/blueprints/hoarder/docker-compose.yml
@@ -0,0 +1,45 @@
+services:
+ web:
+ image: ghcr.io/hoarder-app/hoarder:0.22.0
+ restart: unless-stopped
+ volumes:
+ - hoarder-data:/data
+ ports:
+ - 3000
+ environment:
+ - DISABLE_SIGNUPS
+ - NEXTAUTH_URL
+ - NEXTAUTH_SECRET
+ - MEILI_ADDR=http://meilisearch:7700
+ - BROWSER_WEB_URL=http://chrome:9222
+ - DATA_DIR=/data
+ chrome:
+ image: gcr.io/zenika-hub/alpine-chrome:124
+ restart: unless-stopped
+ command:
+ - --no-sandbox
+ - --disable-gpu
+ - --disable-dev-shm-usage
+ - --remote-debugging-address=0.0.0.0
+ - --remote-debugging-port=9222
+ - --hide-scrollbars
+ meilisearch:
+ image: getmeili/meilisearch:v1.6
+ restart: unless-stopped
+ environment:
+ - MEILI_MASTER_KEY
+ - MEILI_NO_ANALYTICS="true"
+ volumes:
+ - meilisearch-data:/meili_data
+ healthcheck:
+ test:
+ - CMD
+ - curl
+ - '-f'
+ - 'http://127.0.0.1:7700/health'
+ interval: 2s
+ timeout: 10s
+ retries: 15
+volumes:
+ meilisearch-data:
+ hoarder-data:
\ No newline at end of file
diff --git a/blueprints/hoarder/hoarder.svg b/blueprints/hoarder/hoarder.svg
new file mode 100644
index 000000000..dc8f9f4bf
--- /dev/null
+++ b/blueprints/hoarder/hoarder.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/blueprints/hoarder/template.yml b/blueprints/hoarder/template.yml
new file mode 100644
index 000000000..077324579
--- /dev/null
+++ b/blueprints/hoarder/template.yml
@@ -0,0 +1,18 @@
+variables:
+ main_domain: ${domain}
+ postgres_password: ${password}
+ next_secret: ${base64:32}
+ meili_master_key: ${base64:32}
+
+config:
+ domains:
+ - serviceName: web
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ - NEXTAUTH_SECRET=${next_secret}
+ - MEILI_MASTER_KEY=${meili_master_key}
+ - NEXTAUTH_URL=http://${main_domain}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/homarr/docker-compose.yml b/blueprints/homarr/docker-compose.yml
new file mode 100644
index 000000000..876ea3f6f
--- /dev/null
+++ b/blueprints/homarr/docker-compose.yml
@@ -0,0 +1,11 @@
+services:
+ homarr:
+ image: ghcr.io/homarr-labs/homarr:latest
+ restart: unless-stopped
+ volumes:
+ # - /var/run/docker.sock:/var/run/docker.sock # Optional, only if you want docker integration
+ - ../homarr/appdata:/appdata
+ environment:
+ - SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
+ ports:
+ - 7575
diff --git a/blueprints/homarr/homarr.png b/blueprints/homarr/homarr.png
new file mode 100644
index 000000000..25581ea5c
Binary files /dev/null and b/blueprints/homarr/homarr.png differ
diff --git a/blueprints/homarr/template.yml b/blueprints/homarr/template.yml
new file mode 100644
index 000000000..edbfb1de5
--- /dev/null
+++ b/blueprints/homarr/template.yml
@@ -0,0 +1,14 @@
+variables:
+ main_domain: ${domain}
+ secret_key: ${password:64}
+
+config:
+ domains:
+ - serviceName: homarr
+ port: 7575
+ host: ${main_domain}
+
+ env:
+ - SECRET_ENCRYPTION_KEY=${secret_key}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/huly/docker-compose.yml b/blueprints/huly/docker-compose.yml
new file mode 100644
index 000000000..639b10d2f
--- /dev/null
+++ b/blueprints/huly/docker-compose.yml
@@ -0,0 +1,172 @@
+name: ${DOCKER_NAME}
+version: "3"
+services:
+ nginx:
+
+ image: "nginx:1.21.3"
+ ports:
+ - 80
+ volumes:
+ - ../files/volumes/nginx/.huly.nginx:/etc/nginx/conf.d/default.conf
+ restart: unless-stopped
+
+ mongodb:
+
+ image: "mongo:7-jammy"
+ environment:
+ - PUID=1000
+ - PGID=1000
+ volumes:
+ - db:/data/db
+ restart: unless-stopped
+
+ minio:
+
+ image: "minio/minio:RELEASE.2024-11-07T00-52-20Z"
+ command: server /data --address ":9000" --console-address ":9001"
+ volumes:
+ - files:/data
+ restart: unless-stopped
+
+ elastic:
+
+ image: "elasticsearch:7.14.2"
+ command: |
+ /bin/sh -c "./bin/elasticsearch-plugin list | grep -q ingest-attachment || yes | ./bin/elasticsearch-plugin install --silent ingest-attachment;
+ /usr/local/bin/docker-entrypoint.sh eswrapper"
+ volumes:
+ - elastic:/usr/share/elasticsearch/data
+ environment:
+ - ELASTICSEARCH_PORT_NUMBER=9200
+ - BITNAMI_DEBUG=true
+ - discovery.type=single-node
+ - ES_JAVA_OPTS=-Xms1024m -Xmx1024m
+ - http.cors.enabled=true
+ - http.cors.allow-origin=http://localhost:8082
+ healthcheck:
+ interval: 20s
+ retries: 10
+ test: curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"'
+ restart: unless-stopped
+
+ rekoni:
+
+ image: hardcoreeng/rekoni-service:${HULY_VERSION}
+ environment:
+ - SECRET=${SECRET}
+ deploy:
+ resources:
+ limits:
+ memory: 500M
+ restart: unless-stopped
+
+ transactor:
+
+ image: hardcoreeng/transactor:${HULY_VERSION}
+ environment:
+ - SERVER_PORT=3333
+ - SERVER_SECRET=${SECRET}
+ - SERVER_CURSOR_MAXTIMEMS=30000
+ - DB_URL=mongodb://mongodb:27017
+ - MONGO_URL=mongodb://mongodb:27017
+ - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin
+ - FRONT_URL=http://localhost:8087
+ - ACCOUNTS_URL=http://account:3000
+ - FULLTEXT_URL=http://fulltext:4700
+ - STATS_URL=http://stats:4900
+ - LAST_NAME_FIRST=${LAST_NAME_FIRST:-true}
+ restart: unless-stopped
+
+ collaborator:
+
+ image: hardcoreeng/collaborator:${HULY_VERSION}
+ environment:
+ - COLLABORATOR_PORT=3078
+ - SECRET=${SECRET}
+ - ACCOUNTS_URL=http://account:3000
+ - DB_URL=mongodb://mongodb:27017
+ - STATS_URL=http://stats:4900
+ - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin
+ restart: unless-stopped
+
+ account:
+
+ image: hardcoreeng/account:${HULY_VERSION}
+ environment:
+ - SERVER_PORT=3000
+ - SERVER_SECRET=${SECRET}
+ - DB_URL=mongodb://mongodb:27017
+ - MONGO_URL=mongodb://mongodb:27017
+ - TRANSACTOR_URL=ws://transactor:3333;ws${SECURE:+s}://${HOST_ADDRESS}/_transactor
+ - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin
+ - FRONT_URL=http://front:8080
+ - STATS_URL=http://stats:4900
+ - MODEL_ENABLED=*
+ - ACCOUNTS_URL=http://localhost:3000
+ - ACCOUNT_PORT=3000
+ restart: unless-stopped
+
+ workspace:
+
+ image: hardcoreeng/workspace:${HULY_VERSION}
+ environment:
+ - SERVER_SECRET=${SECRET}
+ - DB_URL=mongodb://mongodb:27017
+ - MONGO_URL=mongodb://mongodb:27017
+ - TRANSACTOR_URL=ws://transactor:3333;ws${SECURE:+s}://${HOST_ADDRESS}/_transactor
+ - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin
+ - MODEL_ENABLED=*
+ - ACCOUNTS_URL=http://account:3000
+ - STATS_URL=http://stats:4900
+ restart: unless-stopped
+
+ front:
+
+ image: hardcoreeng/front:${HULY_VERSION}
+ environment:
+ - SERVER_PORT=8080
+ - SERVER_SECRET=${SECRET}
+ - LOVE_ENDPOINT=http${SECURE:+s}://${HOST_ADDRESS}/_love
+ - ACCOUNTS_URL=http${SECURE:+s}://${HOST_ADDRESS}/_accounts
+ - REKONI_URL=http${SECURE:+s}://${HOST_ADDRESS}/_rekoni
+ - CALENDAR_URL=http${SECURE:+s}://${HOST_ADDRESS}/_calendar
+ - GMAIL_URL=http${SECURE:+s}://${HOST_ADDRESS}/_gmail
+ - TELEGRAM_URL=http${SECURE:+s}://${HOST_ADDRESS}/_telegram
+ - STATS_URL=http${SECURE:+s}://${HOST_ADDRESS}/_stats
+ - UPLOAD_URL=/files
+ - ELASTIC_URL=http://elastic:9200
+ - COLLABORATOR_URL=ws${SECURE:+s}://${HOST_ADDRESS}/_collaborator
+ - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin
+ - DB_URL=mongodb://mongodb:27017
+ - MONGO_URL=mongodb://mongodb:27017
+ - TITLE=${TITLE:-Huly Self Host}
+ - DEFAULT_LANGUAGE=${DEFAULT_LANGUAGE:-en}
+ - LAST_NAME_FIRST=${LAST_NAME_FIRST:-true}
+ - DESKTOP_UPDATES_CHANNEL=selfhost
+ restart: unless-stopped
+
+ fulltext:
+
+ image: hardcoreeng/fulltext:${HULY_VERSION}
+ environment:
+ - SERVER_SECRET=${SECRET}
+ - DB_URL=mongodb://mongodb:27017
+ - FULLTEXT_DB_URL=http://elastic:9200
+ - ELASTIC_INDEX_NAME=huly_storage_index
+ - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin
+ - REKONI_URL=http://rekoni:4004
+ - ACCOUNTS_URL=http://account:3000
+ - STATS_URL=http://stats:4900
+ restart: unless-stopped
+
+ stats:
+
+ image: hardcoreeng/stats:${HULY_VERSION}
+ environment:
+ - PORT=4900
+ - SERVER_SECRET=${SECRET}
+ restart: unless-stopped
+volumes:
+ db:
+ elastic:
+ files:
diff --git a/blueprints/huly/huly.svg b/blueprints/huly/huly.svg
new file mode 100644
index 000000000..55a985878
--- /dev/null
+++ b/blueprints/huly/huly.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blueprints/huly/template.yml b/blueprints/huly/template.yml
new file mode 100644
index 000000000..307e59915
--- /dev/null
+++ b/blueprints/huly/template.yml
@@ -0,0 +1,104 @@
+variables:
+ main_domain: ${domain}
+ huly_secret: ${base64:64}
+
+config:
+ domains:
+ - serviceName: nginx
+ port: 80
+ host: ${main_domain}
+
+ env:
+ - HULY_VERSION=v0.6.377
+ - DOCKER_NAME=huly
+ - HOST_ADDRESS=${main_domain}
+ - SECURE=
+ - HTTP_PORT=80
+ - HTTP_BIND=
+ - TITLE=Huly
+ - DEFAULT_LANGUAGE=en
+ - LAST_NAME_FIRST=true
+ - SECRET=${huly_secret}
+
+ mounts:
+ - filePath: /volumes/nginx/.huly.nginx
+ content: |
+ server {
+ listen 80;
+ server_name _;
+ location / {
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_pass http://front:8080;
+ }
+
+ location /_accounts {
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ rewrite ^/_accounts(/.*)$ $1 break;
+ proxy_pass http://account:3000/;
+ }
+
+ location /_collaborator {
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ rewrite ^/_collaborator(/.*)$ $1 break;
+ proxy_pass http://collaborator:3078/;
+ }
+
+ location /_transactor {
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ rewrite ^/_transactor(/.*)$ $1 break;
+ proxy_pass http://transactor:3333/;
+ }
+
+ location ~ ^/eyJ {
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_pass http://transactor:3333;
+ }
+
+ location /_rekoni {
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ rewrite ^/_rekoni(/.*)$ $1 break;
+ proxy_pass http://rekoni:4004/;
+ }
+
+ location /_stats {
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ rewrite ^/_stats(/.*)$ $1 break;
+ proxy_pass http://stats:4900/;
+ }
+ }
\ No newline at end of file
diff --git a/blueprints/immich/docker-compose.yml b/blueprints/immich/docker-compose.yml
new file mode 100644
index 000000000..743f70acf
--- /dev/null
+++ b/blueprints/immich/docker-compose.yml
@@ -0,0 +1,107 @@
+version: "3.9"
+
+services:
+ immich-server:
+ image: ghcr.io/immich-app/immich-server:v1.121.0
+
+ volumes:
+ - immich-library:/usr/src/app/upload
+ - /etc/localtime:/etc/localtime:ro
+ depends_on:
+ immich-redis:
+ condition: service_healthy
+ immich-database:
+ condition: service_healthy
+ environment:
+ PORT: 2283
+ SERVER_URL: ${SERVER_URL}
+ FRONT_BASE_URL: ${FRONT_BASE_URL}
+ # Database Configuration
+ DB_HOSTNAME: ${DB_HOSTNAME}
+ DB_PORT: ${DB_PORT}
+ DB_USERNAME: ${DB_USERNAME}
+ DB_PASSWORD: ${DB_PASSWORD}
+ DB_DATABASE_NAME: ${DB_DATABASE_NAME}
+ # Redis Configuration
+ REDIS_HOSTNAME: ${REDIS_HOSTNAME}
+ REDIS_PORT: ${REDIS_PORT}
+ REDIS_DBINDEX: ${REDIS_DBINDEX}
+ # Server Configuration
+ TZ: ${TZ}
+ restart: always
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:2283/server-info/ping"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+
+ immich-machine-learning:
+ image: ghcr.io/immich-app/immich-machine-learning:v1.121.0
+
+ volumes:
+ - immich-model-cache:/cache
+ environment:
+ REDIS_HOSTNAME: ${REDIS_HOSTNAME}
+ REDIS_PORT: ${REDIS_PORT}
+ REDIS_DBINDEX: ${REDIS_DBINDEX}
+ restart: always
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:3003/ping"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+
+ immich-redis:
+ image: redis:6.2-alpine
+
+ volumes:
+ - immich-redis-data:/data
+ healthcheck:
+ test: ["CMD", "redis-cli", "ping"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ restart: always
+
+ immich-database:
+ image: tensorchord/pgvecto-rs:pg14-v0.2.0
+
+ volumes:
+ - immich-postgres:/var/lib/postgresql/data
+ environment:
+ POSTGRES_PASSWORD: ${DB_PASSWORD}
+ POSTGRES_USER: ${DB_USERNAME}
+ POSTGRES_DB: immich
+ POSTGRES_INITDB_ARGS: '--data-checksums'
+ healthcheck:
+ test: pg_isready -U ${DB_USERNAME} -d immich || exit 1
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ command:
+ [
+ 'postgres',
+ '-c',
+ 'shared_preload_libraries=vectors.so',
+ '-c',
+ 'search_path="$$user", public, vectors',
+ '-c',
+ 'logging_collector=on',
+ '-c',
+ 'max_wal_size=2GB',
+ '-c',
+ 'shared_buffers=512MB',
+ '-c',
+ 'wal_compression=on',
+ ]
+ restart: always
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ immich-model-cache:
+ immich-postgres:
+ immich-library:
+ immich-redis-data:
\ No newline at end of file
diff --git a/blueprints/immich/immich.svg b/blueprints/immich/immich.svg
new file mode 100644
index 000000000..497fbdcf1
--- /dev/null
+++ b/blueprints/immich/immich.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/immich/template.yml b/blueprints/immich/template.yml
new file mode 100644
index 000000000..8490dbd1c
--- /dev/null
+++ b/blueprints/immich/template.yml
@@ -0,0 +1,26 @@
+variables:
+ main_domain: ${domain}
+ db_password: ${password}
+ db_user: immich
+
+config:
+ domains:
+ - serviceName: immich-server
+ port: 2283
+ host: ${main_domain}
+
+ env:
+ - IMMICH_HOST=${main_domain}
+ - SERVER_URL=https://${main_domain}
+ - FRONT_BASE_URL=https://${main_domain}
+ - DB_HOSTNAME=immich-database
+ - DB_PORT=5432
+ - DB_USERNAME=${db_user}
+ - DB_PASSWORD=${db_password}
+ - DB_DATABASE_NAME=immich
+ - REDIS_HOSTNAME=immich-redis
+ - REDIS_PORT=6379
+ - REDIS_DBINDEX=0
+ - TZ=UTC
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/infisical/docker-compose.yml b/blueprints/infisical/docker-compose.yml
new file mode 100644
index 000000000..7566c8980
--- /dev/null
+++ b/blueprints/infisical/docker-compose.yml
@@ -0,0 +1,83 @@
+services:
+ db-migration:
+ depends_on:
+ db:
+ condition: service_healthy
+ image: infisical/infisical:v0.90.1-postgres
+ environment:
+ - NODE_ENV=production
+ - ENCRYPTION_KEY
+ - AUTH_SECRET
+ - SITE_URL
+ - DB_CONNECTION_URI=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
+ - REDIS_URL=redis://redis:6379
+ - SMTP_HOST
+ - SMTP_PORT
+ - SMTP_FROM_NAME
+ - SMTP_USERNAME
+ - SMTP_PASSWORD
+ - SMTP_SECURE=true
+ command: npm run migration:latest
+ pull_policy: always
+
+
+ backend:
+ restart: unless-stopped
+ depends_on:
+ db:
+ condition: service_healthy
+ redis:
+ condition: service_started
+ db-migration:
+ condition: service_completed_successfully
+ image: infisical/infisical:v0.90.1-postgres
+ pull_policy: always
+ environment:
+ - NODE_ENV=production
+ - ENCRYPTION_KEY
+ - AUTH_SECRET
+ - SITE_URL
+ - DB_CONNECTION_URI=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
+ - REDIS_URL=redis://redis:6379
+ - SMTP_HOST
+ - SMTP_PORT
+ - SMTP_FROM_NAME
+ - SMTP_USERNAME
+ - SMTP_PASSWORD
+ - SMTP_SECURE=true
+
+
+ redis:
+ image: redis:7.4.1
+ env_file: .env
+ restart: always
+ environment:
+ - ALLOW_EMPTY_PASSWORD=yes
+
+ volumes:
+ - redis_infisical_data:/data
+
+ db:
+ image: postgres:14-alpine
+ restart: always
+ environment:
+ - POSTGRES_PASSWORD
+ - POSTGRES_USER
+ - POSTGRES_DB
+ volumes:
+ - pg_infisical_data:/var/lib/postgresql/data
+
+ healthcheck:
+ test: "pg_isready --username=${POSTGRES_USER} && psql --username=${POSTGRES_USER} --list"
+ interval: 5s
+ timeout: 10s
+ retries: 10
+
+volumes:
+ pg_infisical_data:
+ redis_infisical_data:
+
+networks:
+ dokploy-network:
+ external: true
+
diff --git a/blueprints/infisical/infisical.jpg b/blueprints/infisical/infisical.jpg
new file mode 100644
index 000000000..404f58119
Binary files /dev/null and b/blueprints/infisical/infisical.jpg differ
diff --git a/blueprints/infisical/template.yml b/blueprints/infisical/template.yml
new file mode 100644
index 000000000..79513b096
--- /dev/null
+++ b/blueprints/infisical/template.yml
@@ -0,0 +1,58 @@
+variables:
+ main_domain: ${domain}
+ postgres_password: ${password}
+ postgres_user: infisical
+ postgres_db: infisical
+
+config:
+ domains:
+ - serviceName: backend
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ - ENCRYPTION_KEY=6c1fe4e407b8911c104518103505b218 # Sample key, not for production
+ - AUTH_SECRET=5lrMXKKWCVocS/uerPsl7V+TX/aaUaI7iDkgl3tSmLE= # Sample key, not for production
+ - POSTGRES_PASSWORD=${postgres_password}
+ - POSTGRES_USER=${postgres_user}
+ - POSTGRES_DB=${postgres_db}
+ - SITE_URL=http://${main_domain}:8080
+ - SMTP_HOST=
+ - SMTP_PORT=
+ - SMTP_NAME=
+ - SMTP_USERNAME=
+ - SMTP_PASSWORD=
+ - CLIENT_ID_HEROKU=
+ - CLIENT_ID_VERCEL=
+ - CLIENT_ID_NETLIFY=
+ - CLIENT_ID_GITHUB=
+ - CLIENT_ID_GITHUB_APP=
+ - CLIENT_SLUG_GITHUB_APP=
+ - CLIENT_ID_GITLAB=
+ - CLIENT_ID_BITBUCKET=
+ - CLIENT_SECRET_HEROKU=
+ - CLIENT_SECRET_VERCEL=
+ - CLIENT_SECRET_NETLIFY=
+ - CLIENT_SECRET_GITHUB=
+ - CLIENT_SECRET_GITHUB_APP=
+ - CLIENT_SECRET_GITLAB=
+ - CLIENT_SECRET_BITBUCKET=
+ - CLIENT_SLUG_VERCEL=
+ - CLIENT_PRIVATE_KEY_GITHUB_APP=
+ - CLIENT_APP_ID_GITHUB_APP=
+ - SENTRY_DSN=
+ - POSTHOG_HOST=
+ - POSTHOG_PROJECT_API_KEY=
+ - CLIENT_ID_GOOGLE_LOGIN=
+ - CLIENT_SECRET_GOOGLE_LOGIN=
+ - CLIENT_ID_GITHUB_LOGIN=
+ - CLIENT_SECRET_GITHUB_LOGIN=
+ - CLIENT_ID_GITLAB_LOGIN=
+ - CLIENT_SECRET_GITLAB_LOGIN=
+ - CAPTCHA_SECRET=
+ - NEXT_PUBLIC_CAPTCHA_SITE_KEY=
+ - PLAIN_API_KEY=
+ - PLAIN_WISH_LABEL_IDS=
+ - SSL_CLIENT_CERTIFICATE_HEADER_KEY=
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/influxdb/docker-compose.yml b/blueprints/influxdb/docker-compose.yml
new file mode 100644
index 000000000..1327c6028
--- /dev/null
+++ b/blueprints/influxdb/docker-compose.yml
@@ -0,0 +1,11 @@
+services:
+ influxdb:
+ image: influxdb:2.7.10
+ restart: unless-stopped
+ volumes:
+ - influxdb2-data:/var/lib/influxdb2
+ - influxdb2-config:/etc/influxdb2
+
+volumes:
+ influxdb2-data:
+ influxdb2-config:
\ No newline at end of file
diff --git a/blueprints/influxdb/influxdb.png b/blueprints/influxdb/influxdb.png
new file mode 100644
index 000000000..8fc62a7fb
Binary files /dev/null and b/blueprints/influxdb/influxdb.png differ
diff --git a/blueprints/influxdb/template.yml b/blueprints/influxdb/template.yml
new file mode 100644
index 000000000..4d32a7063
--- /dev/null
+++ b/blueprints/influxdb/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: influxdb
+ port: 8086
+ host: ${main_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/invoiceshelf/docker-compose.yml b/blueprints/invoiceshelf/docker-compose.yml
new file mode 100644
index 000000000..ef47f1c04
--- /dev/null
+++ b/blueprints/invoiceshelf/docker-compose.yml
@@ -0,0 +1,57 @@
+version: "3.8"
+
+services:
+ invoiceshelf-postgres:
+ image: postgres:15
+
+ volumes:
+ - invoiceshelf-postgres-data:/var/lib/postgresql/data
+ environment:
+ - POSTGRES_PASSWORD=${DB_PASSWORD}
+ - POSTGRES_USER=${DB_USERNAME}
+ - POSTGRES_DB=${DB_DATABASE}
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME}"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+ invoiceshelf-app:
+ image: invoiceshelf/invoiceshelf:latest
+
+ volumes:
+ - invoiceshelf-app-data:/data
+ - invoiceshelf-app-conf:/conf
+ environment:
+ - PHP_TZ=UTC
+ - TIMEZONE=UTC
+ - APP_NAME=InvoiceShelf
+ - APP_ENV=production
+ - APP_DEBUG=false
+ - APP_URL=http://${INVOICESHELF_HOST}
+ - DB_CONNECTION=pgsql
+ - DB_HOST=invoiceshelf-postgres
+ - DB_PORT=5432
+ - DB_DATABASE=${DB_DATABASE}
+ - DB_USERNAME=${DB_USERNAME}
+ - DB_PASSWORD=${DB_PASSWORD}
+ - CACHE_STORE=file
+ - SESSION_DRIVER=file
+ - SESSION_LIFETIME=120
+ - SESSION_ENCRYPT=true
+ - SESSION_PATH=/
+ - SESSION_DOMAIN=${INVOICESHELF_HOST}
+ - SANCTUM_STATEFUL_DOMAINS=${INVOICESHELF_HOST}
+ - STARTUP_DELAY=10
+ depends_on:
+ invoiceshelf-postgres:
+ condition: service_healthy
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ invoiceshelf-postgres-data:
+ invoiceshelf-app-data:
+ invoiceshelf-app-conf:
\ No newline at end of file
diff --git a/blueprints/invoiceshelf/invoiceshelf.png b/blueprints/invoiceshelf/invoiceshelf.png
new file mode 100644
index 000000000..cee025e02
Binary files /dev/null and b/blueprints/invoiceshelf/invoiceshelf.png differ
diff --git a/blueprints/invoiceshelf/template.yml b/blueprints/invoiceshelf/template.yml
new file mode 100644
index 000000000..63ef33c13
--- /dev/null
+++ b/blueprints/invoiceshelf/template.yml
@@ -0,0 +1,19 @@
+variables:
+ main_domain: ${domain}
+ db_password: ${password}
+ db_username: "invoiceshelf"
+ db_database: "invoiceshelf"
+
+config:
+ domains:
+ - serviceName: invoiceshelf-app
+ port: 80
+ host: ${main_domain}
+
+ env:
+ INVOICESHELF_HOST: ${main_domain}
+ DB_PASSWORD: ${db_password}
+ DB_USERNAME: ${db_username}
+ DB_DATABASE: ${db_database}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/it-tools/docker-compose.yml b/blueprints/it-tools/docker-compose.yml
new file mode 100644
index 000000000..b26665f8a
--- /dev/null
+++ b/blueprints/it-tools/docker-compose.yml
@@ -0,0 +1,8 @@
+services:
+ it-tools:
+ image: corentinth/it-tools:latest
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
diff --git a/blueprints/it-tools/it-tools.svg b/blueprints/it-tools/it-tools.svg
new file mode 100644
index 000000000..1e3b614da
--- /dev/null
+++ b/blueprints/it-tools/it-tools.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/blueprints/it-tools/template.yml b/blueprints/it-tools/template.yml
new file mode 100644
index 000000000..b7ff3128d
--- /dev/null
+++ b/blueprints/it-tools/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: it-tools
+ port: 80
+ host: ${main_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/jellyfin/docker-compose.yml b/blueprints/jellyfin/docker-compose.yml
new file mode 100644
index 000000000..cb61476ab
--- /dev/null
+++ b/blueprints/jellyfin/docker-compose.yml
@@ -0,0 +1,19 @@
+version: "3.8"
+services:
+ jellyfin:
+ image: jellyfin/jellyfin:10
+ volumes:
+ - config:/config
+ - cache:/cache
+ - media:/media
+ restart: "unless-stopped"
+ # Optional - alternative address used for autodiscovery
+ environment:
+ - JELLYFIN_PublishedServerUrl=http://${JELLYFIN_HOST}
+ # Optional - may be necessary for docker healthcheck to pass if running in host network mode
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
+volumes:
+ config:
+ cache:
+ media:
diff --git a/blueprints/jellyfin/jellyfin.svg b/blueprints/jellyfin/jellyfin.svg
new file mode 100644
index 000000000..4227a7064
--- /dev/null
+++ b/blueprints/jellyfin/jellyfin.svg
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+ banner-light
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/jellyfin/template.yml b/blueprints/jellyfin/template.yml
new file mode 100644
index 000000000..f8c5c8a09
--- /dev/null
+++ b/blueprints/jellyfin/template.yml
@@ -0,0 +1,13 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: jellyfin
+ port: 8096
+ host: ${main_domain}
+
+ env:
+ JELLYFIN_HOST: ${main_domain}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/kimai/docker-compose.yml b/blueprints/kimai/docker-compose.yml
new file mode 100644
index 000000000..253ecb004
--- /dev/null
+++ b/blueprints/kimai/docker-compose.yml
@@ -0,0 +1,49 @@
+services:
+ app:
+ image: kimai/kimai2:apache-2.26.0
+ restart: unless-stopped
+ environment:
+ APP_ENV: prod
+ DATABASE_URL: mysql://kimai:${KI_MYSQL_PASSWORD:-kimai}@db/kimai
+ TRUSTED_PROXIES: localhost
+ APP_SECRET: ${KI_APP_SECRET}
+ MAILER_FROM: ${KI_MAILER_FROM:-admin@kimai.local}
+ MAILER_URL: ${KI_MAILER_URL:-null://null}
+ ADMINMAIL: ${KI_ADMINMAIL:-admin@kimai.local}
+ ADMINPASS: ${KI_ADMINPASS}
+ volumes:
+ - kimai-data:/opt/kimai/var
+ depends_on:
+ db:
+ condition: service_healthy
+
+ db:
+ image: mariadb:10.11
+ restart: unless-stopped
+ environment:
+ - MYSQL_DATABASE=kimai
+ - MYSQL_USER=kimai
+ - MYSQL_PASSWORD=${KI_MYSQL_PASSWORD}
+ - MYSQL_ROOT_PASSWORD=${KI_MYSQL_ROOT_PASSWORD}
+ volumes:
+ - mysql-data:/var/lib/mysql
+ command:
+ - --character-set-server=utf8mb4
+ - --collation-server=utf8mb4_unicode_ci
+ - --innodb-buffer-pool-size=256M
+ - --innodb-flush-log-at-trx-commit=2
+ healthcheck:
+ test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "kimai", "-p${KI_MYSQL_PASSWORD}"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ start_period: 30s
+
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ kimai-data:
+ mysql-data:
\ No newline at end of file
diff --git a/blueprints/kimai/kimai.svg b/blueprints/kimai/kimai.svg
new file mode 100644
index 000000000..8b2a6c1e5
--- /dev/null
+++ b/blueprints/kimai/kimai.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blueprints/kimai/template.yml b/blueprints/kimai/template.yml
new file mode 100644
index 000000000..53852e28d
--- /dev/null
+++ b/blueprints/kimai/template.yml
@@ -0,0 +1,22 @@
+variables:
+ main_domain: ${domain}
+ admin_password: ${password:32}
+ mysql_password: ${password:32}
+ mysql_root_password: ${password:32}
+ app_secret: ${password:32}
+
+config:
+ domains:
+ - serviceName: app
+ port: 8001
+ host: ${main_domain}
+
+ env:
+ KI_HOST: ${main_domain}
+ KI_ADMINMAIL: "admin@kimai.local"
+ KI_ADMINPASS: ${admin_password}
+ KI_MYSQL_ROOT_PASSWORD: ${mysql_root_password}
+ KI_MYSQL_PASSWORD: ${mysql_password}
+ KI_APP_SECRET: ${app_secret}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/langflow/docker-compose.yml b/blueprints/langflow/docker-compose.yml
new file mode 100644
index 000000000..a96282868
--- /dev/null
+++ b/blueprints/langflow/docker-compose.yml
@@ -0,0 +1,31 @@
+version: "3.8"
+
+services:
+ langflow:
+ image: langflowai/langflow:v1.1.1
+ ports:
+ - 7860
+ depends_on:
+ - postgres-langflow
+ environment:
+ - LANGFLOW_DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres-langflow:5432/langflow
+ # This variable defines where the logs, file storage, monitor data and secret keys are stored.
+ volumes:
+ - langflow-data:/app/langflow
+
+
+ postgres-langflow:
+ image: postgres:16
+ environment:
+ POSTGRES_USER: ${DB_USERNAME}
+ POSTGRES_PASSWORD: ${DB_PASSWORD}
+ POSTGRES_DB: langflow
+ ports:
+ - 5432
+ volumes:
+ - langflow-postgres:/var/lib/postgresql/data
+
+
+volumes:
+ langflow-postgres:
+ langflow-data:
\ No newline at end of file
diff --git a/blueprints/langflow/langflow.svg b/blueprints/langflow/langflow.svg
new file mode 100644
index 000000000..3665f824b
--- /dev/null
+++ b/blueprints/langflow/langflow.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/blueprints/langflow/template.yml b/blueprints/langflow/template.yml
new file mode 100644
index 000000000..73b61ea22
--- /dev/null
+++ b/blueprints/langflow/template.yml
@@ -0,0 +1,16 @@
+variables:
+ main_domain: ${domain}
+ db_password: ${password}
+ db_username: "langflow"
+
+config:
+ domains:
+ - serviceName: langflow
+ port: 7860
+ host: ${main_domain}
+
+ env:
+ DB_PASSWORD: ${db_password}
+ DB_USERNAME: ${db_username}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/linkwarden/docker-compose.yml b/blueprints/linkwarden/docker-compose.yml
new file mode 100644
index 000000000..05ffb8a0a
--- /dev/null
+++ b/blueprints/linkwarden/docker-compose.yml
@@ -0,0 +1,40 @@
+services:
+ linkwarden:
+ environment:
+ - NEXTAUTH_SECRET
+ - NEXTAUTH_URL
+ - DATABASE_URL=postgresql://linkwarden:${POSTGRES_PASSWORD}@postgres:5432/linkwarden
+ restart: unless-stopped
+ image: ghcr.io/linkwarden/linkwarden:v2.9.3
+ ports:
+ - 3000
+ volumes:
+ - linkwarden-data:/data/data
+ depends_on:
+ - postgres
+ healthcheck:
+ test: curl --fail http://localhost:3000 || exit 1
+ interval: 60s
+ retries: 2
+ start_period: 60s
+ timeout: 15s
+
+ postgres:
+ image: postgres:17-alpine
+ restart: unless-stopped
+ user: postgres
+ environment:
+ POSTGRES_USER: linkwarden
+ POSTGRES_DB: linkwarden
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+ volumes:
+ - postgres-data:/var/lib/postgresql/data
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+volumes:
+ linkwarden-data:
+ postgres-data:
diff --git a/blueprints/linkwarden/linkwarden.png b/blueprints/linkwarden/linkwarden.png
new file mode 100644
index 000000000..843f681eb
Binary files /dev/null and b/blueprints/linkwarden/linkwarden.png differ
diff --git a/blueprints/linkwarden/template.yml b/blueprints/linkwarden/template.yml
new file mode 100644
index 000000000..a3930a491
--- /dev/null
+++ b/blueprints/linkwarden/template.yml
@@ -0,0 +1,17 @@
+variables:
+ main_domain: ${domain}
+ postgres_password: ${password}
+ next_secret: ${base64:32}
+
+config:
+ domains:
+ - serviceName: linkwarden
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ POSTGRES_PASSWORD: ${postgres_password}
+ NEXTAUTH_SECRET: ${next_secret}
+ NEXTAUTH_URL: http://${main_domain}/api/v1/auth
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/listmonk/docker-compose.yml b/blueprints/listmonk/docker-compose.yml
new file mode 100644
index 000000000..d9da8b50e
--- /dev/null
+++ b/blueprints/listmonk/docker-compose.yml
@@ -0,0 +1,49 @@
+services:
+ db:
+ image: postgres:17-alpine
+ ports:
+ - 5432
+
+ environment:
+ - POSTGRES_PASSWORD=listmonk
+ - POSTGRES_USER=listmonk
+ - POSTGRES_DB=listmonk
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U listmonk"]
+ interval: 10s
+ timeout: 5s
+ retries: 6
+ volumes:
+ - listmonk-data:/var/lib/postgresql/data
+
+ setup:
+ image: listmonk/listmonk:v4.1.0
+
+ volumes:
+ - ../files/config.toml:/listmonk/config.toml
+ depends_on:
+ - db
+ command:
+ [
+ sh,
+ -c,
+ "sleep 3 && ./listmonk --install --idempotent --yes --config config.toml",
+ ]
+
+ app:
+ restart: unless-stopped
+ image: listmonk/listmonk:v4.1.0
+ environment:
+ - TZ=Etc/UTC
+ depends_on:
+ - db
+ - setup
+ volumes:
+ - ../files/config.toml:/listmonk/config.toml
+ - listmonk-uploads:/listmonk/uploads
+
+volumes:
+ listmonk-uploads:
+ listmonk-data:
+ driver: local
diff --git a/blueprints/listmonk/listmonk.png b/blueprints/listmonk/listmonk.png
new file mode 100644
index 000000000..cd6f5618e
Binary files /dev/null and b/blueprints/listmonk/listmonk.png differ
diff --git a/blueprints/listmonk/template.yml b/blueprints/listmonk/template.yml
new file mode 100644
index 000000000..b0664be96
--- /dev/null
+++ b/blueprints/listmonk/template.yml
@@ -0,0 +1,32 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: app
+ port: 9000
+ host: ${main_domain}
+
+ env:
+ # visit the page to setup your super admin user
+ # check config.toml in Advanced / Volumes for more options
+
+ mounts:
+ - filePath: config.toml
+ content: |
+ [app]
+ address = "0.0.0.0:9000"
+
+ [db]
+ host = "db"
+ port = 5432
+ user = "listmonk"
+ password = "listmonk"
+ database = "listmonk"
+
+ ssl_mode = "disable"
+ max_open = 25
+ max_idle = 25
+ max_lifetime = "300s"
+
+ params = ""
\ No newline at end of file
diff --git a/blueprints/lobe-chat/docker-compose.yml b/blueprints/lobe-chat/docker-compose.yml
new file mode 100644
index 000000000..676140903
--- /dev/null
+++ b/blueprints/lobe-chat/docker-compose.yml
@@ -0,0 +1,12 @@
+version: '3.8'
+
+services:
+ lobe-chat:
+ image: lobehub/lobe-chat:v1.26.1
+ restart: always
+ ports:
+ - 3210
+ environment:
+ OPENAI_API_KEY: sk-xxxx
+ OPENAI_PROXY_URL: https://api-proxy.com/v1
+ ACCESS_CODE: lobe66
\ No newline at end of file
diff --git a/blueprints/lobe-chat/lobe-chat.png b/blueprints/lobe-chat/lobe-chat.png
new file mode 100644
index 000000000..cc29879cf
Binary files /dev/null and b/blueprints/lobe-chat/lobe-chat.png differ
diff --git a/blueprints/lobe-chat/template.yml b/blueprints/lobe-chat/template.yml
new file mode 100644
index 000000000..b75d0d9de
--- /dev/null
+++ b/blueprints/lobe-chat/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: lobe-chat
+ port: 3210
+ host: ${main_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/logto/docker-compose.yml b/blueprints/logto/docker-compose.yml
new file mode 100644
index 000000000..6f2b920a0
--- /dev/null
+++ b/blueprints/logto/docker-compose.yml
@@ -0,0 +1,40 @@
+services:
+ app:
+ depends_on:
+ postgres:
+ condition: service_healthy
+ image: svhd/logto:1.22.0
+ entrypoint: ["sh", "-c", "npm run cli db seed -- --swe && npm start"]
+ ports:
+ - 3001
+ - 3002
+
+ environment:
+ TRUST_PROXY_HEADER: 1
+ DB_URL: postgres://logto:${LOGTO_POSTGRES_PASSWORD}@postgres:5432/logto
+ ENDPOINT: ${LOGTO_ENDPOINT}
+ ADMIN_ENDPOINT: ${LOGTO_ADMIN_ENDPOINT}
+ volumes:
+ - logto-connectors:/etc/logto/packages/core/connectors
+ postgres:
+ image: postgres:17-alpine
+ user: postgres
+
+ environment:
+ POSTGRES_USER: logto
+ POSTGRES_PASSWORD: ${LOGTO_POSTGRES_PASSWORD}
+ volumes:
+ - postgres-data:/var/lib/postgresql/data
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ logto-connectors:
+ postgres-data:
diff --git a/blueprints/logto/logto.png b/blueprints/logto/logto.png
new file mode 100644
index 000000000..c7bfec1d8
Binary files /dev/null and b/blueprints/logto/logto.png differ
diff --git a/blueprints/logto/template.yml b/blueprints/logto/template.yml
new file mode 100644
index 000000000..7fe7f99ce
--- /dev/null
+++ b/blueprints/logto/template.yml
@@ -0,0 +1,20 @@
+variables:
+ main_domain: ${domain}
+ admin_domain: ${domain}
+ postgres_password: ${password}
+
+config:
+ domains:
+ - serviceName: app
+ port: 3001
+ host: ${main_domain}
+ - serviceName: app
+ port: 3002
+ host: ${admin_domain}
+
+ env:
+ LOGTO_ENDPOINT: http://${admin_domain}
+ LOGTO_ADMIN_ENDPOINT: http://${admin_domain}
+ LOGTO_POSTGRES_PASSWORD: ${postgres_password}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/macos/docker-compose.yml b/blueprints/macos/docker-compose.yml
new file mode 100644
index 000000000..585c1bf97
--- /dev/null
+++ b/blueprints/macos/docker-compose.yml
@@ -0,0 +1,16 @@
+services:
+ macos:
+ image: dockurr/macos:1.14
+ volumes:
+ - macos-storage:/storage
+ environment:
+ - VERSION
+ devices:
+ # If in .env string 'KVM=N' is not commented, you need to comment line below
+ - /dev/kvm
+ cap_add:
+ - NET_ADMIN
+ stop_grace_period: 2m
+
+volumes:
+ macos-storage:
\ No newline at end of file
diff --git a/blueprints/macos/macos.png b/blueprints/macos/macos.png
new file mode 100644
index 000000000..617122c87
Binary files /dev/null and b/blueprints/macos/macos.png differ
diff --git a/blueprints/macos/template.yml b/blueprints/macos/template.yml
new file mode 100644
index 000000000..41693bedc
--- /dev/null
+++ b/blueprints/macos/template.yml
@@ -0,0 +1,21 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: macos
+ port: 8006
+ host: ${main_domain}
+
+ env:
+ # https://github.com/dockur/macos?tab=readme-ov-file#how-do-i-select-the-macos-version
+ VERSION: "15"
+
+ # Uncomment this if your PC/VM or etc does not support virtualization technology
+ # KVM: "N"
+
+ DISK_SIZE: "64G"
+ RAM_SIZE: "4G"
+ CPU_CORES: "2"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/mailpit/docker-compose.yml b/blueprints/mailpit/docker-compose.yml
new file mode 100644
index 000000000..d0dbdb8ec
--- /dev/null
+++ b/blueprints/mailpit/docker-compose.yml
@@ -0,0 +1,25 @@
+services:
+ mailpit:
+ image: axllent/mailpit:v1.22.3
+ restart: unless-stopped
+ ports:
+ - '1025:1025'
+ volumes:
+ - 'mailpit-data:/data'
+ environment:
+ - MP_SMTP_AUTH_ALLOW_INSECURE=true
+ - MP_MAX_MESSAGES=5000
+ - MP_DATABASE=/data/mailpit.db
+ - MP_UI_AUTH=${MP_UI_AUTH}
+ - MP_SMTP_AUTH=${MP_SMTP_AUTH}
+ healthcheck:
+ test:
+ - CMD
+ - /mailpit
+ - readyz
+ interval: 5s
+ timeout: 20s
+ retries: 10
+
+volumes:
+ mailpit-data:
\ No newline at end of file
diff --git a/blueprints/mailpit/mailpit.svg b/blueprints/mailpit/mailpit.svg
new file mode 100644
index 000000000..58675a267
--- /dev/null
+++ b/blueprints/mailpit/mailpit.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/mailpit/template.yml b/blueprints/mailpit/template.yml
new file mode 100644
index 000000000..856d58e37
--- /dev/null
+++ b/blueprints/mailpit/template.yml
@@ -0,0 +1,16 @@
+variables:
+ main_domain: ${domain}
+ default_password: ${password}
+
+config:
+ domains:
+ - serviceName: mailpit
+ port: 8025
+ host: ${main_domain}
+
+ env:
+ # Uncomment below if you want basic auth on UI and SMTP
+ #MP_UI_AUTH: mailpit:${default_password}
+ #MP_SMTP_AUTH: mailpit:${default_password}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/maybe/docker-compose.yml b/blueprints/maybe/docker-compose.yml
new file mode 100644
index 000000000..db529e0a7
--- /dev/null
+++ b/blueprints/maybe/docker-compose.yml
@@ -0,0 +1,36 @@
+services:
+ app:
+ image: ghcr.io/maybe-finance/maybe:sha-68c570eed8810fd59b5b33cca51bbad5eabb4cb4
+ restart: unless-stopped
+ volumes:
+ - ../files/uploads:/app/uploads
+ environment:
+ DATABASE_URL: postgresql://maybe:maybe@db:5432/maybe
+ SECRET_KEY_BASE: ${SECRET_KEY_BASE}
+ SELF_HOSTED: true
+ SYNTH_API_KEY: ${SYNTH_API_KEY}
+ RAILS_FORCE_SSL: "false"
+ RAILS_ASSUME_SSL: "false"
+ GOOD_JOB_EXECUTION_MODE: async
+ depends_on:
+ db:
+ condition: service_healthy
+
+ db:
+ image: postgres:16
+ restart: always
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
+ interval: 5s
+ timeout: 5s
+ retries: 5
+
+ volumes:
+ - db-data:/var/lib/postgresql/data
+ environment:
+ POSTGRES_DB: maybe
+ POSTGRES_USER: maybe
+ POSTGRES_PASSWORD: maybe
+
+volumes:
+ db-data:
diff --git a/blueprints/maybe/maybe.svg b/blueprints/maybe/maybe.svg
new file mode 100644
index 000000000..a4a877360
--- /dev/null
+++ b/blueprints/maybe/maybe.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/maybe/template.yml b/blueprints/maybe/template.yml
new file mode 100644
index 000000000..ab9648ac7
--- /dev/null
+++ b/blueprints/maybe/template.yml
@@ -0,0 +1,22 @@
+variables:
+ main_domain: ${domain}
+ secret_key_base: ${base64:64}
+ synth_api_key: ${base64:32}
+
+config:
+ domains:
+ - serviceName: app
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ SECRET_KEY_BASE: ${secret_key_base}
+ SELF_HOSTED: "true"
+ SYNTH_API_KEY: ${synth_api_key}
+ RAILS_FORCE_SSL: "false"
+ RAILS_ASSUME_SSL: "false"
+ GOOD_JOB_EXECUTION_MODE: "async"
+
+ mounts:
+ - filePath: ./uploads
+ content: "This is where user uploads will be stored"
\ No newline at end of file
diff --git a/blueprints/meilisearch/docker-compose.yml b/blueprints/meilisearch/docker-compose.yml
new file mode 100644
index 000000000..ae5ebcb1a
--- /dev/null
+++ b/blueprints/meilisearch/docker-compose.yml
@@ -0,0 +1,14 @@
+version: "3.8"
+
+services:
+ meilisearch:
+ image: getmeili/meilisearch:v1.8.3
+ volumes:
+ - meili_data:/meili_data
+ environment:
+ MEILI_MASTER_KEY: ${MEILI_MASTER_KEY}
+ MEILI_ENV: ${MEILI_ENV}
+
+volumes:
+ meili_data:
+ driver: local
diff --git a/blueprints/meilisearch/meilisearch.png b/blueprints/meilisearch/meilisearch.png
new file mode 100644
index 000000000..7bbb458fa
Binary files /dev/null and b/blueprints/meilisearch/meilisearch.png differ
diff --git a/blueprints/meilisearch/template.yml b/blueprints/meilisearch/template.yml
new file mode 100644
index 000000000..eb7dac7d8
--- /dev/null
+++ b/blueprints/meilisearch/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+ master_key: ${base64:32}
+
+config:
+ domains:
+ - serviceName: meilisearch
+ port: 7700
+ host: ${main_domain}
+
+ env:
+ MEILI_ENV: "development"
+ MEILI_MASTER_KEY: ${master_key}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/metabase/docker-compose.yml b/blueprints/metabase/docker-compose.yml
new file mode 100644
index 000000000..43a03987d
--- /dev/null
+++ b/blueprints/metabase/docker-compose.yml
@@ -0,0 +1,25 @@
+version: "3.8"
+services:
+ metabase:
+ image: metabase/metabase:v0.50.8
+ volumes:
+ - /dev/urandom:/dev/random:ro
+ environment:
+ MB_DB_TYPE: postgres
+ MB_DB_DBNAME: metabaseappdb
+ MB_DB_PORT: 5432
+ MB_DB_USER: metabase
+ MB_DB_PASS: mysecretpassword
+ MB_DB_HOST: postgres
+ healthcheck:
+ test: curl --fail -I http://localhost:3000/api/health || exit 1
+ interval: 15s
+ timeout: 5s
+ retries: 5
+ postgres:
+ image: postgres:14
+ environment:
+ POSTGRES_USER: metabase
+ POSTGRES_DB: metabaseappdb
+ POSTGRES_PASSWORD: mysecretpassword
+
diff --git a/blueprints/metabase/metabase.png b/blueprints/metabase/metabase.png
new file mode 100644
index 000000000..189e5a33a
Binary files /dev/null and b/blueprints/metabase/metabase.png differ
diff --git a/blueprints/metabase/template.yml b/blueprints/metabase/template.yml
new file mode 100644
index 000000000..34f18481b
--- /dev/null
+++ b/blueprints/metabase/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: metabase
+ port: 3000
+ host: ${main_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/minio/docker-compose.yml b/blueprints/minio/docker-compose.yml
new file mode 100644
index 000000000..4b24bbcce
--- /dev/null
+++ b/blueprints/minio/docker-compose.yml
@@ -0,0 +1,13 @@
+version: "3.8"
+services:
+ minio:
+ image: minio/minio
+ volumes:
+ - minio-data:/data
+ environment:
+ - MINIO_ROOT_USER=minioadmin
+ - MINIO_ROOT_PASSWORD=minioadmin123
+ command: server /data --console-address ":9001"
+
+volumes:
+ minio-data:
diff --git a/blueprints/minio/minio.png b/blueprints/minio/minio.png
new file mode 100644
index 000000000..38f6ff9f0
Binary files /dev/null and b/blueprints/minio/minio.png differ
diff --git a/blueprints/minio/template.yml b/blueprints/minio/template.yml
new file mode 100644
index 000000000..c508d8f02
--- /dev/null
+++ b/blueprints/minio/template.yml
@@ -0,0 +1,16 @@
+variables:
+ main_domain: ${domain}
+ api_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: minio
+ port: 9001
+ host: ${main_domain}
+ - serviceName: minio
+ port: 9000
+ host: ${api_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/n8n/docker-compose.yml b/blueprints/n8n/docker-compose.yml
new file mode 100644
index 000000000..d810fa333
--- /dev/null
+++ b/blueprints/n8n/docker-compose.yml
@@ -0,0 +1,18 @@
+version: "3.8"
+services:
+ n8n:
+ image: docker.n8n.io/n8nio/n8n:1.70.3
+ restart: always
+ environment:
+ - N8N_HOST=${N8N_HOST}
+ - N8N_PORT=${N8N_PORT}
+ - N8N_PROTOCOL=http
+ - NODE_ENV=production
+ - WEBHOOK_URL=https://${N8N_HOST}/
+ - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
+ - N8N_SECURE_COOKIE=false
+ volumes:
+ - n8n_data:/home/node/.n8n
+
+volumes:
+ n8n_data:
diff --git a/blueprints/n8n/n8n.png b/blueprints/n8n/n8n.png
new file mode 100644
index 000000000..0e9a607e2
Binary files /dev/null and b/blueprints/n8n/n8n.png differ
diff --git a/blueprints/n8n/template.yml b/blueprints/n8n/template.yml
new file mode 100644
index 000000000..f1e19c97c
--- /dev/null
+++ b/blueprints/n8n/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: n8n
+ port: 5678
+ host: ${main_domain}
+
+ env:
+ N8N_HOST: ${main_domain}
+ N8N_PORT: "5678"
+ GENERIC_TIMEZONE: "Europe/Berlin"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/nextcloud-aio/docker-compose.yml b/blueprints/nextcloud-aio/docker-compose.yml
new file mode 100644
index 000000000..1e6d00fe3
--- /dev/null
+++ b/blueprints/nextcloud-aio/docker-compose.yml
@@ -0,0 +1,36 @@
+services:
+ nextcloud:
+ image: nextcloud:30.0.2
+ restart: always
+
+ ports:
+ - 80
+ volumes:
+ - nextcloud_data:/var/www/html
+ environment:
+ - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_DOMAIN}
+ - MYSQL_HOST=nextcloud_db
+ - MYSQL_DATABASE=nextcloud
+ - MYSQL_USER=nextcloud
+ - MYSQL_PASSWORD=${MYSQL_SECRET_PASSWORD}
+ - OVERWRITEPROTOCOL=https
+
+ nextcloud_db:
+ image: mariadb
+ restart: always
+
+ volumes:
+ - nextcloud_db_data:/var/lib/mysql
+ environment:
+ - MYSQL_ROOT_PASSWORD=${MYSQL_SECRET_PASSWORD_ROOT}
+ - MYSQL_DATABASE=nextcloud
+ - MYSQL_USER=nextcloud
+ - MYSQL_PASSWORD=${MYSQL_SECRET_PASSWORD}
+
+volumes:
+ nextcloud_data:
+ nextcloud_db_data:
+
+networks:
+ dokploy-network:
+ external: true
diff --git a/blueprints/nextcloud-aio/nextcloud-aio.svg b/blueprints/nextcloud-aio/nextcloud-aio.svg
new file mode 100644
index 000000000..54e6056fa
--- /dev/null
+++ b/blueprints/nextcloud-aio/nextcloud-aio.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blueprints/nextcloud-aio/template.yml b/blueprints/nextcloud-aio/template.yml
new file mode 100644
index 000000000..4666a8567
--- /dev/null
+++ b/blueprints/nextcloud-aio/template.yml
@@ -0,0 +1,17 @@
+variables:
+ main_domain: ${domain}
+ db_password: ${password}
+ db_root_password: ${password}
+
+config:
+ domains:
+ - serviceName: nextcloud
+ port: 80
+ host: ${main_domain}
+
+ env:
+ NEXTCLOUD_DOMAIN: ${main_domain}
+ MYSQL_SECRET_PASSWORD: ${db_password}
+ MYSQL_SECRET_PASSWORD_ROOT: ${db_root_password}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/nocodb/docker-compose.yml b/blueprints/nocodb/docker-compose.yml
new file mode 100644
index 000000000..7c4fd1e95
--- /dev/null
+++ b/blueprints/nocodb/docker-compose.yml
@@ -0,0 +1,31 @@
+version: "3.8"
+services:
+ nocodb:
+ image: nocodb/nocodb:0.257.2
+ restart: always
+ environment:
+ NC_DB: "pg://root_db?u=postgres&p=password&d=root_db"
+ PORT: ${NOCODB_PORT}
+ NC_REDIS_URL: ${NC_REDIS_URL}
+ volumes:
+ - nc_data:/usr/app/data
+
+ root_db:
+ image: postgres:17
+ restart: always
+
+ environment:
+ POSTGRES_DB: root_db
+ POSTGRES_PASSWORD: password
+ POSTGRES_USER: postgres
+ healthcheck:
+ interval: 10s
+ retries: 10
+ test: 'pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB"'
+ timeout: 2s
+ volumes:
+ - "db_data:/var/lib/postgresql/data"
+
+volumes:
+ db_data: {}
+ nc_data: {}
diff --git a/blueprints/nocodb/nocodb.png b/blueprints/nocodb/nocodb.png
new file mode 100644
index 000000000..70af49264
Binary files /dev/null and b/blueprints/nocodb/nocodb.png differ
diff --git a/blueprints/nocodb/template.yml b/blueprints/nocodb/template.yml
new file mode 100644
index 000000000..39b8d888d
--- /dev/null
+++ b/blueprints/nocodb/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+ jwt_secret: ${base64:64}
+
+config:
+ domains:
+ - serviceName: nocodb
+ port: 8000
+ host: ${main_domain}
+
+ env:
+ NOCODB_PORT: "8000"
+ NC_AUTH_JWT_SECRET: ${jwt_secret}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/odoo/docker-compose.yml b/blueprints/odoo/docker-compose.yml
new file mode 100644
index 000000000..7c1c7d3ce
--- /dev/null
+++ b/blueprints/odoo/docker-compose.yml
@@ -0,0 +1,28 @@
+version: "3.8"
+services:
+ web:
+ image: odoo:16.0
+ depends_on:
+ - db
+ environment:
+ - HOST=db
+ - USER=odoo
+ - PASSWORD=odoo
+ volumes:
+ - odoo-web-data:/var/lib/odoo
+ - ../files/config:/etc/odoo
+ - ../files/addons:/mnt/extra-addons
+
+ db:
+ image: postgres:13
+
+ environment:
+ - POSTGRES_DB=postgres
+ - POSTGRES_USER=odoo
+ - POSTGRES_PASSWORD=odoo
+ volumes:
+ - odoo-db-data:/var/lib/postgresql/data
+
+volumes:
+ odoo-web-data:
+ odoo-db-data:
diff --git a/blueprints/odoo/odoo.png b/blueprints/odoo/odoo.png
new file mode 100644
index 000000000..5b5988999
Binary files /dev/null and b/blueprints/odoo/odoo.png differ
diff --git a/blueprints/odoo/template.yml b/blueprints/odoo/template.yml
new file mode 100644
index 000000000..969a2f9d0
--- /dev/null
+++ b/blueprints/odoo/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: web
+ port: 8069
+ host: ${main_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/onedev/docker-compose.yml b/blueprints/onedev/docker-compose.yml
new file mode 100644
index 000000000..af4122cf8
--- /dev/null
+++ b/blueprints/onedev/docker-compose.yml
@@ -0,0 +1,12 @@
+---
+services:
+ onedev:
+ image: 1dev/server:11.6.6
+ restart: always
+
+ volumes:
+ - "/var/run/docker.sock:/var/run/docker.sock"
+ - "onedev-data:/opt/onedev"
+
+volumes:
+ onedev-data:
\ No newline at end of file
diff --git a/blueprints/onedev/onedev.png b/blueprints/onedev/onedev.png
new file mode 100644
index 000000000..6c39e6cf6
Binary files /dev/null and b/blueprints/onedev/onedev.png differ
diff --git a/blueprints/onedev/template.yml b/blueprints/onedev/template.yml
new file mode 100644
index 000000000..722495b05
--- /dev/null
+++ b/blueprints/onedev/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: onedev
+ port: 6610
+ host: ${main_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/ontime/docker-compose.yml b/blueprints/ontime/docker-compose.yml
new file mode 100644
index 000000000..2c04bcb3f
--- /dev/null
+++ b/blueprints/ontime/docker-compose.yml
@@ -0,0 +1,14 @@
+services:
+ ontime:
+ image: getontime/ontime:v3.8.0
+ ports:
+ - 4001
+ - 8888
+ - 9999
+ volumes:
+ - ontime-data:/data/
+ environment:
+ - TZ
+ restart: unless-stopped
+volumes:
+ ontime-data:
diff --git a/blueprints/ontime/ontime.png b/blueprints/ontime/ontime.png
new file mode 100644
index 000000000..e7aaee290
Binary files /dev/null and b/blueprints/ontime/ontime.png differ
diff --git a/blueprints/ontime/template.yml b/blueprints/ontime/template.yml
new file mode 100644
index 000000000..fccde7c2f
--- /dev/null
+++ b/blueprints/ontime/template.yml
@@ -0,0 +1,13 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: ontime
+ port: 4001
+ host: ${main_domain}
+
+ env:
+ TZ: "UTC"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/open-webui/docker-compose.yml b/blueprints/open-webui/docker-compose.yml
new file mode 100644
index 000000000..ee179721a
--- /dev/null
+++ b/blueprints/open-webui/docker-compose.yml
@@ -0,0 +1,25 @@
+version: "3.8"
+services:
+ ollama:
+ volumes:
+ - ollama:/root/.ollama
+
+ pull_policy: always
+ tty: true
+ restart: unless-stopped
+ image: ollama/ollama:${OLLAMA_DOCKER_TAG-latest}
+
+ open-webui:
+ image: ghcr.io/open-webui/open-webui:${WEBUI_DOCKER_TAG-main}
+ volumes:
+ - open-webui:/app/backend/data
+ depends_on:
+ - ollama
+ environment:
+ - "OLLAMA_BASE_URL=http://ollama:11434"
+ - "WEBUI_SECRET_KEY="
+ restart: unless-stopped
+
+volumes:
+ ollama: {}
+ open-webui: {}
diff --git a/blueprints/open-webui/open-webui.png b/blueprints/open-webui/open-webui.png
new file mode 100644
index 000000000..2b2074780
Binary files /dev/null and b/blueprints/open-webui/open-webui.png differ
diff --git a/blueprints/open-webui/template.yml b/blueprints/open-webui/template.yml
new file mode 100644
index 000000000..0a66d50b7
--- /dev/null
+++ b/blueprints/open-webui/template.yml
@@ -0,0 +1,14 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: open-webui
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ OLLAMA_DOCKER_TAG: "0.1.47"
+ WEBUI_DOCKER_TAG: "0.3.7"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/outline/docker-compose.yml b/blueprints/outline/docker-compose.yml
new file mode 100644
index 000000000..aaf98ac0b
--- /dev/null
+++ b/blueprints/outline/docker-compose.yml
@@ -0,0 +1,57 @@
+services:
+ outline:
+ image: outlinewiki/outline:0.82.0
+ restart: always
+ depends_on:
+ - postgres
+ - redis
+ - dex
+ ports:
+ - 3000
+ environment:
+ NODE_ENV: production
+ URL: ${URL}
+ FORCE_HTTPS: 'false'
+ SECRET_KEY: ${SECRET_KEY}
+ UTILS_SECRET: ${UTILS_SECRET}
+ DATABASE_URL: postgres://outline:${POSTGRES_PASSWORD}@postgres:5432/outline
+ PGSSLMODE: disable
+ REDIS_URL: redis://redis:6379
+ OIDC_CLIENT_ID: outline
+ OIDC_CLIENT_SECRET: ${CLIENT_SECRET}
+ OIDC_AUTH_URI: ${DEX_URL}/auth
+ OIDC_TOKEN_URI: ${DEX_URL}/token
+ OIDC_USERINFO_URI: ${DEX_URL}/userinfo
+
+ dex:
+ image: ghcr.io/dexidp/dex:v2.37.0
+ restart: always
+ volumes:
+ - ../files/etc/dex/config.yaml:/etc/dex/config.yaml
+ command:
+ - dex
+ - serve
+ - /etc/dex/config.yaml
+ ports:
+ - 5556
+
+ postgres:
+ image: postgres:15
+ restart: always
+ environment:
+ POSTGRES_DB: outline
+ POSTGRES_USER: outline
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+ volumes:
+ - postgres_data-test-outline-khufpx:/var/lib/postgresql/data
+
+ redis:
+ image: redis:latest
+ restart: always
+ command: redis-server --appendonly yes
+ volumes:
+ - redis_data-test-outline-khufpx:/data
+
+volumes:
+ postgres_data-test-outline-khufpx:
+ redis_data-test-outline-khufpx:
\ No newline at end of file
diff --git a/blueprints/outline/outline.png b/blueprints/outline/outline.png
new file mode 100644
index 000000000..b241f01d7
Binary files /dev/null and b/blueprints/outline/outline.png differ
diff --git a/blueprints/outline/template.yml b/blueprints/outline/template.yml
new file mode 100644
index 000000000..f0c240964
--- /dev/null
+++ b/blueprints/outline/template.yml
@@ -0,0 +1,64 @@
+variables:
+ main_domain: ${domain}
+ dex_domain: ${domain}
+ secret_key: ${base64:32}
+ utils_secret: ${base64:32}
+ client_secret: ${base64:32}
+ postgres_password: ${password}
+
+config:
+ domains:
+ - serviceName: outline
+ port: 3000
+ host: ${main_domain}
+ - serviceName: dex
+ port: 5556
+ host: ${dex_domain}
+
+ env:
+ URL: http://${main_domain}
+ DEX_URL: http://${dex_domain}
+ DOMAIN_NAME: ${main_domain}
+ POSTGRES_PASSWORD: ${postgres_password}
+ SECRET_KEY: ${secret_key}
+ UTILS_SECRET: ${utils_secret}
+ CLIENT_SECRET: ${client_secret}
+
+ mounts:
+ - filePath: /etc/dex/config.yaml
+ content: |
+ issuer: http://${dex_domain}
+
+ web:
+ http: 0.0.0.0:5556
+
+ storage:
+ type: memory
+
+ enablePasswordDB: true
+
+ frontend:
+ issuer: Outline
+
+ logger:
+ level: debug
+
+ staticPasswords:
+ - email: "admin@example.com"
+ # bcrypt hash of the string "password": $(echo password | htpasswd -BinC 10 admin | cut -d: -f2)
+ hash: "$2y$10$jsRWHw54uxTUIfhjgUrB9u8HSzPk7TUuQri9sXZrKzRXcScvwYor."
+ username: "admin"
+ userID: "1"
+
+
+ oauth2:
+ skipApprovalScreen: true
+ alwaysShowLoginScreen: false
+ passwordConnector: local
+
+ staticClients:
+ - id: "outline"
+ redirectURIs:
+ - http://${main_domain}/auth/oidc.callback
+ name: "Outline"
+ secret: "${client_secret}"
\ No newline at end of file
diff --git a/blueprints/penpot/docker-compose.yml b/blueprints/penpot/docker-compose.yml
new file mode 100644
index 000000000..3e0efe915
--- /dev/null
+++ b/blueprints/penpot/docker-compose.yml
@@ -0,0 +1,207 @@
+## Common flags:
+# demo-users
+# email-verification
+# log-emails
+# log-invitation-tokens
+# login-with-github
+# login-with-gitlab
+# login-with-google
+# login-with-ldap
+# login-with-oidc
+# login-with-password
+# prepl-server
+# registration
+# secure-session-cookies
+# smtp
+# smtp-debug
+# telemetry
+# webhooks
+##
+## You can read more about all available flags and other
+## environment variables here:
+## https://help.penpot.app/technical-guide/configuration/#advanced-configuration
+#
+# WARNING: if you're exposing Penpot to the internet, you should remove the flags
+# 'disable-secure-session-cookies' and 'disable-email-verification'
+
+volumes:
+ penpot_postgres_v15:
+ penpot_assets:
+ penpot_traefik:
+ # penpot_minio:
+
+services:
+
+ penpot-frontend:
+ image: "penpotapp/frontend:2.3.2"
+ restart: always
+ ports:
+ - 8080
+ - 9001
+
+ volumes:
+ - penpot_assets:/opt/data/assets
+
+ depends_on:
+ - penpot-backend
+ - penpot-exporter
+
+
+
+ environment:
+ PENPOT_FLAGS: disable-email-verification enable-smtp enable-prepl-server disable-secure-session-cookies
+
+ penpot-backend:
+ image: "penpotapp/backend:2.3.2"
+ restart: always
+
+ volumes:
+ - penpot_assets:/opt/data/assets
+
+ depends_on:
+ - penpot-postgres
+ - penpot-redis
+
+
+
+ ## Configuration envronment variables for the backend
+ ## container.
+
+ environment:
+ PENPOT_PUBLIC_URI: http://${DOMAIN_NAME}
+ PENPOT_FLAGS: disable-email-verification enable-smtp enable-prepl-server disable-secure-session-cookies
+
+ ## Penpot SECRET KEY. It serves as a master key from which other keys for subsystems
+ ## (eg http sessions, or invitations) are derived.
+ ##
+ ## If you leave it commented, all created sessions and invitations will
+ ## become invalid on container restart.
+ ##
+ ## If you going to uncomment this, we recommend to use a trully randomly generated
+ ## 512 bits base64 encoded string here. You can generate one with:
+ ##
+ ## python3 -c "import secrets; print(secrets.token_urlsafe(64))"
+
+ # PENPOT_SECRET_KEY: my-insecure-key
+
+ ## The PREPL host. Mainly used for external programatic access to penpot backend
+ ## (example: admin). By default it will listen on `localhost` but if you are going to use
+ ## the `admin`, you will need to uncomment this and set the host to `0.0.0.0`.
+
+ # PENPOT_PREPL_HOST: 0.0.0.0
+
+ ## Database connection parameters. Don't touch them unless you are using custom
+ ## postgresql connection parameters.
+
+ PENPOT_DATABASE_URI: postgresql://penpot-postgres/penpot
+ PENPOT_DATABASE_USERNAME: penpot
+ PENPOT_DATABASE_PASSWORD: penpot
+
+ ## Redis is used for the websockets notifications. Don't touch unless the redis
+ ## container has different parameters or different name.
+
+ PENPOT_REDIS_URI: redis://penpot-redis/0
+
+ ## Default configuration for assets storage: using filesystem based with all files
+ ## stored in a docker volume.
+
+ PENPOT_ASSETS_STORAGE_BACKEND: assets-fs
+ PENPOT_STORAGE_ASSETS_FS_DIRECTORY: /opt/data/assets
+
+ ## Also can be configured to to use a S3 compatible storage
+ ## service like MiniIO. Look below for minio service setup.
+
+ # AWS_ACCESS_KEY_ID:
+ # AWS_SECRET_ACCESS_KEY:
+ # PENPOT_ASSETS_STORAGE_BACKEND: assets-s3
+ # PENPOT_STORAGE_ASSETS_S3_ENDPOINT: http://penpot-minio:9000
+ # PENPOT_STORAGE_ASSETS_S3_BUCKET:
+
+ ## Telemetry. When enabled, a periodical process will send anonymous data about this
+ ## instance. Telemetry data will enable us to learn how the application is used,
+ ## based on real scenarios. If you want to help us, please leave it enabled. You can
+ ## audit what data we send with the code available on github.
+
+ PENPOT_TELEMETRY_ENABLED: true
+
+ ## Example SMTP/Email configuration. By default, emails are sent to the mailcatch
+ ## service, but for production usage it is recommended to setup a real SMTP
+ ## provider. Emails are used to confirm user registrations & invitations. Look below
+ ## how the mailcatch service is configured.
+
+ PENPOT_SMTP_DEFAULT_FROM: no-reply@example.com
+ PENPOT_SMTP_DEFAULT_REPLY_TO: no-reply@example.com
+ PENPOT_SMTP_HOST: penpot-mailcatch
+ PENPOT_SMTP_PORT: 1025
+ PENPOT_SMTP_USERNAME:
+ PENPOT_SMTP_PASSWORD:
+ PENPOT_SMTP_TLS: false
+ PENPOT_SMTP_SSL: false
+
+ penpot-exporter:
+ image: "penpotapp/exporter:2.3.2"
+ restart: always
+
+
+ environment:
+ # Don't touch it; this uses an internal docker network to
+ # communicate with the frontend.
+ PENPOT_PUBLIC_URI: http://penpot-frontend
+
+ ## Redis is used for the websockets notifications.
+ PENPOT_REDIS_URI: redis://penpot-redis/0
+
+ penpot-postgres:
+ image: "postgres:15"
+ restart: always
+ stop_signal: SIGINT
+
+ volumes:
+ - penpot_postgres_v15:/var/lib/postgresql/data
+
+
+
+ environment:
+ - POSTGRES_INITDB_ARGS=--data-checksums
+ - POSTGRES_DB=penpot
+ - POSTGRES_USER=penpot
+ - POSTGRES_PASSWORD=penpot
+
+ penpot-redis:
+ image: redis:7.2
+ restart: always
+
+
+ ## A mailcatch service, used as temporal SMTP server. You can access via HTTP to the
+ ## port 1080 for read all emails the penpot platform has sent. Should be only used as a
+ ## temporal solution while no real SMTP provider is configured.
+
+ penpot-mailcatch:
+ image: sj26/mailcatcher:latest
+ restart: always
+ expose:
+ - '1025'
+ ports:
+ - 1080
+
+
+ ## Example configuration of MiniIO (S3 compatible object storage service); If you don't
+ ## have preference, then just use filesystem, this is here just for the completeness.
+
+ # minio:
+ # image: "minio/minio:latest"
+ # command: minio server /mnt/data --console-address ":9001"
+ # restart: always
+ #
+ # volumes:
+ # - "penpot_minio:/mnt/data"
+ #
+ # environment:
+ # - MINIO_ROOT_USER=minioadmin
+ # - MINIO_ROOT_PASSWORD=minioadmin
+ #
+ # ports:
+ # - 9000:9000
+ # - 9001:9001
+
+
diff --git a/blueprints/penpot/penpot.svg b/blueprints/penpot/penpot.svg
new file mode 100644
index 000000000..054540929
--- /dev/null
+++ b/blueprints/penpot/penpot.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/blueprints/penpot/template.yml b/blueprints/penpot/template.yml
new file mode 100644
index 000000000..54f16e16e
--- /dev/null
+++ b/blueprints/penpot/template.yml
@@ -0,0 +1,13 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: penpot-frontend
+ port: 80
+ host: ${main_domain}
+
+ env:
+ DOMAIN_NAME: ${main_domain}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/peppermint/docker-compose.yml b/blueprints/peppermint/docker-compose.yml
new file mode 100644
index 000000000..06fb46c66
--- /dev/null
+++ b/blueprints/peppermint/docker-compose.yml
@@ -0,0 +1,38 @@
+version: "3.8"
+
+services:
+ peppermint-postgres:
+ image: postgres:latest
+ restart: always
+
+ volumes:
+ - peppermint-postgres-data:/var/lib/postgresql/data
+ environment:
+ POSTGRES_USER: peppermint
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+ POSTGRES_DB: peppermint
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U peppermint"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+ peppermint-app:
+ image: pepperlabs/peppermint:latest
+ restart: always
+
+ depends_on:
+ peppermint-postgres:
+ condition: service_healthy
+ environment:
+ DB_USERNAME: "peppermint"
+ DB_PASSWORD: ${POSTGRES_PASSWORD}
+ DB_HOST: "peppermint-postgres"
+ SECRET: ${SECRET}
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ peppermint-postgres-data:
\ No newline at end of file
diff --git a/blueprints/peppermint/peppermint.svg b/blueprints/peppermint/peppermint.svg
new file mode 100644
index 000000000..b6fff9942
--- /dev/null
+++ b/blueprints/peppermint/peppermint.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/peppermint/template.yml b/blueprints/peppermint/template.yml
new file mode 100644
index 000000000..8766589cb
--- /dev/null
+++ b/blueprints/peppermint/template.yml
@@ -0,0 +1,22 @@
+variables:
+ main_domain: ${domain}
+ api_domain: ${domain}
+ postgres_password: ${password}
+ secret: ${base64:32}
+
+config:
+ domains:
+ - serviceName: peppermint-app
+ port: 3000
+ host: ${main_domain}
+ - serviceName: peppermint-app
+ port: 5003
+ host: ${api_domain}
+
+ env:
+ MAIN_DOMAIN: ${main_domain}
+ API_DOMAIN: ${api_domain}
+ POSTGRES_PASSWORD: ${postgres_password}
+ SECRET: ${secret}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/photoprism/docker-compose.yml b/blueprints/photoprism/docker-compose.yml
new file mode 100644
index 000000000..56793dbd3
--- /dev/null
+++ b/blueprints/photoprism/docker-compose.yml
@@ -0,0 +1,76 @@
+services:
+ photoprism:
+ image: photoprism/photoprism:latest
+ stop_grace_period: 10s
+ depends_on:
+ - mariadb
+ security_opt:
+ - seccomp:unconfined
+ - apparmor:unconfined
+
+ environment:
+ PHOTOPRISM_ADMIN_USER: "admin"
+ PHOTOPRISM_ADMIN_PASSWORD: ${ADMIN_PASSWORD}
+ PHOTOPRISM_AUTH_MODE: "password"
+ PHOTOPRISM_SITE_URL: "http://localhost:2342/"
+ PHOTOPRISM_DISABLE_TLS: "false"
+ PHOTOPRISM_DEFAULT_TLS: "false"
+ PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
+ PHOTOPRISM_HTTP_COMPRESSION: "gzip"
+ PHOTOPRISM_LOG_LEVEL: "info" # log level: trace, debug, info, warning, error, fatal, or panic
+ PHOTOPRISM_READONLY: "false"
+ PHOTOPRISM_EXPERIMENTAL: "false"
+ PHOTOPRISM_DISABLE_CHOWN: "false"
+ PHOTOPRISM_DISABLE_WEBDAV: "false"
+ PHOTOPRISM_DISABLE_SETTINGS: "false"
+ PHOTOPRISM_DISABLE_TENSORFLOW: "false"
+ PHOTOPRISM_DISABLE_FACES: "false"
+ PHOTOPRISM_DISABLE_CLASSIFICATION: "false"
+ PHOTOPRISM_DISABLE_VECTORS: "false"
+ PHOTOPRISM_DISABLE_RAW: "false"
+ PHOTOPRISM_RAW_PRESETS: "false"
+ PHOTOPRISM_SIDECAR_YAML: "true"
+ PHOTOPRISM_BACKUP_ALBUMS: "true"
+ PHOTOPRISM_BACKUP_DATABASE: "true"
+ PHOTOPRISM_BACKUP_SCHEDULE: "daily"
+ PHOTOPRISM_INDEX_SCHEDULE: ""
+ PHOTOPRISM_AUTO_INDEX: 300
+ PHOTOPRISM_AUTO_IMPORT: -1
+ PHOTOPRISM_DETECT_NSFW: "false"
+ PHOTOPRISM_UPLOAD_NSFW: "true"
+ PHOTOPRISM_DATABASE_DRIVER: "mysql"
+ PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
+ PHOTOPRISM_DATABASE_NAME: "photoprism"
+ PHOTOPRISM_DATABASE_USER: "photoprism"
+ PHOTOPRISM_DATABASE_PASSWORD: "insecure"
+ PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App"
+ PHOTOPRISM_SITE_DESCRIPTION: ""
+ PHOTOPRISM_SITE_AUTHOR: ""
+ working_dir:
+ "/photoprism"
+ volumes:
+ - pictures:/photoprism/originals
+ - storage-data:/photoprism/storage
+
+ mariadb:
+ image: mariadb:11
+ restart: unless-stopped
+ stop_grace_period: 5s
+
+ security_opt:
+ - seccomp:unconfined
+ - apparmor:unconfined
+ volumes:
+ - db-data:/var/lib/mysql
+ environment:
+ MARIADB_AUTO_UPGRADE: "1"
+ MARIADB_INITDB_SKIP_TZINFO: "1"
+ MARIADB_DATABASE: "photoprism"
+ MARIADB_USER: "photoprism"
+ MARIADB_PASSWORD: "insecure"
+ MARIADB_ROOT_PASSWORD: "insecure"
+
+volumes:
+ db-data:
+ storage-data:
+ pictures:
\ No newline at end of file
diff --git a/blueprints/photoprism/photoprism.svg b/blueprints/photoprism/photoprism.svg
new file mode 100644
index 000000000..eefa5cde4
--- /dev/null
+++ b/blueprints/photoprism/photoprism.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blueprints/photoprism/template.yml b/blueprints/photoprism/template.yml
new file mode 100644
index 000000000..8a1a26ace
--- /dev/null
+++ b/blueprints/photoprism/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+ admin_password: ${password}
+
+config:
+ domains:
+ - serviceName: photoprism
+ port: 2342
+ host: ${main_domain}
+
+ env:
+ BASE_URL: http://${main_domain}
+ ADMIN_PASSWORD: ${admin_password}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/phpmyadmin/docker-compose.yml b/blueprints/phpmyadmin/docker-compose.yml
new file mode 100644
index 000000000..91674e87c
--- /dev/null
+++ b/blueprints/phpmyadmin/docker-compose.yml
@@ -0,0 +1,27 @@
+version: "3.8"
+
+services:
+ db:
+ image: mysql:5.7
+ environment:
+ MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
+ MYSQL_DATABASE: tu_base_de_datos
+ MYSQL_USER: ${MYSQL_USER}
+ MYSQL_PASSWORD: ${MYSQL_PASSWORD}
+ volumes:
+ - db_data:/var/lib/mysql
+
+
+ phpmyadmin:
+ image: phpmyadmin/phpmyadmin:5.2.1
+ environment:
+ PMA_HOST: db
+ PMA_USER: ${MYSQL_USER}
+ PMA_PASSWORD: ${MYSQL_PASSWORD}
+ PMA_ARBITRARY: 1
+ depends_on:
+ - db
+
+volumes:
+ db_data:
+ driver: local
diff --git a/blueprints/phpmyadmin/phpmyadmin.png b/blueprints/phpmyadmin/phpmyadmin.png
new file mode 100644
index 000000000..56e18d850
Binary files /dev/null and b/blueprints/phpmyadmin/phpmyadmin.png differ
diff --git a/blueprints/phpmyadmin/template.yml b/blueprints/phpmyadmin/template.yml
new file mode 100644
index 000000000..ccbc1bf3a
--- /dev/null
+++ b/blueprints/phpmyadmin/template.yml
@@ -0,0 +1,18 @@
+variables:
+ main_domain: ${domain}
+ root_password: ${password:32}
+ user_password: ${password:32}
+
+config:
+ domains:
+ - serviceName: phpmyadmin
+ port: 80
+ host: ${main_domain}
+
+ env:
+ MYSQL_ROOT_PASSWORD: ${root_password}
+ MYSQL_DATABASE: "mysql"
+ MYSQL_USER: "phpmyadmin"
+ MYSQL_PASSWORD: ${user_password}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/plausible/template.yml b/blueprints/plausible/template.yml
index 346c719bf..d0f3948a5 100644
--- a/blueprints/plausible/template.yml
+++ b/blueprints/plausible/template.yml
@@ -1,5 +1,5 @@
variables:
- main_domain: ${randomDomain}
+ main_domain: ${domain}
secret_base: ${base64:64}
totp_key: ${base64:32}
diff --git a/blueprints/pocket-id/docker-compose.yml b/blueprints/pocket-id/docker-compose.yml
new file mode 100644
index 000000000..f93851430
--- /dev/null
+++ b/blueprints/pocket-id/docker-compose.yml
@@ -0,0 +1,21 @@
+services:
+ pocket-id:
+ image: ghcr.io/pocket-id/pocket-id:v0.35.1
+ restart: unless-stopped
+ environment:
+ - PUBLIC_UI_CONFIG_DISABLED
+ - PUBLIC_APP_URL
+ - TRUST_PROXY
+ ports:
+ - 80
+ volumes:
+ - pocket-id-data:/app/backend/data
+ healthcheck:
+ test: "curl -f http://localhost/health"
+ interval: 1m30s
+ timeout: 5s
+ retries: 2
+ start_period: 10s
+
+volumes:
+ pocket-id-data:
diff --git a/blueprints/pocket-id/pocket-id.svg b/blueprints/pocket-id/pocket-id.svg
new file mode 100644
index 000000000..0ee89b14b
--- /dev/null
+++ b/blueprints/pocket-id/pocket-id.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blueprints/pocket-id/template.yml b/blueprints/pocket-id/template.yml
new file mode 100644
index 000000000..b3af91a73
--- /dev/null
+++ b/blueprints/pocket-id/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: pocket-id
+ port: 80
+ host: ${main_domain}
+
+ env:
+ PUBLIC_UI_CONFIG_DISABLED: "false"
+ PUBLIC_APP_URL: http://${main_domain}
+ TRUST_PROXY: "true"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/pocketbase/template.yml b/blueprints/pocketbase/template.yml
index 472ad6459..82b6f61e9 100644
--- a/blueprints/pocketbase/template.yml
+++ b/blueprints/pocketbase/template.yml
@@ -1,5 +1,5 @@
variables:
- main_domain: ${randomDomain}
+ main_domain: ${domain}
config:
domains:
diff --git a/blueprints/portainer/docker-compose.yml b/blueprints/portainer/docker-compose.yml
new file mode 100644
index 000000000..19e67a3e5
--- /dev/null
+++ b/blueprints/portainer/docker-compose.yml
@@ -0,0 +1,29 @@
+version: '3.8'
+
+services:
+ agent:
+ image: portainer/agent
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - /var/lib/docker/volumes:/var/lib/docker/volumes
+
+
+ deploy:
+ mode: global
+ placement:
+ constraints: [node.platform.os == linux]
+
+ portainer:
+ image: portainer/portainer-ce
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - portainer-data:/data
+ deploy:
+ mode: replicated
+ placement:
+ constraints: [node.role == manager]
+
+
+volumes:
+ portainer-data:
+
\ No newline at end of file
diff --git a/blueprints/portainer/portainer.svg b/blueprints/portainer/portainer.svg
new file mode 100644
index 000000000..e8c91b365
--- /dev/null
+++ b/blueprints/portainer/portainer.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blueprints/portainer/template.yml b/blueprints/portainer/template.yml
new file mode 100644
index 000000000..908f9c803
--- /dev/null
+++ b/blueprints/portainer/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: portainer
+ port: 9000
+ host: ${main_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/postiz/docker-compose.yml b/blueprints/postiz/docker-compose.yml
new file mode 100644
index 000000000..cd06e7952
--- /dev/null
+++ b/blueprints/postiz/docker-compose.yml
@@ -0,0 +1,65 @@
+version: "3.8"
+
+services:
+ postiz-app:
+ image: ghcr.io/gitroomhq/postiz-app:latest
+ restart: always
+
+ environment:
+ MAIN_URL: "https://${POSTIZ_HOST}"
+ FRONTEND_URL: "https://${POSTIZ_HOST}"
+ NEXT_PUBLIC_BACKEND_URL: "https://${POSTIZ_HOST}/api"
+ JWT_SECRET: ${JWT_SECRET}
+ DATABASE_URL: "postgresql://${DB_USER}:${DB_PASSWORD}@postiz-postgres:5432/${DB_NAME}"
+ REDIS_URL: "redis://postiz-redis:6379"
+ BACKEND_INTERNAL_URL: "http://localhost:3000"
+ IS_GENERAL: "true"
+ STORAGE_PROVIDER: "local"
+ UPLOAD_DIRECTORY: "/uploads"
+ NEXT_PUBLIC_UPLOAD_DIRECTORY: "/uploads"
+ volumes:
+ - postiz-config:/config/
+ - postiz-uploads:/uploads/
+ depends_on:
+ postiz-postgres:
+ condition: service_healthy
+ postiz-redis:
+ condition: service_healthy
+
+ postiz-postgres:
+ image: postgres:17-alpine
+ restart: always
+
+ environment:
+ POSTGRES_PASSWORD: ${DB_PASSWORD}
+ POSTGRES_USER: ${DB_USER}
+ POSTGRES_DB: ${DB_NAME}
+ volumes:
+ - postiz-postgres-data:/var/lib/postgresql/data
+ healthcheck:
+ test: pg_isready -U ${DB_USER} -d ${DB_NAME}
+ interval: 10s
+ timeout: 3s
+ retries: 3
+
+ postiz-redis:
+ image: redis:7.2
+ restart: always
+
+ healthcheck:
+ test: redis-cli ping
+ interval: 10s
+ timeout: 3s
+ retries: 3
+ volumes:
+ - postiz-redis-data:/data
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ postiz-postgres-data:
+ postiz-redis-data:
+ postiz-config:
+ postiz-uploads:
\ No newline at end of file
diff --git a/blueprints/postiz/postiz.png b/blueprints/postiz/postiz.png
new file mode 100644
index 000000000..1d435abcd
Binary files /dev/null and b/blueprints/postiz/postiz.png differ
diff --git a/blueprints/postiz/template.yml b/blueprints/postiz/template.yml
new file mode 100644
index 000000000..1ebddc7dd
--- /dev/null
+++ b/blueprints/postiz/template.yml
@@ -0,0 +1,21 @@
+variables:
+ main_domain: ${domain}
+ db_password: ${password}
+ db_user: "postiz"
+ db_name: "postiz"
+ jwt_secret: ${base64:32}
+
+config:
+ domains:
+ - serviceName: postiz-app
+ port: 5000
+ host: ${main_domain}
+
+ env:
+ POSTIZ_HOST: ${main_domain}
+ DB_PASSWORD: ${db_password}
+ DB_USER: ${db_user}
+ DB_NAME: ${db_name}
+ JWT_SECRET: ${jwt_secret}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/registry/docker-compose.yml b/blueprints/registry/docker-compose.yml
new file mode 100644
index 000000000..08c5c3688
--- /dev/null
+++ b/blueprints/registry/docker-compose.yml
@@ -0,0 +1,19 @@
+services:
+ registry:
+ restart: always
+ image: registry:2
+ ports:
+ - 5000
+ volumes:
+ - ../files/auth/registry.password:/auth/registry.password
+ - registry-data:/var/lib/registry
+ environment:
+ REGISTRY_STORAGE_DELETE_ENABLED: true
+ REGISTRY_HEALTH_STORAGEDRIVER_ENABLED: false
+ REGISTRY_HTTP_SECRET: ${REGISTRY_HTTP_SECRET}
+ REGISTRY_AUTH: htpasswd
+ REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
+ REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
+
+volumes:
+ registry-data:
\ No newline at end of file
diff --git a/blueprints/registry/registry.png b/blueprints/registry/registry.png
new file mode 100644
index 000000000..39418022e
Binary files /dev/null and b/blueprints/registry/registry.png differ
diff --git a/blueprints/registry/template.yml b/blueprints/registry/template.yml
new file mode 100644
index 000000000..44bea6825
--- /dev/null
+++ b/blueprints/registry/template.yml
@@ -0,0 +1,18 @@
+variables:
+ main_domain: ${domain}
+ registry_http_secret: ${password:30}
+
+config:
+ domains:
+ - serviceName: registry
+ port: 5000
+ host: ${main_domain}
+
+ env:
+ REGISTRY_HTTP_SECRET: ${registry_http_secret}
+
+ mounts:
+ - filePath: /auth/registry.password
+ content: |
+ # from: docker run --rm --entrypoint htpasswd httpd:2 -Bbn docker password
+ docker:$2y$10$qWZoWev/u5PV7WneFoRAMuoGpRcAQOgUuIIdLnU7pJXogrBSY23/2
\ No newline at end of file
diff --git a/blueprints/rocketchat/docker-compose.yml b/blueprints/rocketchat/docker-compose.yml
new file mode 100644
index 000000000..5119f5a4e
--- /dev/null
+++ b/blueprints/rocketchat/docker-compose.yml
@@ -0,0 +1,34 @@
+version: "3.8"
+services:
+ rocketchat:
+ image: registry.rocket.chat/rocketchat/rocket.chat:6.9.2
+ restart: always
+ environment:
+ MONGO_URL: "mongodb://mongodb:27017/rocketchat?replicaSet=rs0"
+ MONGO_OPLOG_URL: "mongodb://mongodb:27017/local?replicaSet=rs0"
+ ROOT_URL: ${ROOT_URL:-http://${ROCKETCHAT_HOST}:${ROCKETCHAT_PORT}}
+ PORT: ${ROCKETCHAT_PORT}
+ DEPLOY_METHOD: docker
+ DEPLOY_PLATFORM:
+ REG_TOKEN:
+ depends_on:
+ - mongodb
+
+ mongodb:
+ image: docker.io/bitnami/mongodb:5.0
+ restart: always
+ volumes:
+ - mongodb_data:/bitnami/mongodb
+ environment:
+ MONGODB_REPLICA_SET_MODE: primary
+ MONGODB_REPLICA_SET_NAME: rs0
+ MONGODB_PORT_NUMBER: 27017
+ MONGODB_INITIAL_PRIMARY_HOST: mongodb
+ MONGODB_INITIAL_PRIMARY_PORT_NUMBER: 27017
+ MONGODB_ADVERTISED_HOSTNAME: mongodb
+ MONGODB_ENABLE_JOURNAL: true
+ ALLOW_EMPTY_PASSWORD: yes
+
+
+volumes:
+ mongodb_data: { driver: local }
diff --git a/blueprints/rocketchat/rocketchat.png b/blueprints/rocketchat/rocketchat.png
new file mode 100644
index 000000000..5d42c70f8
Binary files /dev/null and b/blueprints/rocketchat/rocketchat.png differ
diff --git a/blueprints/rocketchat/template.yml b/blueprints/rocketchat/template.yml
new file mode 100644
index 000000000..ca684d556
--- /dev/null
+++ b/blueprints/rocketchat/template.yml
@@ -0,0 +1,14 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: rocketchat
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ ROCKETCHAT_HOST: ${main_domain}
+ ROCKETCHAT_PORT: "3000"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/roundcube/docker-compose.yml b/blueprints/roundcube/docker-compose.yml
new file mode 100644
index 000000000..e5ba4a8b1
--- /dev/null
+++ b/blueprints/roundcube/docker-compose.yml
@@ -0,0 +1,16 @@
+services:
+ roundcubemail:
+ image: roundcube/roundcubemail:1.6.9-apache
+ volumes:
+ - ./www:/var/www/html
+ - ./db/sqlite:/var/roundcube/db
+ environment:
+ - ROUNDCUBEMAIL_DB_TYPE=sqlite
+ - ROUNDCUBEMAIL_SKIN=elastic
+ - ROUNDCUBEMAIL_DEFAULT_HOST=${DEFAULT_HOST}
+ - ROUNDCUBEMAIL_SMTP_SERVER=${SMTP_SERVER}
+
+
+networks:
+ dokploy-network:
+ external: true
diff --git a/blueprints/roundcube/roundcube.svg b/blueprints/roundcube/roundcube.svg
new file mode 100644
index 000000000..04238a06a
--- /dev/null
+++ b/blueprints/roundcube/roundcube.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/roundcube/template.yml b/blueprints/roundcube/template.yml
new file mode 100644
index 000000000..c3874ddec
--- /dev/null
+++ b/blueprints/roundcube/template.yml
@@ -0,0 +1,14 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: roundcubemail
+ port: 80
+ host: ${main_domain}
+
+ env:
+ DEFAULT_HOST: "tls://mail.example.com"
+ SMTP_SERVER: "tls://mail.example.com"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/ryot/docker-compose.yml b/blueprints/ryot/docker-compose.yml
new file mode 100644
index 000000000..09a727071
--- /dev/null
+++ b/blueprints/ryot/docker-compose.yml
@@ -0,0 +1,37 @@
+version: '3.7'
+
+services:
+ ryot-app:
+ image: ignisda/ryot:v7.10
+
+ environment:
+ - DATABASE_URL=postgres://postgres:${POSTGRES_PASSWORD}@ryot-db:5432/postgres
+ - SERVER_ADMIN_ACCESS_TOKEN=${ADMIN_ACCESS_TOKEN}
+ - TZ=UTC
+ # Optional: Uncomment and set your pro key if you have one
+ # - SERVER_PRO_KEY=${SERVER_PRO_KEY}
+ depends_on:
+ ryot-db:
+ condition: service_healthy
+ restart: always
+ pull_policy: always
+
+ ryot-db:
+ image: postgres:16-alpine
+
+ volumes:
+ - ryot-postgres-data:/var/lib/postgresql/data
+ environment:
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+ - POSTGRES_USER=postgres
+ - POSTGRES_DB=postgres
+ - TZ=UTC
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ restart: unless-stopped
+
+volumes:
+ ryot-postgres-data:
\ No newline at end of file
diff --git a/blueprints/ryot/ryot.png b/blueprints/ryot/ryot.png
new file mode 100644
index 000000000..8f03b124d
Binary files /dev/null and b/blueprints/ryot/ryot.png differ
diff --git a/blueprints/ryot/template.yml b/blueprints/ryot/template.yml
new file mode 100644
index 000000000..50d3142d4
--- /dev/null
+++ b/blueprints/ryot/template.yml
@@ -0,0 +1,18 @@
+variables:
+ main_domain: ${domain}
+ postgres_password: ${password}
+ admin_access_token: ${base64:32}
+
+config:
+ domains:
+ - serviceName: ryot-app
+ port: 8000
+ host: ${main_domain}
+
+ env:
+ POSTGRES_PASSWORD: ${postgres_password}
+ ADMIN_ACCESS_TOKEN: ${admin_access_token}
+ # Optional: Uncomment and set your pro key if you have one
+ # SERVER_PRO_KEY: "your_pro_key_here"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/shlink/docker-compose.yml b/blueprints/shlink/docker-compose.yml
new file mode 100644
index 000000000..6d15a26d8
--- /dev/null
+++ b/blueprints/shlink/docker-compose.yml
@@ -0,0 +1,29 @@
+services:
+ shlink:
+ image: shlinkio/shlink:stable
+ environment:
+ - INITIAL_API_KEY=${INITIAL_API_KEY}
+ - DEFAULT_DOMAIN=${DEFAULT_DOMAIN}
+ # Note: you should also update SHLINK_SERVER_URL in the shlink-web service.
+ - IS_HTTPS_ENABLED=false
+ volumes:
+ - shlink-data:/etc/shlink/data
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:8080/rest/v3/health"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ shlink-web:
+ image: shlinkio/shlink-web-client
+ environment:
+ - SHLINK_SERVER_API_KEY=${INITIAL_API_KEY}
+ # Note: if you've set IS_HTTPS_ENABLED=true, change http to https.
+ - SHLINK_SERVER_URL=http://${DEFAULT_DOMAIN}
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:8080"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+
+volumes:
+ shlink-data:
diff --git a/blueprints/shlink/shlink.svg b/blueprints/shlink/shlink.svg
new file mode 100644
index 000000000..6253cd361
--- /dev/null
+++ b/blueprints/shlink/shlink.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/shlink/template.yml b/blueprints/shlink/template.yml
new file mode 100644
index 000000000..1ab9f5f9e
--- /dev/null
+++ b/blueprints/shlink/template.yml
@@ -0,0 +1,18 @@
+variables:
+ main_domain: ${domain}
+ initial_api_key: ${password:30}
+
+config:
+ domains:
+ - serviceName: shlink-web
+ port: 8080
+ host: web-${main_domain}
+ - serviceName: shlink
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ INITIAL_API_KEY: ${initial_api_key}
+ DEFAULT_DOMAIN: ${main_domain}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/slash/docker-compose.yml b/blueprints/slash/docker-compose.yml
new file mode 100644
index 000000000..ee6cdf895
--- /dev/null
+++ b/blueprints/slash/docker-compose.yml
@@ -0,0 +1,39 @@
+version: "3.8"
+
+services:
+ slash-app:
+ image: yourselfhosted/slash:latest
+
+ volumes:
+ - slash-app-data:/var/opt/slash
+ environment:
+ - SLASH_DRIVER=postgres
+ - SLASH_DSN=postgresql://${DB_USER}:${DB_PASSWORD}@slash-postgres:5432/${DB_NAME}?sslmode=disable
+ depends_on:
+ slash-postgres:
+ condition: service_healthy
+ restart: unless-stopped
+
+ slash-postgres:
+ image: postgres:16-alpine
+
+ volumes:
+ - slash-postgres-data:/var/lib/postgresql/data
+ environment:
+ - POSTGRES_USER=${DB_USER}
+ - POSTGRES_PASSWORD=${DB_PASSWORD}
+ - POSTGRES_DB=${DB_NAME}
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ restart: unless-stopped
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ slash-app-data:
+ slash-postgres-data:
\ No newline at end of file
diff --git a/blueprints/slash/slash.png b/blueprints/slash/slash.png
new file mode 100644
index 000000000..c843b4095
Binary files /dev/null and b/blueprints/slash/slash.png differ
diff --git a/blueprints/slash/template.yml b/blueprints/slash/template.yml
new file mode 100644
index 000000000..625788565
--- /dev/null
+++ b/blueprints/slash/template.yml
@@ -0,0 +1,18 @@
+variables:
+ main_domain: ${domain}
+ db_password: ${password}
+ db_user: "slash"
+ db_name: "slash"
+
+config:
+ domains:
+ - serviceName: slash-app
+ port: 5231
+ host: ${main_domain}
+
+ env:
+ DB_USER: ${db_user}
+ DB_PASSWORD: ${db_password}
+ DB_NAME: ${db_name}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/soketi/docker-compose.yml b/blueprints/soketi/docker-compose.yml
new file mode 100644
index 000000000..d38cbb086
--- /dev/null
+++ b/blueprints/soketi/docker-compose.yml
@@ -0,0 +1,11 @@
+version: "3"
+
+services:
+ soketi:
+ image: quay.io/soketi/soketi:1.6.1-16-debian
+ environment:
+ SOKETI_DEBUG: "1"
+ SOKETI_HOST: "0.0.0.0"
+ SOKETI_PORT: "6001"
+ SOKETI_METRICS_SERVER_PORT: "9601"
+ restart: unless-stopped
diff --git a/blueprints/soketi/soketi.png b/blueprints/soketi/soketi.png
new file mode 100644
index 000000000..aec5a79a2
Binary files /dev/null and b/blueprints/soketi/soketi.png differ
diff --git a/blueprints/soketi/template.yml b/blueprints/soketi/template.yml
new file mode 100644
index 000000000..58064a70f
--- /dev/null
+++ b/blueprints/soketi/template.yml
@@ -0,0 +1,16 @@
+variables:
+ main_domain: ${domain}
+ metrics_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: soketi
+ port: 6001
+ host: ${main_domain}
+ - serviceName: soketi
+ port: 9601
+ host: ${metrics_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/spacedrive/docker-compose.yml b/blueprints/spacedrive/docker-compose.yml
new file mode 100644
index 000000000..b98d55abf
--- /dev/null
+++ b/blueprints/spacedrive/docker-compose.yml
@@ -0,0 +1,9 @@
+services:
+ server:
+ image: ghcr.io/spacedriveapp/spacedrive/server:latest
+ ports:
+ - 8080
+ environment:
+ - SD_AUTH=${SD_USERNAME}:${SD_PASSWORD}
+ volumes:
+ - /var/spacedrive:/var/spacedrive
diff --git a/blueprints/spacedrive/spacedrive.png b/blueprints/spacedrive/spacedrive.png
new file mode 100644
index 000000000..a10fffd52
Binary files /dev/null and b/blueprints/spacedrive/spacedrive.png differ
diff --git a/blueprints/spacedrive/template.yml b/blueprints/spacedrive/template.yml
new file mode 100644
index 000000000..b5aca28b8
--- /dev/null
+++ b/blueprints/spacedrive/template.yml
@@ -0,0 +1,15 @@
+variables:
+ main_domain: ${domain}
+ secret_key: ${password}
+
+config:
+ domains:
+ - serviceName: server
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ SD_USERNAME: "admin"
+ SD_PASSWORD: ${secret_key}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/stirling/docker-compose.yml b/blueprints/stirling/docker-compose.yml
new file mode 100644
index 000000000..27bd01216
--- /dev/null
+++ b/blueprints/stirling/docker-compose.yml
@@ -0,0 +1,22 @@
+services:
+ stirling-pdf:
+ image: frooodle/s-pdf:latest
+ ports:
+ - 8080
+ volumes:
+ - stirling_pdf_trainingdata:/usr/share/tessdata
+ - stirling_pdf_extraconfigs:/configs
+ - stirling_pdf_customfiles:/customFiles/
+ - stirling_pdf_logs:/logs/
+ - stirling_pdf_pipeline:/pipeline/
+ environment:
+ - DOCKER_ENABLE_SECURITY=false
+ - INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false
+ - LANGS=en_GB
+
+volumes:
+ stirling_pdf_trainingdata:
+ stirling_pdf_extraconfigs:
+ stirling_pdf_customfiles:
+ stirling_pdf_logs:
+ stirling_pdf_pipeline:
diff --git a/blueprints/stirling/stirling.svg b/blueprints/stirling/stirling.svg
new file mode 100644
index 000000000..0db55164b
--- /dev/null
+++ b/blueprints/stirling/stirling.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/stirling/template.yml b/blueprints/stirling/template.yml
new file mode 100644
index 000000000..e8f2d184f
--- /dev/null
+++ b/blueprints/stirling/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: stirling-pdf
+ port: 8080
+ host: ${main_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/supabase/docker-compose.yml b/blueprints/supabase/docker-compose.yml
new file mode 100644
index 000000000..89339736f
--- /dev/null
+++ b/blueprints/supabase/docker-compose.yml
@@ -0,0 +1,448 @@
+# Usage
+# Start: docker compose up
+# With helpers: docker compose -f docker-compose.yml -f ../files/dev/docker-compose.dev.yml up
+# Stop: docker compose down
+# Destroy: docker compose -f docker-compose.yml -f ../files/dev/docker-compose.dev.yml down -v --remove-orphans
+
+name: supabase
+version: "3.8"
+
+services:
+ studio:
+ container_name: supabase-studio
+ image: supabase/studio:20240729-ce42139
+
+ restart: unless-stopped
+ healthcheck:
+ test:
+ [
+ "CMD",
+ "node",
+ "-e",
+ "require('http').get('http://localhost:3000/api/profile', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})",
+ ]
+ timeout: 5s
+ interval: 5s
+ retries: 3
+ depends_on:
+ analytics:
+ condition: service_healthy
+ environment:
+ STUDIO_PG_META_URL: http://meta:8080
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+
+ DEFAULT_ORGANIZATION_NAME: ${STUDIO_DEFAULT_ORGANIZATION}
+ DEFAULT_PROJECT_NAME: ${STUDIO_DEFAULT_PROJECT}
+
+ SUPABASE_URL: http://kong:8000
+ SUPABASE_PUBLIC_URL: http://${SUPABASE_HOST}
+ SUPABASE_ANON_KEY: ${ANON_KEY}
+ SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
+ AUTH_JWT_SECRET: ${JWT_SECRET}
+
+ LOGFLARE_API_KEY: ${LOGFLARE_API_KEY}
+ LOGFLARE_URL: http://analytics:4000
+ NEXT_PUBLIC_ENABLE_LOGS: true
+ # Comment to use Big Query backend for analytics
+ NEXT_ANALYTICS_BACKEND_PROVIDER: postgres
+ # Uncomment to use Big Query backend for analytics
+ # NEXT_ANALYTICS_BACKEND_PROVIDER: bigquery
+
+ kong:
+ container_name: supabase-kong
+ image: kong:2.8.1
+ restart: unless-stopped
+
+ # https://unix.stackexchange.com/a/294837
+ entrypoint: bash -c 'eval "echo \"$$(cat ~/temp.yml)\"" > ~/kong.yml && /docker-entrypoint.sh kong docker-start'
+ #ports:
+ # - ${KONG_HTTP_PORT}:8000/tcp
+ # - ${KONG_HTTPS_PORT}:8443/tcp
+ expose:
+ - 8000
+ - 8443
+ depends_on:
+ analytics:
+ condition: service_healthy
+ environment:
+ KONG_DATABASE: "off"
+ KONG_DECLARATIVE_CONFIG: /home/kong/kong.yml
+ # https://github.com/supabase/cli/issues/14
+ KONG_DNS_ORDER: LAST,A,CNAME
+ KONG_PLUGINS: request-transformer,cors,key-auth,acl,basic-auth
+ KONG_NGINX_PROXY_PROXY_BUFFER_SIZE: 160k
+ KONG_NGINX_PROXY_PROXY_BUFFERS: 64 160k
+ SUPABASE_ANON_KEY: ${ANON_KEY}
+ SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
+ DASHBOARD_USERNAME: ${DASHBOARD_USERNAME}
+ DASHBOARD_PASSWORD: ${DASHBOARD_PASSWORD}
+ volumes:
+ # https://github.com/supabase/supabase/issues/12661
+ - ../files/volumes/api/kong.yml:/home/kong/temp.yml:ro
+
+ auth:
+ container_name: supabase-auth
+ image: supabase/gotrue:v2.158.1
+
+ depends_on:
+ db:
+ # Disable this if you are using an external Postgres database
+ condition: service_healthy
+ analytics:
+ condition: service_healthy
+ healthcheck:
+ test:
+ [
+ "CMD",
+ "wget",
+ "--no-verbose",
+ "--tries=1",
+ "--spider",
+ "http://localhost:9999/health",
+ ]
+ timeout: 5s
+ interval: 5s
+ retries: 3
+ restart: unless-stopped
+ environment:
+ GOTRUE_API_HOST: 0.0.0.0
+ GOTRUE_API_PORT: 9999
+ API_EXTERNAL_URL: http://${SUPABASE_HOST}
+
+ GOTRUE_DB_DRIVER: postgres
+ GOTRUE_DB_DATABASE_URL: postgres://supabase_auth_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOSTNAME}:${POSTGRES_PORT}/${POSTGRES_DB}
+
+ GOTRUE_SITE_URL: http://${SUPABASE_HOST}
+ GOTRUE_URI_ALLOW_LIST: ${ADDITIONAL_REDIRECT_URLS}
+ GOTRUE_DISABLE_SIGNUP: ${DISABLE_SIGNUP}
+
+ GOTRUE_JWT_ADMIN_ROLES: service_role
+ GOTRUE_JWT_AUD: authenticated
+ GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated
+ GOTRUE_JWT_EXP: ${JWT_EXPIRY}
+ GOTRUE_JWT_SECRET: ${JWT_SECRET}
+
+ GOTRUE_EXTERNAL_EMAIL_ENABLED: ${ENABLE_EMAIL_SIGNUP}
+ GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED: ${ENABLE_ANONYMOUS_USERS}
+ GOTRUE_MAILER_AUTOCONFIRM: ${ENABLE_EMAIL_AUTOCONFIRM}
+ # GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED: true
+ # GOTRUE_SMTP_MAX_FREQUENCY: 1s
+ GOTRUE_SMTP_ADMIN_EMAIL: ${SMTP_ADMIN_EMAIL}
+ GOTRUE_SMTP_HOST: ${SMTP_HOSTNAME}
+ GOTRUE_SMTP_PORT: ${SMTP_PORT}
+ GOTRUE_SMTP_USER: ${SMTP_USER}
+ GOTRUE_SMTP_PASS: ${SMTP_PASS}
+ GOTRUE_SMTP_SENDER_NAME: ${SMTP_SENDER_NAME}
+ GOTRUE_MAILER_URLPATHS_INVITE: ${MAILER_URLPATHS_INVITE}
+ GOTRUE_MAILER_URLPATHS_CONFIRMATION: ${MAILER_URLPATHS_CONFIRMATION}
+ GOTRUE_MAILER_URLPATHS_RECOVERY: ${MAILER_URLPATHS_RECOVERY}
+ GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: ${MAILER_URLPATHS_EMAIL_CHANGE}
+
+ GOTRUE_EXTERNAL_PHONE_ENABLED: ${ENABLE_PHONE_SIGNUP}
+ GOTRUE_SMS_AUTOCONFIRM: ${ENABLE_PHONE_AUTOCONFIRM}
+ # Uncomment to enable custom access token hook. You'll need to create a public.custom_access_token_hook function and grant necessary permissions.
+ # See: https://supabase.com/docs/guides/auth/auth-hooks#hook-custom-access-token for details
+ # GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_ENABLED="true"
+ # GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_URI="pg-functions://postgres/public/custom_access_token_hook"
+
+ # GOTRUE_HOOK_MFA_VERIFICATION_ATTEMPT_ENABLED="true"
+ # GOTRUE_HOOK_MFA_VERIFICATION_ATTEMPT_URI="pg-functions://postgres/public/mfa_verification_attempt"
+
+ # GOTRUE_HOOK_PASSWORD_VERIFICATION_ATTEMPT_ENABLED="true"
+ # GOTRUE_HOOK_PASSWORD_VERIFICATION_ATTEMPT_URI="pg-functions://postgres/public/password_verification_attempt"
+
+ rest:
+ container_name: supabase-rest
+ image: postgrest/postgrest:v12.2.0
+
+ depends_on:
+ db:
+ # Disable this if you are using an external Postgres database
+ condition: service_healthy
+ analytics:
+ condition: service_healthy
+ restart: unless-stopped
+ environment:
+ PGRST_DB_URI: postgres://authenticator:${POSTGRES_PASSWORD}@${POSTGRES_HOSTNAME}:${POSTGRES_PORT}/${POSTGRES_DB}
+ PGRST_DB_SCHEMAS: ${PGRST_DB_SCHEMAS}
+ PGRST_DB_ANON_ROLE: anon
+ PGRST_JWT_SECRET: ${JWT_SECRET}
+ PGRST_DB_USE_LEGACY_GUCS: "false"
+ PGRST_APP_SETTINGS_JWT_SECRET: ${JWT_SECRET}
+ PGRST_APP_SETTINGS_JWT_EXP: ${JWT_EXPIRY}
+ command: "postgrest"
+
+ realtime:
+ # This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain
+ container_name: realtime-dev.supabase-realtime
+ image: supabase/realtime:v2.30.23
+
+ depends_on:
+ db:
+ # Disable this if you are using an external Postgres database
+ condition: service_healthy
+ analytics:
+ condition: service_healthy
+ healthcheck:
+ test:
+ [
+ "CMD",
+ "curl",
+ "-sSfL",
+ "--head",
+ "-o",
+ "/dev/null",
+ "-H",
+ "Authorization: Bearer ${ANON_KEY}",
+ "http://localhost:4000/api/tenants/realtime-dev/health",
+ ]
+ timeout: 5s
+ interval: 5s
+ retries: 3
+ restart: unless-stopped
+ environment:
+ PORT: 4000
+ DB_HOST: ${POSTGRES_HOSTNAME}
+ DB_PORT: ${POSTGRES_PORT}
+ DB_USER: supabase_admin
+ DB_PASSWORD: ${POSTGRES_PASSWORD}
+ DB_NAME: ${POSTGRES_DB}
+ DB_AFTER_CONNECT_QUERY: "SET search_path TO _realtime"
+ DB_ENC_KEY: supabaserealtime
+ API_JWT_SECRET: ${JWT_SECRET}
+ SECRET_KEY_BASE: UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq
+ ERL_AFLAGS: -proto_dist inet_tcp
+ DNS_NODES: "''"
+ RLIMIT_NOFILE: "10000"
+ APP_NAME: realtime
+ SEED_SELF_HOST: true
+
+ # To use S3 backed storage: docker compose -f docker-compose.yml -f docker-compose.s3.yml up
+ storage:
+ container_name: supabase-storage
+ image: supabase/storage-api:v1.0.6
+
+ depends_on:
+ db:
+ # Disable this if you are using an external Postgres database
+ condition: service_healthy
+ rest:
+ condition: service_started
+ imgproxy:
+ condition: service_started
+ healthcheck:
+ test:
+ [
+ "CMD",
+ "wget",
+ "--no-verbose",
+ "--tries=1",
+ "--spider",
+ "http://localhost:5000/status",
+ ]
+ timeout: 5s
+ interval: 5s
+ retries: 3
+ restart: unless-stopped
+ environment:
+ ANON_KEY: ${ANON_KEY}
+ SERVICE_KEY: ${SERVICE_ROLE_KEY}
+ POSTGREST_URL: http://rest:3000
+ PGRST_JWT_SECRET: ${JWT_SECRET}
+ DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOSTNAME}:${POSTGRES_PORT}/${POSTGRES_DB}
+ FILE_SIZE_LIMIT: 52428800
+ STORAGE_BACKEND: file
+ FILE_STORAGE_BACKEND_PATH: /var/lib/storage
+ TENANT_ID: stub
+ # TODO: https://github.com/supabase/storage-api/issues/55
+ REGION: stub
+ GLOBAL_S3_BUCKET: stub
+ ENABLE_IMAGE_TRANSFORMATION: "true"
+ IMGPROXY_URL: http://imgproxy:5001
+ volumes:
+ - ../files/volumes/storage:/var/lib/storage:z
+
+ imgproxy:
+ container_name: supabase-imgproxy
+ image: darthsim/imgproxy:v3.8.0
+
+ healthcheck:
+ test: ["CMD", "imgproxy", "health"]
+ timeout: 5s
+ interval: 5s
+ retries: 3
+ environment:
+ IMGPROXY_BIND: ":5001"
+ IMGPROXY_LOCAL_FILESYSTEM_ROOT: /
+ IMGPROXY_USE_ETAG: "true"
+ IMGPROXY_ENABLE_WEBP_DETECTION: ${IMGPROXY_ENABLE_WEBP_DETECTION}
+ volumes:
+ - ../files/volumes/storage:/var/lib/storage:z
+
+ meta:
+ container_name: supabase-meta
+ image: supabase/postgres-meta:v0.83.2
+
+ depends_on:
+ db:
+ # Disable this if you are using an external Postgres database
+ condition: service_healthy
+ analytics:
+ condition: service_healthy
+ restart: unless-stopped
+ environment:
+ PG_META_PORT: 8080
+ PG_META_DB_HOST: ${POSTGRES_HOSTNAME}
+ PG_META_DB_PORT: ${POSTGRES_PORT}
+ PG_META_DB_NAME: ${POSTGRES_DB}
+ PG_META_DB_USER: supabase_admin
+ PG_META_DB_PASSWORD: ${POSTGRES_PASSWORD}
+
+ functions:
+ container_name: supabase-edge-functions
+ image: supabase/edge-runtime:v1.56.0
+ restart: unless-stopped
+
+ depends_on:
+ analytics:
+ condition: service_healthy
+ environment:
+ JWT_SECRET: ${JWT_SECRET}
+ SUPABASE_URL: http://kong:8000
+ SUPABASE_ANON_KEY: ${ANON_KEY}
+ SUPABASE_SERVICE_ROLE_KEY: ${SERVICE_ROLE_KEY}
+ SUPABASE_DB_URL: postgresql://postgres:${POSTGRES_PASSWORD}@${POSTGRES_HOSTNAME}:${POSTGRES_PORT}/${POSTGRES_DB}
+ # TODO: Allow configuring VERIFY_JWT per function. This PR might help: https://github.com/supabase/cli/pull/786
+ VERIFY_JWT: "${FUNCTIONS_VERIFY_JWT}"
+ volumes:
+ - ../files/volumes/functions:/home/deno/functions:Z
+ command:
+ - start
+ - --main-service
+ - /home/deno/functions/main
+
+ analytics:
+ container_name: supabase-analytics
+ image: supabase/logflare:1.4.0
+
+ healthcheck:
+ test: ["CMD", "curl", "http://localhost:4000/health"]
+ timeout: 5s
+ interval: 5s
+ retries: 10
+ restart: unless-stopped
+ depends_on:
+ db:
+ # Disable this if you are using an external Postgres database
+ condition: service_healthy
+ # Uncomment to use Big Query backend for analytics
+ # volumes:
+ # - type: bind
+ # source: ${PWD}/gcloud.json
+ # target: /opt/app/rel/logflare/bin/gcloud.json
+ # read_only: true
+ environment:
+ LOGFLARE_NODE_HOST: 127.0.0.1
+ DB_USERNAME: supabase_admin
+ DB_DATABASE: ${POSTGRES_DB}
+ DB_HOSTNAME: ${POSTGRES_HOSTNAME}
+ DB_PORT: ${POSTGRES_PORT}
+ DB_PASSWORD: ${POSTGRES_PASSWORD}
+ DB_SCHEMA: _analytics
+ LOGFLARE_API_KEY: ${LOGFLARE_API_KEY}
+ LOGFLARE_SINGLE_TENANT: true
+ LOGFLARE_SUPABASE_MODE: true
+ LOGFLARE_MIN_CLUSTER_SIZE: 1
+
+ # Comment variables to use Big Query backend for analytics
+ POSTGRES_BACKEND_URL: postgresql://supabase_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOSTNAME}:${POSTGRES_PORT}/${POSTGRES_DB}
+ POSTGRES_BACKEND_SCHEMA: _analytics
+ LOGFLARE_FEATURE_FLAG_OVERRIDE: multibackend=true
+ # Uncomment to use Big Query backend for analytics
+ # GOOGLE_PROJECT_ID: ${GOOGLE_PROJECT_ID}
+ # GOOGLE_PROJECT_NUMBER: ${GOOGLE_PROJECT_NUMBER}
+ #ports:
+ # - 4000:4000
+ expose:
+ - 4000
+
+ # Comment out everything below this point if you are using an external Postgres database
+ db:
+ container_name: supabase-db
+ image: supabase/postgres:15.1.1.78
+
+ healthcheck:
+ test: pg_isready -U postgres -h localhost
+ interval: 5s
+ timeout: 5s
+ retries: 10
+ depends_on:
+ vector:
+ condition: service_healthy
+ command:
+ - postgres
+ - -c
+ - config_file=/etc/postgresql/postgresql.conf
+ - -c
+ - log_min_messages=fatal # prevents Realtime polling queries from appearing in logs
+ restart: unless-stopped
+ #ports:
+ # # Pass down internal port because it's set dynamically by other services
+ # - ${POSTGRES_PORT}:${POSTGRES_PORT}
+ expose:
+ - ${POSTGRES_PORT}
+ environment:
+ POSTGRES_HOST: /var/run/postgresql
+ PGPORT: ${POSTGRES_PORT}
+ POSTGRES_PORT: ${POSTGRES_PORT}
+ PGPASSWORD: ${POSTGRES_PASSWORD}
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+ PGDATABASE: ${POSTGRES_DB}
+ POSTGRES_DB: ${POSTGRES_DB}
+ JWT_SECRET: ${JWT_SECRET}
+ JWT_EXP: ${JWT_EXPIRY}
+ volumes:
+ - ../files/volumes/db/realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql:Z
+ # Must be superuser to create event trigger
+ - ../files/volumes/db/webhooks.sql:/docker-entrypoint-initdb.d/init-scripts/98-webhooks.sql:Z
+ # Must be superuser to alter reserved role
+ - ../files/volumes/db/roles.sql:/docker-entrypoint-initdb.d/init-scripts/99-roles.sql:Z
+ # Initialize the database settings with JWT_SECRET and JWT_EXP
+ - ../files/volumes/db/jwt.sql:/docker-entrypoint-initdb.d/init-scripts/99-jwt.sql:Z
+ # PGDATA directory is persisted between restarts
+ - ../files/volumes/db/data:/var/lib/postgresql/data:Z
+ # Changes required for Analytics support
+ - ../files/volumes/db/logs.sql:/docker-entrypoint-initdb.d/migrations/99-logs.sql:Z
+ # Use named volume to persist pgsodium decryption key between restarts
+ - db-config:/etc/postgresql-custom
+
+ vector:
+ container_name: supabase-vector
+ image: timberio/vector:0.28.1-alpine
+
+ healthcheck:
+ test:
+ [
+ "CMD",
+ "wget",
+ "--no-verbose",
+ "--tries=1",
+ "--spider",
+ "http://vector:9001/health",
+ ]
+ timeout: 5s
+ interval: 5s
+ retries: 3
+ volumes:
+ - ../files/volumes/logs/vector.yml:/etc/vector/vector.yml:ro
+ - ${DOCKER_SOCKET_LOCATION}:/var/run/docker.sock:ro
+ environment:
+ LOGFLARE_API_KEY: ${LOGFLARE_API_KEY}
+ command: ["--config", "etc/vector/vector.yml"]
+
+volumes:
+ db-config:
+
+networks:
+ dokploy-network:
+ external: true
diff --git a/blueprints/supabase/supabase.svg b/blueprints/supabase/supabase.svg
new file mode 100644
index 000000000..2b69d42e7
--- /dev/null
+++ b/blueprints/supabase/supabase.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/supabase/template.yml b/blueprints/supabase/template.yml
new file mode 100644
index 000000000..22bb73918
--- /dev/null
+++ b/blueprints/supabase/template.yml
@@ -0,0 +1,183 @@
+variables:
+ main_domain: ${domain}
+ postgres_password: ${password:32}
+ jwt_secret: ${base64:32}
+ dashboard_password: ${password:32}
+ logflare_api_key: ${password:32}
+ anon_key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzQxNTAwMDAwLAogICJleHAiOiAxODk5MjY2NDAwCn0.muKe0Nrvkf5bMyLoFqAuFypRu3jHAcTYU08SYKrgRQo
+ service_role_key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogInNlcnZpY2Vfcm9sZSIsCiAgImlzcyI6ICJzdXBhYmFzZSIsCiAgImlhdCI6IDE3NDE1MDAwMDAsCiAgImV4cCI6IDE4OTkyNjY0MDAKfQ.1KoSiJVueKJNkF59uc84BLqk7h8VdAoVp6Gozqr_vGc
+
+config:
+ domains:
+ - serviceName: kong
+ port: 8000
+ host: ${main_domain}
+
+ env:
+ SUPABASE_HOST: ${main_domain}
+ POSTGRES_PASSWORD: ${postgres_password}
+ JWT_SECRET: ${jwt_secret}
+ ANON_KEY: ${anon_key}
+ SERVICE_ROLE_KEY: ${service_role_key}
+ DASHBOARD_USERNAME: "supabase"
+ DASHBOARD_PASSWORD: ${dashboard_password}
+ POSTGRES_HOSTNAME: "db"
+ POSTGRES_DB: "postgres"
+ POSTGRES_PORT: "5432"
+ KONG_HTTP_PORT: "8000"
+ KONG_HTTPS_PORT: "8443"
+ PGRST_DB_SCHEMAS: "public,storage,graphql_public"
+ ADDITIONAL_REDIRECT_URLS: ""
+ JWT_EXPIRY: "3600"
+ DISABLE_SIGNUP: "false"
+ MAILER_URLPATHS_CONFIRMATION: "\"/auth/v1/verify\""
+ MAILER_URLPATHS_INVITE: "\"/auth/v1/verify\""
+ MAILER_URLPATHS_RECOVERY: "\"/auth/v1/verify\""
+ MAILER_URLPATHS_EMAIL_CHANGE: "\"/auth/v1/verify\""
+ ENABLE_EMAIL_SIGNUP: "true"
+ ENABLE_EMAIL_AUTOCONFIRM: "false"
+ SMTP_ADMIN_EMAIL: "admin@example.com"
+ SMTP_HOSTNAME: "supabase-mail"
+ SMTP_PORT: "2500"
+ SMTP_USER: "fake_mail_user"
+ SMTP_PASS: "fake_mail_password"
+ SMTP_SENDER_NAME: "fake_sender"
+ ENABLE_ANONYMOUS_USERS: "false"
+ ENABLE_PHONE_SIGNUP: "true"
+ ENABLE_PHONE_AUTOCONFIRM: "true"
+ STUDIO_DEFAULT_ORGANIZATION: "Default Organization"
+ STUDIO_DEFAULT_PROJECT: "Default Project"
+ STUDIO_PORT: "3000"
+ IMGPROXY_ENABLE_WEBP_DETECTION: "true"
+ FUNCTIONS_VERIFY_JWT: "false"
+ LOGFLARE_LOGGER_BACKEND_API_KEY: ${logflare_api_key}
+ LOGFLARE_API_KEY: ${logflare_api_key}
+ DOCKER_SOCKET_LOCATION: "/var/run/docker.sock"
+ GOOGLE_PROJECT_ID: "GOOGLE_PROJECT_ID"
+ GOOGLE_PROJECT_NUMBER: "GOOGLE_PROJECT_NUMBER"
+
+ mounts:
+ - filePath: /volumes/api/kong.yml
+ content: |
+ _format_version: '2.1'
+ _transform: true
+
+ ###
+ ### Consumers / Users
+ ###
+ consumers:
+ - username: DASHBOARD
+ - username: anon
+ keyauth_credentials:
+ - key: $SUPABASE_ANON_KEY
+ - username: service_role
+ keyauth_credentials:
+ - key: $SUPABASE_SERVICE_KEY
+
+ ###
+ ### Access Control List
+ ###
+ acls:
+ - consumer: anon
+ group: anon
+ - consumer: service_role
+ group: admin
+
+ ###
+ ### Dashboard credentials
+ ###
+ basicauth_credentials:
+ - consumer: DASHBOARD
+ username: $DASHBOARD_USERNAME
+ password: $DASHBOARD_PASSWORD
+
+ ###
+ ### API Routes
+ ###
+ services:
+ ## Open Auth routes
+ - name: auth-v1-open
+ url: http://auth:9999/verify
+ routes:
+ - name: auth-v1-open
+ strip_path: true
+ paths:
+ - /auth/v1/verify
+ plugins:
+ - name: cors
+ - name: auth-v1-open-callback
+ url: http://auth:9999/callback
+ routes:
+ - name: auth-v1-open-callback
+ strip_path: true
+ paths:
+ - /auth/v1/callback
+ plugins:
+ - name: cors
+ - name: auth-v1-open-authorize
+ url: http://auth:9999/authorize
+ routes:
+ - name: auth-v1-open-authorize
+ strip_path: true
+ paths:
+ - /auth/v1/authorize
+ plugins:
+ - name: cors
+
+ ## Secure Auth routes
+ - name: auth-v1
+ _comment: 'GoTrue: /auth/v1/* -> http://auth:9999/*'
+ url: http://auth:9999/
+ routes:
+ - name: auth-v1-all
+ strip_path: true
+ paths:
+ - /auth/v1/
+ plugins:
+ - name: cors
+ - name: key-auth
+ config:
+ hide_credentials: false
+ - name: acl
+ config:
+ hide_groups_header: true
+ allow:
+ - admin
+ - anon
+
+ ## Secure REST routes
+ - name: rest-v1
+ _comment: 'PostgREST: /rest/v1/* -> http://rest:3000/*'
+ url: http://rest:3000/
+ routes:
+ - name: rest-v1-all
+ strip_path: true
+ paths:
+ - /rest/v1/
+ plugins:
+ - name: cors
+ - name: key-auth
+ config:
+ hide_credentials: true
+ - name: acl
+ config:
+ hide_groups_header: true
+ allow:
+ - admin
+ - anon
+
+ ## Secure GraphQL routes
+ - name: graphql-v1
+ _comment: 'PostgREST: /graphql/v1/* -> http://rest:3000/rpc/graphql'
+ url: http://rest:3000/rpc/graphql
+ routes:
+ - name: graphql-v1-all
+ strip_path: true
+ paths:
+ - /graphql/v1
+ plugins:
+ - name: cors
+ - name: key-auth
+ config:
+ hide_credentials: true
+ - name: request-transformer
\ No newline at end of file
diff --git a/blueprints/superset/docker-compose.yml b/blueprints/superset/docker-compose.yml
new file mode 100644
index 000000000..e786a9340
--- /dev/null
+++ b/blueprints/superset/docker-compose.yml
@@ -0,0 +1,87 @@
+# This is an UNOFFICIAL production docker image build for Superset:
+# - https://github.com/amancevice/docker-superset
+
+
+# ## SETUP INSTRUCTIONS
+#
+# After deploying this image, you will need to run one of the two
+# commands below in a terminal within the superset container:
+# $ superset-demo # Initialise database + load demo charts/datasets
+# $ superset-init # Initialise database only
+#
+# You will be prompted to enter the credentials for the admin user.
+
+
+# ## NETWORK INSTRUCTIONS
+#
+# If you want to connect superset with other internal databases managed by
+# Dokploy (on dokploy-network) using internal hostnames, you will need to
+# uncomment the `networks` section, both for the superset container and
+# at the very bottom of this docker-compose template.
+#
+# Note that the `superset` service name/hostname will not be unique on the
+# global `dokploy-network`. If you plan to:
+#
+# 1. deploy a second instance of superset on dokploy-network, and
+# 2. have other containers on dokploy-network utilise the second instance's
+# Superset API (https://superset.apache.org/docs/api)
+#
+# Please change the service name of the second instance.
+
+services:
+ superset:
+ image: amancevice/superset
+ restart: always
+ #networks:
+ # - dokploy-network
+ depends_on:
+ - superset_postgres
+ - superset_redis
+ volumes:
+ # This superset_config.py can be edited in Dokploy's UI Advanced -> Volume Mount
+ - ../files/superset/superset_config.py:/etc/superset/superset_config.py
+ environment:
+ SECRET_KEY: ${SECRET_KEY}
+ MAPBOX_API_KEY: ${MAPBOX_API_KEY}
+ POSTGRES_USER: ${POSTGRES_USER}
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+ POSTGRES_DB: ${POSTGRES_DB}
+ REDIS_PASSWORD: ${REDIS_PASSWORD}
+ # Ensure the hosts matches your service names below.
+ POSTGRES_HOST: superset_postgres
+ REDIS_HOST: superset_redis
+
+ superset_postgres:
+ image: postgres
+ restart: always
+ environment:
+ POSTGRES_USER: ${POSTGRES_USER}
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+ POSTGRES_DB: ${POSTGRES_DB}
+ volumes:
+ - superset_postgres_data:/var/lib/postgresql/data
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+
+ superset_redis:
+ image: redis
+ restart: always
+ volumes:
+ - superset_redis_data:/data
+ command: redis-server --requirepass ${REDIS_PASSWORD}
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+
+#networks:
+# dokploy-network:
+# external: true
+
+volumes:
+ superset_postgres_data:
+ superset_redis_data:
diff --git a/blueprints/superset/superset.svg b/blueprints/superset/superset.svg
new file mode 100644
index 000000000..522c3b28a
--- /dev/null
+++ b/blueprints/superset/superset.svg
@@ -0,0 +1,9 @@
+
+
+ Superset
+
+
+
+
+
+
diff --git a/blueprints/superset/template.yml b/blueprints/superset/template.yml
new file mode 100644
index 000000000..d06519f97
--- /dev/null
+++ b/blueprints/superset/template.yml
@@ -0,0 +1,54 @@
+variables:
+ main_domain: ${domain}
+ secret_key: ${password:30}
+ postgres_password: ${password:30}
+ redis_password: ${password:30}
+ mapbox_api_key: ""
+
+config:
+ domains:
+ - serviceName: superset
+ port: 8088
+ host: ${main_domain}
+
+ env:
+ SECRET_KEY: ${secret_key}
+ MAPBOX_API_KEY: ${mapbox_api_key}
+ POSTGRES_DB: "superset"
+ POSTGRES_USER: "superset"
+ POSTGRES_PASSWORD: ${postgres_password}
+ REDIS_PASSWORD: ${redis_password}
+
+ mounts:
+ - filePath: ./superset/superset_config.py
+ content: |
+ """
+ For more configuration options, see:
+ - https://superset.apache.org/docs/configuration/configuring-superset
+ """
+
+ import os
+
+ SECRET_KEY = os.getenv("SECRET_KEY")
+ MAPBOX_API_KEY = os.getenv("MAPBOX_API_KEY", "")
+
+ CACHE_CONFIG = {
+ "CACHE_TYPE": "RedisCache",
+ "CACHE_DEFAULT_TIMEOUT": 300,
+ "CACHE_KEY_PREFIX": "superset_",
+ "CACHE_REDIS_HOST": "redis",
+ "CACHE_REDIS_PORT": 6379,
+ "CACHE_REDIS_DB": 1,
+ "CACHE_REDIS_URL": f"redis://:{os.getenv('REDIS_PASSWORD')}@{os.getenv('REDIS_HOST')}:6379/1",
+ }
+
+ FILTER_STATE_CACHE_CONFIG = {**CACHE_CONFIG, "CACHE_KEY_PREFIX": "superset_filter_"}
+ EXPLORE_FORM_DATA_CACHE_CONFIG = {**CACHE_CONFIG, "CACHE_KEY_PREFIX": "superset_explore_form_"}
+
+ SQLALCHEMY_TRACK_MODIFICATIONS = True
+ SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{os.getenv('POSTGRES_USER')}:{os.getenv('POSTGRES_PASSWORD')}@{os.getenv('POSTGRES_HOST')}:5432/{os.getenv('POSTGRES_DB')}"
+
+ # Uncomment if you want to load example data (using "superset load_examples") at the
+ # same location as your metadata postgresql instance. Otherwise, the default sqlite
+ # will be used, which will not persist in volume when restarting superset by default.
+ #SQLALCHEMY_EXAMPLES_URI = SQLALCHEMY_DATABASE_URI
\ No newline at end of file
diff --git a/blueprints/teable/docker-compose.yml b/blueprints/teable/docker-compose.yml
new file mode 100644
index 000000000..386e37738
--- /dev/null
+++ b/blueprints/teable/docker-compose.yml
@@ -0,0 +1,67 @@
+version: "3.9"
+
+services:
+ teable:
+ image: ghcr.io/teableio/teable:latest
+ restart: always
+ volumes:
+ - teable-data:/app/.assets
+ # you may use a bind-mounted host directory instead,
+ # so that it is harder to accidentally remove the volume and lose all your data!
+ # - ./docker/teable/data:/app/.assets:rw
+ environment:
+ - TZ=${TIMEZONE}
+ - NEXT_ENV_IMAGES_ALL_REMOTE=true
+ - PUBLIC_ORIGIN=${PUBLIC_ORIGIN}
+ - PRISMA_DATABASE_URL=${PRISMA_DATABASE_URL}
+ - PUBLIC_DATABASE_PROXY=${PUBLIC_DATABASE_PROXY}
+ - BACKEND_MAIL_HOST=${BACKEND_MAIL_HOST}
+ - BACKEND_MAIL_PORT=${BACKEND_MAIL_PORT}
+ - BACKEND_MAIL_SECURE=${BACKEND_MAIL_SECURE}
+ - BACKEND_MAIL_SENDER=${BACKEND_MAIL_SENDER}
+ - BACKEND_MAIL_SENDER_NAME=${BACKEND_MAIL_SENDER_NAME}
+ - BACKEND_MAIL_AUTH_USER=${BACKEND_MAIL_AUTH_USER}
+ - BACKEND_MAIL_AUTH_PASS=${BACKEND_MAIL_AUTH_PASS}
+ depends_on:
+ teable-db-migrate:
+ condition: service_completed_successfully
+
+ teable-db:
+ image: postgres:15.4
+ restart: always
+ ports:
+ - "${TEABLE_DB_PORT}:${POSTGRES_PORT}"
+ volumes:
+ - teable-db:/var/lib/postgresql/data
+ # you may use a bind-mounted host directory instead,
+ # so that it is harder to accidentally remove the volume and lose all your data!
+ # - ./docker/db/data:/var/lib/postgresql/data:rw
+ environment:
+ - TZ=${TIMEZONE}
+ - POSTGRES_DB=${POSTGRES_DB}
+ - POSTGRES_USER=${POSTGRES_USER}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+
+ healthcheck:
+ test:
+ [
+ "CMD-SHELL",
+ "sh -c 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}'",
+ ]
+ interval: 10s
+ timeout: 3s
+ retries: 3
+
+ teable-db-migrate:
+ image: ghcr.io/teableio/teable-db-migrate:latest
+ environment:
+ - TZ=${TIMEZONE}
+ - PRISMA_DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
+
+ depends_on:
+ teable-db:
+ condition: service_healthy
+
+volumes:
+ teable-data: {}
+ teable-db: {}
diff --git a/blueprints/teable/teable.png b/blueprints/teable/teable.png
new file mode 100644
index 000000000..f2b938d85
Binary files /dev/null and b/blueprints/teable/teable.png differ
diff --git a/blueprints/teable/template.yml b/blueprints/teable/template.yml
new file mode 100644
index 000000000..834f4cc01
--- /dev/null
+++ b/blueprints/teable/template.yml
@@ -0,0 +1,36 @@
+variables:
+ main_domain: ${domain}
+ db_password: ${password}
+ public_db_port: ${randomPort}
+
+config:
+ domains:
+ - serviceName: teable
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ TEABLE_HOST: ${main_domain}
+ TEABLE_DB_PORT: ${public_db_port}
+ TIMEZONE: "UTC"
+ # Postgres
+ POSTGRES_HOST: "teable-db"
+ POSTGRES_PORT: "5432"
+ POSTGRES_DB: "teable"
+ POSTGRES_USER: "teable"
+ POSTGRES_PASSWORD: ${db_password}
+ # App
+ PUBLIC_ORIGIN: https://${main_domain}
+ PRISMA_DATABASE_URL: postgresql://teable:${db_password}@teable-db:5432/teable
+ PUBLIC_DATABASE_PROXY: ${TEABLE_HOST}:${TEABLE_DB_PORT}
+ # Need to support sending emails to enable the following configurations
+ # You need to modify the configuration according to the actual situation, otherwise it will not be able to send emails correctly.
+ #BACKEND_MAIL_HOST: "smtp.teable.io"
+ #BACKEND_MAIL_PORT: "465"
+ #BACKEND_MAIL_SECURE: "true"
+ #BACKEND_MAIL_SENDER: "noreply.teable.io"
+ #BACKEND_MAIL_SENDER_NAME: "Teable"
+ #BACKEND_MAIL_AUTH_USER: "username"
+ #BACKEND_MAIL_AUTH_PASS: "password"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/tolgee/docker-compose.yml b/blueprints/tolgee/docker-compose.yml
new file mode 100644
index 000000000..f17b9b3c4
--- /dev/null
+++ b/blueprints/tolgee/docker-compose.yml
@@ -0,0 +1,24 @@
+version: "3"
+
+services:
+ app:
+ image: tolgee/tolgee:v3.80.4
+ volumes:
+ - ./data:/data
+ - ./config.yaml:/config.yaml
+ ports:
+ - '8080'
+ environment:
+ TOLGEE_FRONT_END_URL: ${TOLGEE_HOST}
+ TOLGEE_AUTHENTICATION_ENABLED: ${TOLGEE_AUTHENTICATION_ENABLED}
+ TOLGEE_AUTHENTICATION_INITIAL_PASSWORD: ${TOLGEE_AUTHENTICATION_INITIAL_PASSWORD}
+ TOLGEE_AUTHENTICATION_INITIAL_USERNAME: ${TOLGEE_AUTHENTICATION_INITIAL_USERNAME}
+ TOLGEE_AUTHENTICATION_JWT_SECRET: ${TOLGEE_AUTHENTICATION_JWT_SECRET}
+ TOLGEE_MACHINE_TRANSLATION_GOOGLE_API_KEY: ${TOLGEE_MACHINE_TRANSLATION_GOOGLE_API_KEY}
+ TOLGEE_SMTP_AUTH: ${TOLGEE_SMTP_AUTH}
+ TOLGEE_SMTP_FROM: ${TOLGEE_SMTP_FROM}
+ TOLGEE_SMTP_HOST: ${TOLGEE_SMTP_HOST}
+ TOLGEE_SMTP_PASSWORD: ${TOLGEE_SMTP_PASSWORD}
+ TOLGEE_SMTP_PORT: ${TOLGEE_SMTP_PORT}
+ TOLGEE_SMTP_SSL_ENABLED: ${TOLGEE_SMTP_SSL_ENABLED}
+ TOLGEE_SMTP_USERNAME: ${TOLGEE_SMTP_USERNAME}
diff --git a/blueprints/tolgee/template.yml b/blueprints/tolgee/template.yml
new file mode 100644
index 000000000..60d5e2694
--- /dev/null
+++ b/blueprints/tolgee/template.yml
@@ -0,0 +1,26 @@
+variables:
+ main_domain: ${domain}
+ jwt_secret: ${base64:32}
+
+config:
+ domains:
+ - serviceName: app
+ port: 8080
+ host: ${main_domain}
+
+ env:
+ TOLGEE_HOST: ${main_domain}
+ TOLGEE_AUTHENTICATION_ENABLED: "true"
+ TOLGEE_AUTHENTICATION_INITIAL_PASSWORD: "admin"
+ TOLGEE_AUTHENTICATION_INITIAL_USERNAME: "admin"
+ TOLGEE_AUTHENTICATION_JWT_SECRET: ${jwt_secret}
+ TOLGEE_MACHINE_TRANSLATION_GOOGLE_API_KEY: "my_google_api_key"
+ TOLGEE_SMTP_AUTH: "true"
+ TOLGEE_SMTP_FROM: "Tolgee "
+ TOLGEE_SMTPHOST: "email-smtp.regional-region.amazonaws.com"
+ TOLGEE_SMTP_PASSWORD: "omg/my/password"
+ TOLGEE_SMTP_PORT: "465"
+ TOLGEE_SMTP_SSL_ENABLED: "true"
+ TOLGEE_SMTP_USERNAME: "user@company.com"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/tolgee/tolgee.svg b/blueprints/tolgee/tolgee.svg
new file mode 100644
index 000000000..0f216e0c6
--- /dev/null
+++ b/blueprints/tolgee/tolgee.svg
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/blueprints/triggerdotdev/docker-compose.yml b/blueprints/triggerdotdev/docker-compose.yml
new file mode 100644
index 000000000..f53980277
--- /dev/null
+++ b/blueprints/triggerdotdev/docker-compose.yml
@@ -0,0 +1,107 @@
+x-webapp-env: &webapp-env
+ LOGIN_ORIGIN: &trigger-url ${TRIGGER_PROTOCOL:-http}://${TRIGGER_DOMAIN:-localhost:3040}
+ APP_ORIGIN: *trigger-url
+ DEV_OTEL_EXPORTER_OTLP_ENDPOINT: &trigger-otel ${TRIGGER_PROTOCOL:-http}://${TRIGGER_DOMAIN:-localhost:3040}/otel
+ ELECTRIC_ORIGIN: http://electric:3000
+
+x-worker-env: &worker-env
+ PLATFORM_HOST: webapp
+ PLATFORM_WS_PORT: 3030
+ SECURE_CONNECTION: "false"
+ OTEL_EXPORTER_OTLP_ENDPOINT: *trigger-otel
+
+volumes:
+ postgres-data:
+ redis-data:
+
+networks:
+ webapp:
+
+services:
+ webapp:
+ image: ghcr.io/triggerdotdev/trigger.dev:${TRIGGER_IMAGE_TAG:-v3}
+ restart: ${RESTART_POLICY:-unless-stopped}
+ env_file:
+ - .env
+ environment:
+ <<: *webapp-env
+ ports:
+ - 3000
+ depends_on:
+ - postgres
+ - redis
+ networks:
+ - webapp
+
+ postgres:
+ image: postgres:${POSTGRES_IMAGE_TAG:-16}
+ restart: ${RESTART_POLICY:-unless-stopped}
+ volumes:
+ - postgres-data:/var/lib/postgresql/data/
+ env_file:
+ - .env
+ networks:
+ - webapp
+ ports:
+ - 5432
+ command:
+ - -c
+ - wal_level=logical
+
+ redis:
+ image: redis:${REDIS_IMAGE_TAG:-7}
+ restart: ${RESTART_POLICY:-unless-stopped}
+ volumes:
+ - redis-data:/data
+ networks:
+ - webapp
+ ports:
+ - 6379
+
+ docker-provider:
+ image: ghcr.io/triggerdotdev/provider/docker:${TRIGGER_IMAGE_TAG:-v3}
+ restart: ${RESTART_POLICY:-unless-stopped}
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ user: root
+ networks:
+ - webapp
+ depends_on:
+ - webapp
+ ports:
+ - 9020
+ env_file:
+ - .env
+ environment:
+ <<: *worker-env
+ PLATFORM_SECRET: $PROVIDER_SECRET
+
+ coordinator:
+ image: ghcr.io/triggerdotdev/coordinator:${TRIGGER_IMAGE_TAG:-v3}
+ restart: ${RESTART_POLICY:-unless-stopped}
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ user: root
+ networks:
+ - webapp
+ depends_on:
+ - webapp
+ ports:
+ - 9020
+ env_file:
+ - .env
+ environment:
+ <<: *worker-env
+ PLATFORM_SECRET: $COORDINATOR_SECRET
+
+ electric:
+ image: electricsql/electric:${ELECTRIC_IMAGE_TAG:-latest}
+ restart: ${RESTART_POLICY:-unless-stopped}
+ environment:
+ DATABASE_URL: ${DATABASE_URL}?sslmode=disable
+ networks:
+ - webapp
+ depends_on:
+ - postgres
+ ports:
+ - 3000
diff --git a/blueprints/triggerdotdev/template.yml b/blueprints/triggerdotdev/template.yml
new file mode 100644
index 000000000..34cc8b1bc
--- /dev/null
+++ b/blueprints/triggerdotdev/template.yml
@@ -0,0 +1,75 @@
+variables:
+ main_domain: ${domain}
+ magic_link_secret: ${base64:16}
+ session_secret: ${base64:16}
+ encryption_key: ${base64:32}
+ provider_secret: ${base64:32}
+ coordinator_secret: ${base64:32}
+ db_password: ${base64:24}
+ db_user: "triggeruser"
+ db_name: "triggerdb"
+
+config:
+ domains:
+ - serviceName: webapp
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ NODE_ENV: "production"
+ RUNTIME_PLATFORM: "docker-compose"
+ V3_ENABLED: "true"
+
+ # Domain configuration
+ TRIGGER_DOMAIN: ${main_domain}
+ TRIGGER_PROTOCOL: "http"
+
+ # Database configuration with secure credentials
+ POSTGRES_USER: ${db_user}
+ POSTGRES_PASSWORD: ${db_password}
+ POSTGRES_DB: ${db_name}
+ DATABASE_URL: postgresql://${db_user}:${db_password}@postgres:5432/${db_name}
+
+ # Secrets
+ MAGIC_LINK_SECRET: ${magic_link_secret}
+ SESSION_SECRET: ${session_secret}
+ ENCRYPTION_KEY: ${encryption_key}
+ PROVIDER_SECRET: ${provider_secret}
+ COORDINATOR_SECRET: ${coordinator_secret}
+
+ # TRIGGER_TELEMETRY_DISABLED: "1"
+ INTERNAL_OTEL_TRACE_DISABLED: "1"
+ INTERNAL_OTEL_TRACE_LOGGING_ENABLED: "0"
+
+ DEFAULT_ORG_EXECUTION_CONCURRENCY_LIMIT: "300"
+ DEFAULT_ENV_EXECUTION_CONCURRENCY_LIMIT: "100"
+
+ DIRECT_URL: ${DATABASE_URL}
+ REDIS_HOST: "redis"
+ REDIS_PORT: "6379"
+ REDIS_TLS_DISABLED: "true"
+
+ # If this is set, emails that are not specified won't be able to log in
+ # WHITELISTED_EMAILS: "authorized@yahoo.com|authorized@gmail.com"
+ # Accounts with these emails will become admins when signing up and get access to the admin panel
+ # ADMIN_EMAILS: "admin@example.com|another-admin@example.com"
+
+ # If this is set, your users will be able to log in via GitHub
+ # AUTH_GITHUB_CLIENT_ID: ""
+ # AUTH_GITHUB_CLIENT_SECRET: ""
+
+ # E-mail settings
+ # Ensure the FROM_EMAIL matches what you setup with Resend.com
+ # If these are not set, emails will be printed to the console
+ # FROM_EMAIL: ""
+ # REPLY_TO_EMAIL: ""
+ # RESEND_API_KEY: ""
+
+ # Worker settings
+ HTTP_SERVER_PORT: "9020"
+ COORDINATOR_HOST: "127.0.0.1"
+ COORDINATOR_PORT: ${HTTP_SERVER_PORT}
+ # REGISTRY_HOST: ${DEPLOY_REGISTRY_HOST}
+ # REGISTRY_NAMESPACE: ${DEPLOY_REGISTRY_NAMESPACE}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/triggerdotdev/triggerdotdev.svg b/blueprints/triggerdotdev/triggerdotdev.svg
new file mode 100644
index 000000000..4e0957f44
--- /dev/null
+++ b/blueprints/triggerdotdev/triggerdotdev.svg
@@ -0,0 +1,2 @@
+
+Trigger.dev logo
\ No newline at end of file
diff --git a/blueprints/trilium/docker-compose.yml b/blueprints/trilium/docker-compose.yml
new file mode 100644
index 000000000..f549d8204
--- /dev/null
+++ b/blueprints/trilium/docker-compose.yml
@@ -0,0 +1,14 @@
+services:
+ trilium:
+ image: zadam/trilium:latest
+ ports:
+ - 8080
+ networks:
+ - dokploy-network
+ restart: always
+ volumes:
+ - /root/trilium-backups:/home/node/trilium-data/backup
+
+networks:
+ dokploy-network:
+ external: true
diff --git a/blueprints/trilium/template.yml b/blueprints/trilium/template.yml
new file mode 100644
index 000000000..1d8406b79
--- /dev/null
+++ b/blueprints/trilium/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: trilium
+ port: 8080
+ host: ${main_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/trilium/trilium.png b/blueprints/trilium/trilium.png
new file mode 100644
index 000000000..f6afe82f8
Binary files /dev/null and b/blueprints/trilium/trilium.png differ
diff --git a/blueprints/twenty/docker-compose.yml b/blueprints/twenty/docker-compose.yml
new file mode 100644
index 000000000..800e9a724
--- /dev/null
+++ b/blueprints/twenty/docker-compose.yml
@@ -0,0 +1,99 @@
+version: "3.9"
+
+services:
+ twenty-change-vol-ownership:
+ image: ubuntu
+ user: root
+
+ volumes:
+ - twenty-server-local-data:/tmp/server-local-data
+ - twenty-docker-data:/tmp/docker-data
+ command: >
+ bash -c "
+ chown -R 1000:1000 /tmp/server-local-data
+ && chown -R 1000:1000 /tmp/docker-data"
+
+ twenty-server:
+ image: twentycrm/twenty:latest
+
+ volumes:
+ - twenty-server-local-data:/app/packages/twenty-server/${STORAGE_LOCAL_PATH:-.local-storage}
+ - twenty-docker-data:/app/docker-data
+ environment:
+ PORT: 3000
+ PG_DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@twenty-postgres:5432/twenty
+ SERVER_URL: https://${TWENTY_HOST}
+ FRONT_BASE_URL: https://${TWENTY_HOST}
+ REDIS_URL: redis://twenty-redis:6379
+ ENABLE_DB_MIGRATIONS: "true"
+ SIGN_IN_PREFILLED: "true"
+ STORAGE_TYPE: local
+ APP_SECRET: ${APP_SECRET}
+ depends_on:
+ twenty-change-vol-ownership:
+ condition: service_completed_successfully
+ twenty-postgres:
+ condition: service_healthy
+ healthcheck:
+ test: curl --fail http://localhost:3000/healthz
+ interval: 5s
+ timeout: 5s
+ retries: 10
+ restart: always
+
+ twenty-worker:
+ image: twentycrm/twenty:latest
+
+ command: ["yarn", "worker:prod"]
+ environment:
+ PG_DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@twenty-postgres:5432/twenty
+ SERVER_URL: https://${TWENTY_HOST}
+ FRONT_BASE_URL: https://${TWENTY_HOST}
+ REDIS_URL: redis://twenty-redis:6379
+ ENABLE_DB_MIGRATIONS: "false"
+ STORAGE_TYPE: local
+ APP_SECRET: ${APP_SECRET}
+ depends_on:
+ twenty-postgres:
+ condition: service_healthy
+ twenty-server:
+ condition: service_healthy
+ restart: always
+
+ twenty-postgres:
+ image: postgres:16-alpine
+
+ volumes:
+ - twenty-postgres-data:/var/lib/postgresql/data
+ environment:
+ POSTGRES_USER: ${DB_USER}
+ POSTGRES_PASSWORD: ${DB_PASSWORD}
+ POSTGRES_DB: twenty
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d twenty"]
+ interval: 5s
+ timeout: 5s
+ retries: 10
+ restart: always
+
+ twenty-redis:
+ image: redis:latest
+
+ volumes:
+ - twenty-redis-data:/data
+ healthcheck:
+ test: ["CMD", "redis-cli", "ping"]
+ interval: 5s
+ timeout: 5s
+ retries: 10
+ restart: always
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ twenty-docker-data:
+ twenty-postgres-data:
+ twenty-server-local-data:
+ twenty-redis-data:
\ No newline at end of file
diff --git a/blueprints/twenty/template.yml b/blueprints/twenty/template.yml
new file mode 100644
index 000000000..387a55c14
--- /dev/null
+++ b/blueprints/twenty/template.yml
@@ -0,0 +1,21 @@
+variables:
+ main_domain: ${domain}
+ db_password: ${password}
+ db_user: "twenty"
+ app_secret: ${base64:32}
+
+config:
+ domains:
+ - serviceName: twenty-server
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ TWENTY_HOST: ${main_domain}
+ DB_USER: ${db_user}
+ DB_PASSWORD: ${db_password}
+ APP_SECRET: ${app_secret}
+ # Optional: Configure storage path
+ # STORAGE_LOCAL_PATH: ".local-storage"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/twenty/twenty.svg b/blueprints/twenty/twenty.svg
new file mode 100644
index 000000000..bad18fab3
--- /dev/null
+++ b/blueprints/twenty/twenty.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/typebot/docker-compose.yml b/blueprints/typebot/docker-compose.yml
new file mode 100644
index 000000000..7881bd8f6
--- /dev/null
+++ b/blueprints/typebot/docker-compose.yml
@@ -0,0 +1,48 @@
+version: '3.3'
+
+volumes:
+ db-data:
+
+services:
+ typebot-db:
+ image: postgres:14-alpine
+ restart: always
+ volumes:
+ - db-data:/var/lib/postgresql/data
+ environment:
+ POSTGRES_USER: typebot
+ POSTGRES_DB: typebot
+ POSTGRES_PASSWORD: typebot
+
+
+ typebot-builder:
+ image: baptistearno/typebot-builder:2.27
+ restart: always
+ depends_on:
+ - typebot-db
+ environment:
+ ENCRYPTION_SECRET: '${ENCRYPTION_SECRET}'
+ DATABASE_URL: 'postgresql://typebot:typebot@typebot-db:5432/typebot'
+ NEXTAUTH_URL: '${NEXTAUTH_URL}'
+ NEXT_PUBLIC_VIEWER_URL: '${NEXT_PUBLIC_VIEWER_URL}'
+ ADMIN_EMAIL: '${ADMIN_EMAIL}'
+ SMTP_HOST: '${SMTP_HOST}'
+ NEXT_PUBLIC_SMTP_FROM: '${NEXT_PUBLIC_SMTP_FROM}'
+ SMTP_USERNAME: '${SMTP_USERNAME}'
+ SMTP_PASSWORD: '${SMTP_PASSWORD}'
+ DEFAULT_WORKSPACE_PLAN: '${DEFAULT_WORKSPACE_PLAN}'
+
+ typebot-viewer:
+ image: baptistearno/typebot-viewer:2.27.0
+ restart: always
+ environment:
+ ENCRYPTION_SECRET: '${ENCRYPTION_SECRET}'
+ DATABASE_URL: postgresql://typebot:typebot@typebot-db:5432/typebot
+ NEXTAUTH_URL: '${NEXTAUTH_URL}'
+ NEXT_PUBLIC_VIEWER_URL: '${NEXT_PUBLIC_VIEWER_URL}'
+ ADMIN_EMAIL: '${ADMIN_EMAIL}'
+ SMTP_HOST: '${SMTP_HOST}'
+ NEXT_PUBLIC_SMTP_FROM: '${NEXT_PUBLIC_SMTP_FROM}'
+ SMTP_USERNAME: '${SMTP_USERNAME}'
+ SMTP_PASSWORD: '${SMTP_PASSWORD}'
+ DEFAULT_WORKSPACE_PLAN: '${DEFAULT_WORKSPACE_PLAN}'
\ No newline at end of file
diff --git a/blueprints/typebot/template.yml b/blueprints/typebot/template.yml
new file mode 100644
index 000000000..400ffff9a
--- /dev/null
+++ b/blueprints/typebot/template.yml
@@ -0,0 +1,27 @@
+variables:
+ builder_domain: ${domain}
+ viewer_domain: ${domain}
+ encryption_secret: ${base64:24}
+
+config:
+ domains:
+ - serviceName: typebot-builder
+ port: 3000
+ host: ${builder_domain}
+ - serviceName: typebot-viewer
+ port: 3000
+ host: ${viewer_domain}
+
+ env:
+ ENCRYPTION_SECRET: ${encryption_secret}
+ NEXTAUTH_URL: http://${builder_domain}
+ NEXT_PUBLIC_VIEWER_URL: http://${viewer_domain}
+ ADMIN_EMAIL: "typebot@example.com"
+ SMTP_HOST: "'Fill'"
+ SMTP_PORT: "25"
+ SMTP_USERNAME: "'Fill'"
+ SMTP_PASSWORD: "'Fill'"
+ NEXT_PUBLIC_SMTP_FROM: "typebot@example.com"
+ DEFAULT_WORKSPACE_PLAN: "UNLIMITED"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/typebot/typebot.svg b/blueprints/typebot/typebot.svg
new file mode 100644
index 000000000..83d04de25
--- /dev/null
+++ b/blueprints/typebot/typebot.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/umami/template.yml b/blueprints/umami/template.yml
index ece3e01a0..d0b72343d 100644
--- a/blueprints/umami/template.yml
+++ b/blueprints/umami/template.yml
@@ -1,5 +1,5 @@
variables:
- main_domain: ${randomDomain}
+ main_domain: ${domain}
config:
domains:
diff --git a/blueprints/unifi/docker-compose.yml b/blueprints/unifi/docker-compose.yml
new file mode 100644
index 000000000..cf0102c00
--- /dev/null
+++ b/blueprints/unifi/docker-compose.yml
@@ -0,0 +1,46 @@
+services:
+ unifi-network-application:
+ image: lscr.io/linuxserver/unifi-network-application:latest
+ environment:
+ - PUID=1000 # User ID
+ - PGID=1000 # Group ID
+ - TZ=Etc/UTC # Timezone
+ - MONGO_HOST=unifi-db
+ - MONGO_USER=unifi
+ - MONGO_PASS=unifi_password
+ - MONGO_PORT=27017
+ - MONGO_DBNAME=unifi
+ - MEM_LIMIT=1024
+ - MEM_STARTUP=1024
+ - MONGO_TLS= #optional # MongoDB TLS setting
+ - MONGO_AUTHSOURCE= #optional # MongoDB authentication source
+ volumes: # Volumes to mount in the container
+ - ../files/config:/config # Map host directory to container directory
+ ports:
+ - 8443:8443 # HTTPS portal
+ # - 3478:3478/udp # STUN service
+ # - 10001:10001/udp # UniFi AP discovery
+ # - 8080:8080 # HTTP portal
+ # - 1900:1900/udp #optional # For DLNA
+ # - 8843:8843 #optional # HTTPS guest portal
+ # - 8880:8880 #optional # HTTP guest portal
+ # - 6789:6789 #optional # Mobile speed test port
+ # - 5514:5514/udp #optional # Remote syslog port
+ restart: unless-stopped
+ depends_on:
+ - unifi-db
+
+
+ unifi-db:
+ image: mongo:4.4
+ volumes:
+ - ../files/db/data:/data/db
+ - ../files/init-mongo.sh:/docker-entrypoint-initdb.d/init-mongo.sh:ro
+ ports:
+ - 27017
+ restart: unless-stopped
+
+
+networks:
+ dokploy-network:
+ external: true
diff --git a/blueprints/unifi/template.yml b/blueprints/unifi/template.yml
new file mode 100644
index 000000000..cf3d978d9
--- /dev/null
+++ b/blueprints/unifi/template.yml
@@ -0,0 +1,22 @@
+variables: {}
+
+config:
+ domains: []
+
+ env: {}
+
+ mounts:
+ - filePath: init-mongo.sh
+ content: |
+ #!/bin/bash
+ mongo <
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/wikijs/docker-compose.yml b/blueprints/wikijs/docker-compose.yml
new file mode 100644
index 000000000..6b21423d1
--- /dev/null
+++ b/blueprints/wikijs/docker-compose.yml
@@ -0,0 +1,31 @@
+version: '3.5'
+services:
+ wiki:
+ image: ghcr.io/requarks/wiki:2.5
+ restart: unless-stopped
+ environment:
+ - DB_TYPE
+ - DB_HOST
+ - DB_PORT
+ - DB_USER
+ - DB_PASS
+ - DB_NAME
+ depends_on:
+ - db
+ labels:
+ - traefik.enable=true
+ - traefik.constraint-label-stack=wikijs
+ db:
+ image: postgres:14
+ restart: unless-stopped
+ environment:
+ - POSTGRES_USER
+ - POSTGRES_PASSWORD
+ - POSTGRES_DB
+ volumes:
+ - wiki-db-data:/var/lib/postgresql/data
+networks:
+ dokploy-network:
+ external: true
+volumes:
+ wiki-db-data:
diff --git a/blueprints/wikijs/template.yml b/blueprints/wikijs/template.yml
new file mode 100644
index 000000000..ef855ab33
--- /dev/null
+++ b/blueprints/wikijs/template.yml
@@ -0,0 +1,23 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: wiki
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ # Database Setup
+ POSTGRES_USER: "wikijs"
+ POSTGRES_PASSWORD: "wikijsrocks"
+ POSTGRES_DB: "wiki"
+ # WikiJS Database Connection
+ DB_TYPE: "postgres"
+ DB_HOST: "db"
+ DB_PORT: "5432"
+ DB_USER: "wikijs"
+ DB_PASS: "wikijsrocks"
+ DB_NAME: "wiki"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/wikijs/wikijs.svg b/blueprints/wikijs/wikijs.svg
new file mode 100644
index 000000000..78073b234
--- /dev/null
+++ b/blueprints/wikijs/wikijs.svg
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/blueprints/windmill/docker-compose.yml b/blueprints/windmill/docker-compose.yml
new file mode 100644
index 000000000..9e91fa0ab
--- /dev/null
+++ b/blueprints/windmill/docker-compose.yml
@@ -0,0 +1,105 @@
+version: "3.8"
+
+services:
+ windmill-postgres:
+ image: postgres:16
+ shm_size: 1g
+ restart: unless-stopped
+ volumes:
+ - windmill-postgres-data:/var/lib/postgresql/data
+
+ environment:
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+ POSTGRES_DB: windmill
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+ windmill-server:
+ image: ghcr.io/windmill-labs/windmill:main
+
+ restart: unless-stopped
+ environment:
+ - DATABASE_URL=${DATABASE_URL}
+ - MODE=server
+ - BASE_URL=http://${WINDMILL_HOST}
+ depends_on:
+ windmill-postgres:
+ condition: service_healthy
+ volumes:
+ - windmill-worker-logs:/tmp/windmill/logs
+
+ windmill-worker:
+ image: ghcr.io/windmill-labs/windmill:main
+ deploy:
+ replicas: 3
+ resources:
+ limits:
+ cpus: "1"
+ memory: 2048M
+ restart: unless-stopped
+
+ environment:
+ - DATABASE_URL=${DATABASE_URL}
+ - MODE=worker
+ - WORKER_GROUP=default
+ depends_on:
+ windmill-postgres:
+ condition: service_healthy
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - windmill-worker-cache:/tmp/windmill/cache
+ - windmill-worker-logs:/tmp/windmill/logs
+
+ windmill-worker-native:
+ image: ghcr.io/windmill-labs/windmill:main
+ deploy:
+ replicas: 1
+ resources:
+ limits:
+ cpus: "0.1"
+ memory: 128M
+ restart: unless-stopped
+
+ environment:
+ - DATABASE_URL=${DATABASE_URL}
+ - MODE=worker
+ - WORKER_GROUP=native
+ - NUM_WORKERS=8
+ - SLEEP_QUEUE=200
+ depends_on:
+ windmill-postgres:
+ condition: service_healthy
+ volumes:
+ - windmill-worker-logs:/tmp/windmill/logs
+
+ windmill-lsp:
+ image: ghcr.io/windmill-labs/windmill-lsp:latest
+ restart: unless-stopped
+
+ volumes:
+ - windmill-lsp-cache:/root/.cache
+
+ windmill-caddy:
+ image: ghcr.io/windmill-labs/caddy-l4:latest
+ restart: unless-stopped
+
+ volumes:
+ - ../files/Caddyfile:/etc/caddy/Caddyfile
+ environment:
+ - BASE_URL=":80"
+ depends_on:
+ - windmill-server
+ - windmill-lsp
+
+networks:
+ dokploy-network:
+ external: true
+
+volumes:
+ windmill-postgres-data:
+ windmill-worker-cache:
+ windmill-worker-logs:
+ windmill-lsp-cache:
\ No newline at end of file
diff --git a/blueprints/windmill/template.yml b/blueprints/windmill/template.yml
new file mode 100644
index 000000000..682b122ef
--- /dev/null
+++ b/blueprints/windmill/template.yml
@@ -0,0 +1,23 @@
+variables:
+ main_domain: ${domain}
+ postgres_password: ${password}
+
+config:
+ domains:
+ - serviceName: windmill-caddy
+ port: 80
+ host: ${main_domain}
+
+ env:
+ WINDMILL_HOST: ${main_domain}
+ POSTGRES_PASSWORD: ${postgres_password}
+ DATABASE_URL: postgres://postgres:${postgres_password}@windmill-postgres/windmill?sslmode=disable
+
+ mounts:
+ - filePath: Caddyfile
+ content: |
+ :80 {
+ bind 0.0.0.0
+ reverse_proxy /ws/* http://windmill-lsp:3001
+ reverse_proxy /* http://windmill-server:8000
+ }
\ No newline at end of file
diff --git a/blueprints/windmill/windmill.svg b/blueprints/windmill/windmill.svg
new file mode 100644
index 000000000..2b06716f9
--- /dev/null
+++ b/blueprints/windmill/windmill.svg
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/blueprints/windows/docker-compose.yml b/blueprints/windows/docker-compose.yml
new file mode 100644
index 000000000..8a0833702
--- /dev/null
+++ b/blueprints/windows/docker-compose.yml
@@ -0,0 +1,17 @@
+services:
+ windows:
+ image: dockurr/windows:4.00
+ volumes:
+ - win-storage:/storage
+ environment:
+ - VERSION
+ - KVM
+ devices:
+ # If in .env string 'KVM=N' is not commented, you need to comment line below
+ - /dev/kvm
+ cap_add:
+ - NET_ADMIN
+ stop_grace_period: 2m
+
+volumes:
+ win-storage:
\ No newline at end of file
diff --git a/blueprints/windows/template.yml b/blueprints/windows/template.yml
new file mode 100644
index 000000000..dc138d932
--- /dev/null
+++ b/blueprints/windows/template.yml
@@ -0,0 +1,27 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: windows
+ port: 8006
+ host: ${main_domain}
+
+ env:
+ # https://github.com/dockur/windows?tab=readme-ov-file#how-do-i-select-the-windows-version
+ VERSION: "win11"
+
+ # Uncomment this if your PC/VM or etc does not support virtualization technology
+ # KVM: "N"
+
+ DISK_SIZE: "64G"
+ RAM_SIZE: "4G"
+ CPU_CORES: "2"
+
+ USERNAME: "Dokploy"
+ PASSWORD: ""
+
+ # https://github.com/dockur/windows?tab=readme-ov-file#how-do-i-select-the-windows-language
+ LANGUAGE: "English"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/windows/windows.png b/blueprints/windows/windows.png
new file mode 100644
index 000000000..61ced4559
Binary files /dev/null and b/blueprints/windows/windows.png differ
diff --git a/blueprints/wordpress/docker-compose.yml b/blueprints/wordpress/docker-compose.yml
new file mode 100644
index 000000000..f2fc4d9a5
--- /dev/null
+++ b/blueprints/wordpress/docker-compose.yml
@@ -0,0 +1,25 @@
+version: "3.8"
+services:
+ wordpress:
+ image: wordpress:6.7.1
+ environment:
+ WORDPRESS_DB_HOST: db
+ WORDPRESS_DB_USER: exampleuser
+ WORDPRESS_DB_PASSWORD: examplepass
+ WORDPRESS_DB_NAME: exampledb
+ volumes:
+ - wordpress_data:/var/www/html
+
+ db:
+ image: mysql:5.7.34
+ environment:
+ MYSQL_DATABASE: exampledb
+ MYSQL_USER: exampleuser
+ MYSQL_PASSWORD: examplepass
+ MYSQL_ROOT_PASSWORD: rootpass
+ volumes:
+ - db_data:/var/lib/mysql
+
+volumes:
+ wordpress_data:
+ db_data:
diff --git a/blueprints/wordpress/template.yml b/blueprints/wordpress/template.yml
new file mode 100644
index 000000000..067640b63
--- /dev/null
+++ b/blueprints/wordpress/template.yml
@@ -0,0 +1,12 @@
+variables:
+ main_domain: ${domain}
+
+config:
+ domains:
+ - serviceName: wordpress
+ port: 80
+ host: ${main_domain}
+
+ env: {}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/wordpress/wordpress.png b/blueprints/wordpress/wordpress.png
new file mode 100644
index 000000000..693cb9026
Binary files /dev/null and b/blueprints/wordpress/wordpress.png differ
diff --git a/blueprints/yourls/docker-compose.yml b/blueprints/yourls/docker-compose.yml
new file mode 100644
index 000000000..f4aa16e35
--- /dev/null
+++ b/blueprints/yourls/docker-compose.yml
@@ -0,0 +1,41 @@
+version: '3.7'
+
+services:
+ yourls-app:
+ image: yourls:1.9.2
+
+ environment:
+ YOURLS_SITE: https://${YOURLS_HOST}
+ YOURLS_USER: ${YOURLS_ADMIN_USER}
+ YOURLS_PASS: ${YOURLS_ADMIN_PASSWORD}
+ YOURLS_DB_HOST: yourls-mysql
+ YOURLS_DB_USER: yourls
+ YOURLS_DB_PASS: ${MYSQL_PASSWORD}
+ YOURLS_DB_NAME: yourls
+ volumes:
+ - yourls-data:/var/www/html
+ depends_on:
+ yourls-mysql:
+ condition: service_healthy
+ restart: always
+
+ yourls-mysql:
+ image: mysql:5.7
+
+ environment:
+ MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
+ MYSQL_DATABASE: yourls
+ MYSQL_USER: yourls
+ MYSQL_PASSWORD: ${MYSQL_PASSWORD}
+ volumes:
+ - yourls-mysql-data:/var/lib/mysql
+ healthcheck:
+ test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u$$MYSQL_USER", "-p$$MYSQL_PASSWORD"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ restart: always
+
+volumes:
+ yourls-data:
+ yourls-mysql-data:
\ No newline at end of file
diff --git a/blueprints/yourls/template.yml b/blueprints/yourls/template.yml
new file mode 100644
index 000000000..aa8b48323
--- /dev/null
+++ b/blueprints/yourls/template.yml
@@ -0,0 +1,20 @@
+variables:
+ main_domain: ${domain}
+ mysql_password: ${password}
+ mysql_root_password: ${password}
+ admin_password: ${password}
+
+config:
+ domains:
+ - serviceName: yourls-app
+ port: 80
+ host: ${main_domain}
+
+ env:
+ YOURLS_HOST: ${main_domain}
+ YOURLS_ADMIN_USER: "admin"
+ YOURLS_ADMIN_PASSWORD: ${admin_password}
+ MYSQL_PASSWORD: ${mysql_password}
+ MYSQL_ROOT_PASSWORD: ${mysql_root_password}
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/yourls/yourls.svg b/blueprints/yourls/yourls.svg
new file mode 100644
index 000000000..2d1d77339
--- /dev/null
+++ b/blueprints/yourls/yourls.svg
@@ -0,0 +1 @@
+
diff --git a/blueprints/zipline/docker-compose.yml b/blueprints/zipline/docker-compose.yml
new file mode 100644
index 000000000..6227164f8
--- /dev/null
+++ b/blueprints/zipline/docker-compose.yml
@@ -0,0 +1,38 @@
+version: "3"
+services:
+ postgres:
+ image: postgres:15
+
+ restart: unless-stopped
+ environment:
+ - POSTGRES_USER=postgres
+ - POSTGRES_PASSWORD=postgres
+ - POSTGRES_DATABASE=postgres
+ volumes:
+ - pg_data:/var/lib/postgresql/data
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+ zipline:
+ image: ghcr.io/diced/zipline:4
+ restart: unless-stopped
+ environment:
+ - CORE_RETURN_HTTPS=${ZIPLINE_RETURN_HTTPS}
+ - CORE_SECRET=${ZIPLINE_SECRET}
+ - CORE_HOSTNAME=0.0.0.0
+ - CORE_PORT=${ZIPLINE_PORT}
+ - DATABASE_URL=postgres://postgres:postgres@postgres/postgres
+ - CORE_LOGGER=${ZIPLINE_LOGGER}
+ - DATASOURCE_TYPE=local
+ - DATASOURCE_LOCAL_DIRECTORY=./uploads
+ volumes:
+ - "../files/uploads:/zipline/uploads"
+ - "../files/public:/zipline/public"
+ depends_on:
+ - "postgres"
+
+volumes:
+ pg_data:
diff --git a/blueprints/zipline/template.yml b/blueprints/zipline/template.yml
new file mode 100644
index 000000000..fe6d12425
--- /dev/null
+++ b/blueprints/zipline/template.yml
@@ -0,0 +1,17 @@
+variables:
+ main_domain: ${domain}
+ secret_base: ${base64:64}
+
+config:
+ domains:
+ - serviceName: zipline
+ port: 3000
+ host: ${main_domain}
+
+ env:
+ ZIPLINE_PORT: "3000"
+ ZIPLINE_SECRET: ${secret_base}
+ ZIPLINE_RETURN_HTTPS: "false"
+ ZIPLINE_LOGGER: "true"
+
+ mounts: []
\ No newline at end of file
diff --git a/blueprints/zipline/zipline.png b/blueprints/zipline/zipline.png
new file mode 100644
index 000000000..2b8f6972d
Binary files /dev/null and b/blueprints/zipline/zipline.png differ
diff --git a/meta.json b/meta.json
index 3ebaad8ea..0b01ced56 100644
--- a/meta.json
+++ b/meta.json
@@ -1,51 +1,1813 @@
[
{
- "id": "pocketbase",
- "name": "PocketBase",
- "description": "Open Source backend in 1 file",
- "version": "v0.22.4",
- "logo": "logo.svg",
- "links": {
- "github": "https://github.com/pocketbase/pocketbase",
- "website": "https://pocketbase.io/",
- "docs": "https://pocketbase.io/docs/"
- },
- "tags": [
- "backend",
- "database",
- "api"
- ]
- },
- {
- "id":"plausible",
- "name":"Plausible",
- "description":"Simple, reliable, and privacy-friendly web analytics",
- "version":"v1.1.0",
- "logo":"logo.svg",
- "links":{
- "github":"https://github.com/plausible/analytics",
- "website":"https://plausible.io/",
- "docs":"https://plausible.io/docs/"
- },
- "tags":[
- "analytics",
- "privacy"
- ]
- },
- {
- "id": "umami",
- "name": "Umami",
- "version": "v2.16.1",
- "description":
- "Umami is a simple, fast, privacy-focused alternative to Google Analytics.",
- "logo": "umami.png",
- "links": {
- "github": "https://github.com/umami-software/umami",
- "website": "https://umami.is",
- "docs": "https://umami.is/docs"
- },
- "tags": [
- "analytics"
- ]
+ "id": "appwrite",
+ "name": "Appwrite",
+ "version": "1.6.0",
+ "description": "Appwrite is an end-to-end backend server for Web, Mobile, Native, or Backend apps. Appwrite abstracts the complexity and repetitiveness required to build a modern backend API from scratch and allows you to build secure apps faster.\nUsing Appwrite, you can easily integrate your app with user authentication and multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, Cloud Functions, messaging, and more services.",
+ "links": {
+ "github": "https://github.com/appwrite/appwrite",
+ "website": "https://appwrite.io/",
+ "docs": "https://appwrite.io/docs"
+ },
+ "logo": "appwrite.svg",
+ "tags": [
+ "database",
+ "firebase",
+ "postgres"
+ ]
+ },
+ {
+ "id": "outline",
+ "name": "Outline",
+ "version": "0.82.0",
+ "description": "Outline is a self-hosted knowledge base and documentation platform that allows you to build and manage your own knowledge base applications.",
+ "links": {
+ "github": "https://github.com/outline/outline",
+ "website": "https://getoutline.com/",
+ "docs": "https://docs.getoutline.com/s/guide"
+ },
+ "logo": "outline.png",
+ "tags": [
+ "documentation",
+ "knowledge-base",
+ "self-hosted"
+ ]
+ },
+ {
+ "id": "supabase",
+ "name": "SupaBase",
+ "version": "1.24.07",
+ "description": "The open source Firebase alternative. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications. ",
+ "links": {
+ "github": "https://github.com/supabase/supabase",
+ "website": "https://supabase.com/",
+ "docs": "https://supabase.com/docs/guides/self-hosting"
+ },
+ "logo": "supabase.svg",
+ "tags": [
+ "database",
+ "firebase",
+ "postgres"
+ ]
+ },
+ {
+ "id": "pocketbase",
+ "name": "PocketBase",
+ "description": "Open Source backend in 1 file",
+ "version": "v0.22.4",
+ "logo": "logo.svg",
+ "links": {
+ "github": "https://github.com/pocketbase/pocketbase",
+ "website": "https://pocketbase.io/",
+ "docs": "https://pocketbase.io/docs/"
+ },
+ "tags": [
+ "backend",
+ "database",
+ "api"
+ ]
+ },
+ {
+ "id": "plausible",
+ "name": "Plausible",
+ "version": "v2.1.5",
+ "description": "Plausible is a open source, self-hosted web analytics platform that lets you track website traffic and user behavior.",
+ "logo": "logo.svg",
+ "links": {
+ "github": "https://github.com/plausible/plausible",
+ "website": "https://plausible.io/",
+ "docs": "https://plausible.io/docs"
+ },
+ "tags": [
+ "analytics"
+ ]
+ },
+ {
+ "id": "calcom",
+ "name": "Calcom",
+ "version": "v2.7.6",
+ "description": "Calcom is a open source alternative to Calendly that allows to create scheduling and booking services.",
+ "links": {
+ "github": "https://github.com/calcom/cal.com",
+ "website": "https://cal.com/",
+ "docs": "https://cal.com/docs"
+ },
+ "logo": "calcom.jpg",
+ "tags": [
+ "scheduling",
+ "booking"
+ ]
+ },
+ {
+ "id": "grafana",
+ "name": "Grafana",
+ "version": "9.5.20",
+ "description": "Grafana is an open source platform for data visualization and monitoring.",
+ "logo": "grafana.svg",
+ "links": {
+ "github": "https://github.com/grafana/grafana",
+ "website": "https://grafana.com/",
+ "docs": "https://grafana.com/docs/"
+ },
+ "tags": [
+ "monitoring"
+ ]
+ },
+ {
+ "id": "datalens",
+ "name": "DataLens",
+ "version": "1.23.0",
+ "description": "A modern, scalable business intelligence and data visualization system.",
+ "logo": "datalens.svg",
+ "links": {
+ "github": "https://github.com/datalens-tech/datalens",
+ "website": "https://datalens.tech/",
+ "docs": "https://datalens.tech/docs/"
+ },
+ "tags": [
+ "analytics",
+ "self-hosted",
+ "bi",
+ "monitoring"
+ ]
+ },
+ {
+ "id": "directus",
+ "name": "Directus",
+ "version": "11.0.2",
+ "description": "Directus is an open source headless CMS that provides an API-first solution for building custom backends.",
+ "logo": "directus.jpg",
+ "links": {
+ "github": "https://github.com/directus/directus",
+ "website": "https://directus.io/",
+ "docs": "https://docs.directus.io/"
+ },
+ "tags": [
+ "cms"
+ ]
+ },
+ {
+ "id": "baserow",
+ "name": "Baserow",
+ "version": "1.25.2",
+ "description": "Baserow is an open source database management tool that allows you to create and manage databases.",
+ "logo": "baserow.webp",
+ "links": {
+ "github": "https://github.com/Baserow/baserow",
+ "website": "https://baserow.io/",
+ "docs": "https://baserow.io/docs/index"
+ },
+ "tags": [
+ "database"
+ ]
+ },
+ {
+ "id": "budibase",
+ "name": "Budibase",
+ "version": "3.2.25",
+ "description": "Budibase is an open-source low-code platform that saves engineers 100s of hours building forms, portals, and approval apps, securely.",
+ "logo": "budibase.svg",
+ "links": {
+ "github": "https://github.com/Budibase/budibase",
+ "website": "https://budibase.com/",
+ "docs": "https://docs.budibase.com/docs/"
+ },
+ "tags": [
+ "database",
+ "low-code",
+ "nocode",
+ "applications"
+ ]
+ },
+ {
+ "id": "ghost",
+ "name": "Ghost",
+ "version": "5.0.0",
+ "description": "Ghost is a free and open source, professional publishing platform built on a modern Node.js technology stack.",
+ "logo": "ghost.jpeg",
+ "links": {
+ "github": "https://github.com/TryGhost/Ghost",
+ "website": "https://ghost.org/",
+ "docs": "https://ghost.org/docs/"
+ },
+ "tags": [
+ "cms"
+ ]
+ },
+ {
+ "id": "uptime-kuma",
+ "name": "Uptime Kuma",
+ "version": "1.23.15",
+ "description": "Uptime Kuma is a free and open source monitoring tool that allows you to monitor your websites and applications.",
+ "logo": "uptime-kuma.png",
+ "links": {
+ "github": "https://github.com/louislam/uptime-kuma",
+ "website": "https://uptime.kuma.pet/",
+ "docs": "https://github.com/louislam/uptime-kuma/wiki"
+ },
+ "tags": [
+ "monitoring"
+ ]
+ },
+ {
+ "id": "n8n",
+ "name": "n8n",
+ "version": "1.70.3",
+ "description": "n8n is an open source low-code platform for automating workflows and integrations.",
+ "logo": "n8n.png",
+ "links": {
+ "github": "https://github.com/n8n-io/n8n",
+ "website": "https://n8n.io/",
+ "docs": "https://docs.n8n.io/"
+ },
+ "tags": [
+ "automation"
+ ]
+ },
+ {
+ "id": "wordpress",
+ "name": "Wordpress",
+ "version": "6.7.1",
+ "description": "Wordpress is a free and open source content management system (CMS) for publishing and managing websites.",
+ "logo": "wordpress.png",
+ "links": {
+ "github": "https://github.com/WordPress/WordPress",
+ "website": "https://wordpress.org/",
+ "docs": "https://wordpress.org/documentation/"
+ },
+ "tags": [
+ "cms"
+ ]
+ },
+ {
+ "id": "odoo",
+ "name": "Odoo",
+ "version": "16.0",
+ "description": "Odoo is a free and open source business management software that helps you manage your company's operations.",
+ "logo": "odoo.png",
+ "links": {
+ "github": "https://github.com/odoo/odoo",
+ "website": "https://odoo.com/",
+ "docs": "https://www.odoo.com/documentation/"
+ },
+ "tags": [
+ "cms"
+ ]
+ },
+ {
+ "id": "appsmith",
+ "name": "Appsmith",
+ "version": "v1.29",
+ "description": "Appsmith is a free and open source platform for building internal tools and applications.",
+ "logo": "appsmith.png",
+ "links": {
+ "github": "https://github.com/appsmithorg/appsmith",
+ "website": "https://appsmith.com/",
+ "docs": "https://docs.appsmith.com/"
+ },
+ "tags": [
+ "cms"
+ ]
+ },
+ {
+ "id": "excalidraw",
+ "name": "Excalidraw",
+ "version": "latest",
+ "description": "Excalidraw is a free and open source online diagramming tool that lets you easily create and share beautiful diagrams.",
+ "logo": "excalidraw.jpg",
+ "links": {
+ "github": "https://github.com/excalidraw/excalidraw",
+ "website": "https://excalidraw.com/",
+ "docs": "https://docs.excalidraw.com/"
+ },
+ "tags": [
+ "drawing"
+ ]
+ },
+ {
+ "id": "documenso",
+ "name": "Documenso",
+ "version": "v1.5.6",
+ "description": "Documenso is the open source alternative to DocuSign for signing documents digitally",
+ "links": {
+ "github": "https://github.com/documenso/documenso",
+ "website": "https://documenso.com/",
+ "docs": "https://documenso.com/docs"
+ },
+ "logo": "documenso.png",
+ "tags": [
+ "document-signing"
+ ]
+ },
+ {
+ "id": "nocodb",
+ "name": "NocoDB",
+ "version": "0.257.2",
+ "description": "NocoDB is an opensource Airtable alternative that turns any MySQL, PostgreSQL, SQL Server, SQLite & MariaDB into a smart spreadsheet.",
+ "links": {
+ "github": "https://github.com/nocodb/nocodb",
+ "website": "https://nocodb.com/",
+ "docs": "https://docs.nocodb.com/"
+ },
+ "logo": "nocodb.png",
+ "tags": [
+ "database",
+ "spreadsheet",
+ "low-code",
+ "nocode"
+ ]
+ },
+ {
+ "id": "meilisearch",
+ "name": "Meilisearch",
+ "version": "v1.8.3",
+ "description": "Meilisearch is a free and open-source search engine that allows you to easily add search functionality to your web applications.",
+ "logo": "meilisearch.png",
+ "links": {
+ "github": "https://github.com/meilisearch/meilisearch",
+ "website": "https://www.meilisearch.com/",
+ "docs": "https://docs.meilisearch.com/"
+ },
+ "tags": [
+ "search"
+ ]
+ },
+ {
+ "id": "phpmyadmin",
+ "name": "Phpmyadmin",
+ "version": "5.2.1",
+ "description": "Phpmyadmin is a free and open-source web interface for MySQL and MariaDB that allows you to manage your databases.",
+ "logo": "phpmyadmin.png",
+ "links": {
+ "github": "https://github.com/phpmyadmin/phpmyadmin",
+ "website": "https://www.phpmyadmin.net/",
+ "docs": "https://www.phpmyadmin.net/docs/"
+ },
+ "tags": [
+ "database"
+ ]
+ },
+ {
+ "id": "rocketchat",
+ "name": "Rocketchat",
+ "version": "6.9.2",
+ "description": "Rocket.Chat is a free and open-source web chat platform that allows you to build and manage your own chat applications.",
+ "logo": "rocketchat.png",
+ "links": {
+ "github": "https://github.com/RocketChat/Rocket.Chat",
+ "website": "https://rocket.chat/",
+ "docs": "https://rocket.chat/docs/"
+ },
+ "tags": [
+ "chat"
+ ]
+ },
+ {
+ "id": "minio",
+ "name": "Minio",
+ "description": "Minio is an open source object storage server compatible with Amazon S3 cloud storage service.",
+ "logo": "minio.png",
+ "version": "latest",
+ "links": {
+ "github": "https://github.com/minio/minio",
+ "website": "https://minio.io/",
+ "docs": "https://docs.minio.io/"
+ },
+ "tags": [
+ "storage"
+ ]
+ },
+ {
+ "id": "metabase",
+ "name": "Metabase",
+ "version": "v0.50.8",
+ "description": "Metabase is an open source business intelligence tool that allows you to ask questions and visualize data.",
+ "logo": "metabase.png",
+ "links": {
+ "github": "https://github.com/metabase/metabase",
+ "website": "https://www.metabase.com/",
+ "docs": "https://www.metabase.com/docs/"
+ },
+ "tags": [
+ "database",
+ "dashboard"
+ ]
+ },
+ {
+ "id": "glitchtip",
+ "name": "Glitchtip",
+ "version": "v4.0",
+ "description": "Glitchtip is simple, open source error tracking",
+ "logo": "glitchtip.png",
+ "links": {
+ "github": "https://gitlab.com/glitchtip/",
+ "website": "https://glitchtip.com/",
+ "docs": "https://glitchtip.com/documentation"
+ },
+ "tags": [
+ "hosting"
+ ]
+ },
+ {
+ "id": "open-webui",
+ "name": "Open WebUI",
+ "version": "v0.3.7",
+ "description": "Open WebUI is a free and open source chatgpt alternative. Open WebUI is an extensible, feature-rich, and user-friendly self-hosted WebUI designed to operate entirely offline. It supports various LLM runners, including Ollama and OpenAI-compatible APIs. The template include ollama and webui services.",
+ "logo": "open-webui.png",
+ "links": {
+ "github": "https://github.com/open-webui/open-webui",
+ "website": "https://openwebui.com/",
+ "docs": "https://docs.openwebui.com/"
+ },
+ "tags": [
+ "chat"
+ ]
+ },
+ {
+ "id": "mailpit",
+ "name": "Mailpit",
+ "version": "v1.22.3",
+ "description": "Mailpit is a tiny, self-contained, and secure email & SMTP testing tool with API for developers.",
+ "logo": "mailpit.svg",
+ "links": {
+ "github": "https://github.com/axllent/mailpit",
+ "website": "https://mailpit.axllent.org/",
+ "docs": "https://mailpit.axllent.org/docs/"
+ },
+ "tags": [
+ "email",
+ "smtp"
+ ]
+ },
+ {
+ "id": "listmonk",
+ "name": "Listmonk",
+ "version": "v3.0.0",
+ "description": "High performance, self-hosted, newsletter and mailing list manager with a modern dashboard.",
+ "logo": "listmonk.png",
+ "links": {
+ "github": "https://github.com/knadh/listmonk",
+ "website": "https://listmonk.app/",
+ "docs": "https://listmonk.app/docs/"
+ },
+ "tags": [
+ "email",
+ "newsletter",
+ "mailing-list"
+ ]
+ },
+ {
+ "id": "doublezero",
+ "name": "Double Zero",
+ "version": "v0.2.1",
+ "description": "00 is a self hostable SES dashboard for sending and monitoring emails with AWS",
+ "logo": "doublezero.svg",
+ "links": {
+ "github": "https://github.com/technomancy-dev/00",
+ "website": "https://www.double-zero.cloud/",
+ "docs": "https://github.com/technomancy-dev/00"
+ },
+ "tags": [
+ "email"
+ ]
+ },
+ {
+ "id": "umami",
+ "name": "Umami",
+ "version": "v2.16.1",
+ "description": "Umami is a simple, fast, privacy-focused alternative to Google Analytics.",
+ "logo": "umami.png",
+ "links": {
+ "github": "https://github.com/umami-software/umami",
+ "website": "https://umami.is",
+ "docs": "https://umami.is/docs"
+ },
+ "tags": [
+ "analytics"
+ ]
+ },
+ {
+ "id": "jellyfin",
+ "name": "jellyfin",
+ "version": "v10.9.7",
+ "description": "Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media. ",
+ "logo": "jellyfin.svg",
+ "links": {
+ "github": "https://github.com/jellyfin/jellyfin",
+ "website": "https://jellyfin.org/",
+ "docs": "https://jellyfin.org/docs/"
+ },
+ "tags": [
+ "media system"
+ ]
+ },
+ {
+ "id": "teable",
+ "name": "teable",
+ "version": "v1.3.1-alpha-build.460",
+ "description": "Teable is a Super fast, Real-time, Professional, Developer friendly, No-code database built on Postgres. It uses a simple, spreadsheet-like interface to create complex enterprise-level database applications. Unlock efficient app development with no-code, free from the hurdles of data security and scalability.",
+ "logo": "teable.png",
+ "links": {
+ "github": "https://github.com/teableio/teable",
+ "website": "https://teable.io/",
+ "docs": "https://help.teable.io/"
+ },
+ "tags": [
+ "database",
+ "spreadsheet",
+ "low-code",
+ "nocode"
+ ]
+ },
+ {
+ "id": "zipline",
+ "name": "Zipline",
+ "version": "v3.7.9",
+ "description": "A ShareX/file upload server that is easy to use, packed with features, and with an easy setup!",
+ "logo": "zipline.png",
+ "links": {
+ "github": "https://github.com/diced/zipline",
+ "website": "https://zipline.diced.sh/",
+ "docs": "https://zipline.diced.sh/docs/"
+ },
+ "tags": [
+ "media system",
+ "storage"
+ ]
+ },
+ {
+ "id": "soketi",
+ "name": "Soketi",
+ "version": "v1.6.1-16",
+ "description": "Soketi is your simple, fast, and resilient open-source WebSockets server.",
+ "logo": "soketi.png",
+ "links": {
+ "github": "https://github.com/soketi/soketi",
+ "website": "https://soketi.app/",
+ "docs": "https://docs.soketi.app/"
+ },
+ "tags": [
+ "chat"
+ ]
+ },
+ {
+ "id": "aptabase",
+ "name": "Aptabase",
+ "version": "v1.0.0",
+ "description": "Aptabase is a self-hosted web analytics platform that lets you track website traffic and user behavior.",
+ "logo": "aptabase.svg",
+ "links": {
+ "github": "https://github.com/aptabase/aptabase",
+ "website": "https://aptabase.com/",
+ "docs": "https://github.com/aptabase/aptabase/blob/main/README.md"
+ },
+ "tags": [
+ "analytics",
+ "self-hosted"
+ ]
+ },
+ {
+ "id": "typebot",
+ "name": "Typebot",
+ "version": "2.27.0",
+ "description": "Typebot is an open-source chatbot builder platform.",
+ "logo": "typebot.svg",
+ "links": {
+ "github": "https://github.com/baptisteArno/typebot.io",
+ "website": "https://typebot.io/",
+ "docs": "https://docs.typebot.io/get-started/introduction"
+ },
+ "tags": [
+ "chatbot",
+ "builder",
+ "open-source"
+ ]
+ },
+ {
+ "id": "gitea",
+ "name": "Gitea",
+ "version": "1.22.3",
+ "description": "Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD.",
+ "logo": "gitea.png",
+ "links": {
+ "github": "https://github.com/go-gitea/gitea.git",
+ "website": "https://gitea.com/",
+ "docs": "https://docs.gitea.com/installation/install-with-docker"
+ },
+ "tags": [
+ "self-hosted",
+ "storage"
+ ]
+ },
+ {
+ "id": "roundcube",
+ "name": "Roundcube",
+ "version": "1.6.9",
+ "description": "Free and open source webmail software for the masses, written in PHP.",
+ "logo": "roundcube.svg",
+ "links": {
+ "github": "https://github.com/roundcube/roundcubemail",
+ "website": "https://roundcube.net/",
+ "docs": "https://roundcube.net/about/"
+ },
+ "tags": [
+ "self-hosted",
+ "email",
+ "webmail"
+ ]
+ },
+ {
+ "id": "filebrowser",
+ "name": "File Browser",
+ "version": "2.31.2",
+ "description": "Filebrowser is a standalone file manager for uploading, deleting, previewing, renaming, and editing files, with support for multiple users, each with their own directory.",
+ "logo": "filebrowser.svg",
+ "links": {
+ "github": "https://github.com/filebrowser/filebrowser",
+ "website": "https://filebrowser.org/",
+ "docs": "https://filebrowser.org/"
+ },
+ "tags": [
+ "file-manager",
+ "storage"
+ ]
+ },
+ {
+ "id": "tolgee",
+ "name": "Tolgee",
+ "version": "v3.80.4",
+ "description": "Developer & translator friendly web-based localization platform",
+ "logo": "tolgee.svg",
+ "links": {
+ "github": "https://github.com/tolgee/tolgee-platform",
+ "website": "https://tolgee.io",
+ "docs": "https://tolgee.io/platform"
+ },
+ "tags": [
+ "self-hosted",
+ "i18n",
+ "localization",
+ "translations"
+ ]
+ },
+ {
+ "id": "portainer",
+ "name": "Portainer",
+ "version": "2.21.4",
+ "description": "Portainer is a container management tool for deploying, troubleshooting, and securing applications across cloud, data centers, and IoT.",
+ "logo": "portainer.svg",
+ "links": {
+ "github": "https://github.com/portainer/portainer",
+ "website": "https://www.portainer.io/",
+ "docs": "https://docs.portainer.io/"
+ },
+ "tags": [
+ "cloud",
+ "monitoring"
+ ]
+ },
+ {
+ "id": "influxdb",
+ "name": "InfluxDB",
+ "version": "2.7.10",
+ "description": "InfluxDB 2.7 is the platform purpose-built to collect, store, process and visualize time series data.",
+ "logo": "influxdb.png",
+ "links": {
+ "github": "https://github.com/influxdata/influxdb",
+ "website": "https://www.influxdata.com/",
+ "docs": "https://docs.influxdata.com/influxdb/v2/"
+ },
+ "tags": [
+ "self-hosted",
+ "open-source",
+ "storage",
+ "database"
+ ]
+ },
+ {
+ "id": "infisical",
+ "name": "Infisical",
+ "version": "0.90.1",
+ "description": "All-in-one platform to securely manage application configuration and secrets across your team and infrastructure.",
+ "logo": "infisical.jpg",
+ "links": {
+ "github": "https://github.com/Infisical/infisical",
+ "website": "https://infisical.com/",
+ "docs": "https://infisical.com/docs/documentation/getting-started/introduction"
+ },
+ "tags": [
+ "self-hosted",
+ "open-source"
+ ]
+ },
+ {
+ "id": "docmost",
+ "name": "Docmost",
+ "version": "0.4.1",
+ "description": "Docmost, is an open-source collaborative wiki and documentation software.",
+ "logo": "docmost.png",
+ "links": {
+ "github": "https://github.com/docmost/docmost",
+ "website": "https://docmost.com/",
+ "docs": "https://docmost.com/docs/"
+ },
+ "tags": [
+ "self-hosted",
+ "open-source",
+ "manager"
+ ]
+ },
+ {
+ "id": "vaultwarden",
+ "name": "Vaultwarden",
+ "version": "1.32.7",
+ "description": "Unofficial Bitwarden compatible server written in Rust, formerly known as bitwarden_rs",
+ "logo": "vaultwarden.svg",
+ "links": {
+ "github": "https://github.com/dani-garcia/vaultwarden",
+ "website": "",
+ "docs": "https://github.com/dani-garcia/vaultwarden/wiki"
+ },
+ "tags": [
+ "open-source"
+ ]
+ },
+ {
+ "id": "linkwarden",
+ "name": "Linkwarden",
+ "version": "2.9.3",
+ "description": "Self-hosted, open-source collaborative bookmark manager to collect, organize and archive webpages.",
+ "logo": "linkwarden.png",
+ "links": {
+ "github": "https://github.com/linkwarden/linkwarden",
+ "website": "https://linkwarden.app/",
+ "docs": "https://docs.linkwarden.app/"
+ },
+ "tags": [
+ "bookmarks",
+ "link-sharing"
+ ]
+ },
+ {
+ "id": "hi-events",
+ "name": "Hi.events",
+ "version": "0.8.0-beta.1",
+ "description": "Hi.Events is a self-hosted event management and ticket selling platform that allows you to create, manage and promote events easily.",
+ "logo": "hi-events.svg",
+ "links": {
+ "github": "https://github.com/HiEventsDev/hi.events",
+ "website": "https://hi.events/",
+ "docs": "https://hi.events/docs"
+ },
+ "tags": [
+ "self-hosted",
+ "open-source",
+ "manager"
+ ]
+ },
+ {
+ "id": "hoarder",
+ "name": "Hoarder",
+ "version": "0.22.0",
+ "description": "Hoarder is an open source \"Bookmark Everything\" app that uses AI for automatically tagging the content you throw at it.",
+ "logo": "hoarder.svg",
+ "links": {
+ "github": "https://github.com/hoarder/hoarder",
+ "website": "https://hoarder.app/",
+ "docs": "https://docs.hoarder.app/"
+ },
+ "tags": [
+ "self-hosted",
+ "bookmarks",
+ "link-sharing"
+ ]
+ },
+ {
+ "id": "windows",
+ "name": "Windows (dockerized)",
+ "version": "4.00",
+ "description": "Windows inside a Docker container.",
+ "logo": "windows.png",
+ "links": {
+ "github": "https://github.com/dockur/windows",
+ "website": "",
+ "docs": "https://github.com/dockur/windows?tab=readme-ov-file#how-do-i-use-it"
+ },
+ "tags": [
+ "self-hosted",
+ "open-source",
+ "os"
+ ]
+ },
+ {
+ "id": "macos",
+ "name": "MacOS (dockerized)",
+ "version": "1.14",
+ "description": "MacOS inside a Docker container.",
+ "logo": "macos.png",
+ "links": {
+ "github": "https://github.com/dockur/macos",
+ "website": "",
+ "docs": "https://github.com/dockur/macos?tab=readme-ov-file#how-do-i-use-it"
+ },
+ "tags": [
+ "self-hosted",
+ "open-source",
+ "os"
+ ]
+ },
+ {
+ "id": "coder",
+ "name": "Coder",
+ "version": "2.15.3",
+ "description": "Coder is an open-source cloud development environment (CDE) that you host in your cloud or on-premises.",
+ "logo": "coder.svg",
+ "links": {
+ "github": "https://github.com/coder/coder",
+ "website": "https://coder.com/",
+ "docs": "https://coder.com/docs"
+ },
+ "tags": [
+ "self-hosted",
+ "open-source",
+ "builder"
+ ]
+ },
+ {
+ "id": "stirling",
+ "name": "Stirling PDF",
+ "version": "0.30.1",
+ "description": "A locally hosted one-stop shop for all your PDF needs",
+ "logo": "stirling.svg",
+ "links": {
+ "github": "https://github.com/Stirling-Tools/Stirling-PDF",
+ "website": "https://www.stirlingpdf.com/",
+ "docs": "https://docs.stirlingpdf.com/"
+ },
+ "tags": [
+ "pdf",
+ "tools"
+ ]
+ },
+ {
+ "id": "lobe-chat",
+ "name": "Lobe Chat",
+ "version": "v1.26.1",
+ "description": "Lobe Chat - an open-source, modern-design AI chat framework.",
+ "logo": "lobe-chat.png",
+ "links": {
+ "github": "https://github.com/lobehub/lobe-chat",
+ "website": "https://chat-preview.lobehub.com/",
+ "docs": "https://lobehub.com/docs/self-hosting/platform/docker-compose"
+ },
+ "tags": [
+ "IA",
+ "chat"
+ ]
+ },
+ {
+ "id": "peppermint",
+ "name": "Peppermint",
+ "version": "latest",
+ "description": "Peppermint is a modern, open-source API development platform that helps you build, test and document your APIs.",
+ "logo": "peppermint.svg",
+ "links": {
+ "github": "https://github.com/Peppermint-Lab/peppermint",
+ "website": "https://peppermint.sh/",
+ "docs": "https://docs.peppermint.sh/"
+ },
+ "tags": [
+ "api",
+ "development",
+ "documentation"
+ ]
+ },
+ {
+ "id": "windmill",
+ "name": "Windmill",
+ "version": "latest",
+ "description": "A developer platform to build production-grade workflows and internal apps. Open-source alternative to Airplane, Retool, and GitHub Actions.",
+ "logo": "windmill.svg",
+ "links": {
+ "github": "https://github.com/windmill-labs/windmill",
+ "website": "https://www.windmill.dev/",
+ "docs": "https://docs.windmill.dev/"
+ },
+ "tags": [
+ "workflow",
+ "automation",
+ "development"
+ ]
+ },
+ {
+ "id": "activepieces",
+ "name": "Activepieces",
+ "version": "0.35.0",
+ "description": "Open-source no-code business automation tool. An alternative to Zapier, Make.com, and Tray.",
+ "logo": "activepieces.svg",
+ "links": {
+ "github": "https://github.com/activepieces/activepieces",
+ "website": "https://www.activepieces.com/",
+ "docs": "https://www.activepieces.com/docs"
+ },
+ "tags": [
+ "automation",
+ "workflow",
+ "no-code"
+ ]
+ },
+ {
+ "id": "invoiceshelf",
+ "name": "InvoiceShelf",
+ "version": "latest",
+ "description": "InvoiceShelf is a self-hosted open source invoicing system for freelancers and small businesses.",
+ "logo": "invoiceshelf.png",
+ "links": {
+ "github": "https://github.com/InvoiceShelf/invoiceshelf",
+ "website": "https://invoiceshelf.com",
+ "docs": "https://github.com/InvoiceShelf/invoiceshelf#readme"
+ },
+ "tags": [
+ "invoice",
+ "business",
+ "finance"
+ ]
+ },
+ {
+ "id": "postiz",
+ "name": "Postiz",
+ "version": "latest",
+ "description": "Postiz is a modern, open-source platform for managing and publishing content across multiple channels.",
+ "logo": "postiz.png",
+ "links": {
+ "github": "https://github.com/gitroomhq/postiz",
+ "website": "https://postiz.com",
+ "docs": "https://docs.postiz.com"
+ },
+ "tags": [
+ "cms",
+ "content-management",
+ "publishing"
+ ]
+ },
+ {
+ "id": "slash",
+ "name": "Slash",
+ "version": "latest",
+ "description": "Slash is a modern, self-hosted bookmarking service and link shortener that helps you organize and share your favorite links.",
+ "logo": "slash.png",
+ "links": {
+ "github": "https://github.com/yourselfhosted/slash",
+ "website": "https://github.com/yourselfhosted/slash#readme",
+ "docs": "https://github.com/yourselfhosted/slash/wiki"
+ },
+ "tags": [
+ "bookmarks",
+ "link-shortener",
+ "self-hosted"
+ ]
+ },
+ {
+ "id": "discord-tickets",
+ "name": "Discord Tickets",
+ "version": "4.0.21",
+ "description": "An open-source Discord bot for creating and managing support ticket channels.",
+ "logo": "discord-tickets.png",
+ "links": {
+ "github": "https://github.com/discord-tickets/bot",
+ "website": "https://discordtickets.app",
+ "docs": "https://discordtickets.app/self-hosting/installation/docker/"
+ },
+ "tags": [
+ "discord",
+ "tickets",
+ "support"
+ ]
+ },
+ {
+ "id": "nextcloud-aio",
+ "name": "Nextcloud All in One",
+ "version": "30.0.2",
+ "description": "Nextcloud (AIO) is a self-hosted file storage and sync platform with powerful collaboration capabilities. It integrates Files, Talk, Groupware, Office, Assistant and more into a single platform for remote work and data protection.",
+ "logo": "nextcloud-aio.svg",
+ "links": {
+ "github": "https://github.com/nextcloud/docker",
+ "website": "https://nextcloud.com/",
+ "docs": "https://docs.nextcloud.com/"
+ },
+ "tags": [
+ "file-manager",
+ "sync"
+ ]
+ },
+ {
+ "id": "blender",
+ "name": "Blender",
+ "version": "latest",
+ "description": "Blender is a free and open-source 3D creation suite. It supports the entire 3D pipeline—modeling, rigging, animation, simulation, rendering, compositing and motion tracking, video editing and 2D animation pipeline.",
+ "logo": "blender.svg",
+ "links": {
+ "github": "https://github.com/linuxserver/docker-blender",
+ "website": "https://www.blender.org/",
+ "docs": "https://docs.blender.org/"
+ },
+ "tags": [
+ "3d",
+ "rendering",
+ "animation"
+ ]
+ },
+ {
+ "id": "heyform",
+ "name": "HeyForm",
+ "version": "latest",
+ "description": "Allows anyone to create engaging conversational forms for surveys, questionnaires, quizzes, and polls. No coding skills required.",
+ "logo": "heyform.svg",
+ "links": {
+ "github": "https://github.com/heyform/heyform",
+ "website": "https://heyform.net",
+ "docs": "https://docs.heyform.net"
+ },
+ "tags": [
+ "form",
+ "builder",
+ "questionnaire",
+ "quiz",
+ "survey"
+ ]
+ },
+ {
+ "id": "chatwoot",
+ "name": "Chatwoot",
+ "version": "v3.14.1",
+ "description": "Open-source customer engagement platform that provides a shared inbox for teams, live chat, and omnichannel support.",
+ "logo": "chatwoot.svg",
+ "links": {
+ "github": "https://github.com/chatwoot/chatwoot",
+ "website": "https://www.chatwoot.com",
+ "docs": "https://www.chatwoot.com/docs"
+ },
+ "tags": [
+ "support",
+ "chat",
+ "customer-service"
+ ]
+ },
+ {
+ "id": "discourse",
+ "name": "Discourse",
+ "version": "3.3.2",
+ "description": "Discourse is a modern forum software for your community. Use it as a mailing list, discussion forum, or long-form chat room.",
+ "logo": "discourse.svg",
+ "links": {
+ "github": "https://github.com/discourse/discourse",
+ "website": "https://www.discourse.org/",
+ "docs": "https://meta.discourse.org/"
+ },
+ "tags": [
+ "forum",
+ "community",
+ "discussion"
+ ]
+ },
+ {
+ "id": "immich",
+ "name": "Immich",
+ "version": "v1.121.0",
+ "description": "High performance self-hosted photo and video backup solution directly from your mobile phone.",
+ "logo": "immich.svg",
+ "links": {
+ "github": "https://github.com/immich-app/immich",
+ "website": "https://immich.app/",
+ "docs": "https://immich.app/docs/overview/introduction"
+ },
+ "tags": [
+ "photos",
+ "videos",
+ "backup",
+ "media"
+ ]
+ },
+ {
+ "id": "twenty",
+ "name": "Twenty CRM",
+ "version": "latest",
+ "description": "Twenty is a modern CRM offering a powerful spreadsheet interface and open-source alternative to Salesforce.",
+ "logo": "twenty.svg",
+ "links": {
+ "github": "https://github.com/twentyhq/twenty",
+ "website": "https://twenty.com",
+ "docs": "https://docs.twenty.com"
+ },
+ "tags": [
+ "crm",
+ "sales",
+ "business"
+ ]
+ },
+ {
+ "id": "yourls",
+ "name": "YOURLS",
+ "version": "1.9.2",
+ "description": "YOURLS (Your Own URL Shortener) is a set of PHP scripts that will allow you to run your own URL shortening service (a la TinyURL or Bitly).",
+ "logo": "yourls.svg",
+ "links": {
+ "github": "https://github.com/YOURLS/YOURLS",
+ "website": "https://yourls.org/",
+ "docs": "https://yourls.org/#documentation"
+ },
+ "tags": [
+ "url-shortener",
+ "php"
+ ]
+ },
+ {
+ "id": "ryot",
+ "name": "Ryot",
+ "version": "v7.10",
+ "description": "A self-hosted platform for tracking various media types including movies, TV shows, video games, books, audiobooks, and more.",
+ "logo": "ryot.png",
+ "links": {
+ "github": "https://github.com/IgnisDa/ryot",
+ "website": "https://ryot.io/",
+ "docs": "https://docs.ryot.io/"
+ },
+ "tags": [
+ "media",
+ "tracking",
+ "self-hosted"
+ ]
+ },
+ {
+ "id": "photoprism",
+ "name": "Photoprism",
+ "version": "latest",
+ "description": "PhotoPrism® is an AI-Powered Photos App for the Decentralized Web. It makes use of the latest technologies to tag and find pictures automatically without getting in your way.",
+ "logo": "photoprism.svg",
+ "links": {
+ "github": "https://github.com/photoprism/photoprism",
+ "website": "https://www.photoprism.app/",
+ "docs": "https://docs.photoprism.app/"
+ },
+ "tags": [
+ "media",
+ "photos",
+ "self-hosted"
+ ]
+ },
+ {
+ "id": "ontime",
+ "name": "Ontime",
+ "version": "v3.8.0",
+ "description": "Ontime is browser-based application that manages event rundowns, scheduliing and cuing",
+ "logo": "ontime.png",
+ "links": {
+ "github": "https://github.com/cpvalente/ontime/",
+ "website": "https://getontime.no",
+ "docs": "https://docs.getontime.no"
+ },
+ "tags": [
+ "event"
+ ]
+ },
+ {
+ "id": "triggerdotdev",
+ "name": "Trigger.dev",
+ "version": "v3",
+ "description": "Trigger is a platform for building event-driven applications.",
+ "logo": "triggerdotdev.svg",
+ "links": {
+ "github": "https://github.com/triggerdotdev/trigger.dev",
+ "website": "https://trigger.dev/",
+ "docs": "https://trigger.dev/docs"
+ },
+ "tags": [
+ "event-driven",
+ "applications"
+ ]
+ },
+ {
+ "id": "browserless",
+ "name": "Browserless",
+ "version": "2.23.0",
+ "description": "Browserless allows remote clients to connect and execute headless work, all inside of docker. It supports the standard, unforked Puppeteer and Playwright libraries, as well offering REST-based APIs for common actions like data collection, PDF generation and more.",
+ "logo": "browserless.svg",
+ "links": {
+ "github": "https://github.com/browserless/browserless",
+ "website": "https://www.browserless.io/",
+ "docs": "https://docs.browserless.io/"
+ },
+ "tags": [
+ "browser",
+ "automation"
+ ]
+ },
+ {
+ "id": "drawio",
+ "name": "draw.io",
+ "version": "24.7.17",
+ "description": "draw.io is a configurable diagramming/whiteboarding visualization application.",
+ "logo": "drawio.svg",
+ "links": {
+ "github": "https://github.com/jgraph/drawio",
+ "website": "https://draw.io/",
+ "docs": "https://www.drawio.com/doc/"
+ },
+ "tags": [
+ "drawing",
+ "diagrams"
+ ]
+ },
+ {
+ "id": "kimai",
+ "name": "Kimai",
+ "version": "2.26.0",
+ "description": "Kimai is a web-based multi-user time-tracking application. Works great for everyone: freelancers, companies, organizations - everyone can track their times, generate reports, create invoices and do so much more.",
+ "logo": "kimai.svg",
+ "links": {
+ "github": "https://github.com/kimai/kimai",
+ "website": "https://www.kimai.org",
+ "docs": "https://www.kimai.org/documentation"
+ },
+ "tags": [
+ "invoice",
+ "business",
+ "finance"
+ ]
+ },
+ {
+ "id": "logto",
+ "name": "Logto",
+ "version": "1.22.0",
+ "description": "Logto is an open-source Identity and Access Management (IAM) platform designed to streamline Customer Identity and Access Management (CIAM) and Workforce Identity Management.",
+ "logo": "logto.png",
+ "links": {
+ "github": "https://github.com/logto-io/logto",
+ "website": "https://logto.io/",
+ "docs": "https://docs.logto.io/introduction"
+ },
+ "tags": [
+ "identity",
+ "auth"
+ ]
+ },
+ {
+ "id": "pocket-id",
+ "name": "Pocket ID",
+ "version": "0.35.1",
+ "description": "A simple and easy-to-use OIDC provider that allows users to authenticate with their passkeys to your services.",
+ "logo": "pocket-id.svg",
+ "links": {
+ "github": "https://github.com/pocket-id/pocket-id",
+ "website": "https://pocket-id.org/",
+ "docs": "https://pocket-id.org/docs"
+ },
+ "tags": [
+ "identity",
+ "auth"
+ ]
+ },
+ {
+ "id": "penpot",
+ "name": "Penpot",
+ "version": "2.3.2",
+ "description": "Penpot is the web-based open-source design tool that bridges the gap between designers and developers.",
+ "logo": "penpot.svg",
+ "links": {
+ "github": "https://github.com/penpot/penpot",
+ "website": "https://penpot.app/",
+ "docs": "https://docs.penpot.app/"
+ },
+ "tags": [
+ "design",
+ "collaboration"
+ ]
+ },
+ {
+ "id": "huly",
+ "name": "Huly",
+ "version": "0.6.377",
+ "description": "Huly — All-in-One Project Management Platform (alternative to Linear, Jira, Slack, Notion, Motion)",
+ "logo": "huly.svg",
+ "links": {
+ "github": "https://github.com/hcengineering/huly-selfhost",
+ "website": "https://huly.io/",
+ "docs": "https://docs.huly.io/"
+ },
+ "tags": [
+ "project-management",
+ "community",
+ "discussion"
+ ]
+ },
+ {
+ "id": "unsend",
+ "name": "Unsend",
+ "version": "v1.3.2",
+ "description": "Open source alternative to Resend,Sendgrid, Postmark etc. ",
+ "logo": "unsend.png",
+ "links": {
+ "github": "https://github.com/unsend-dev/unsend",
+ "website": "https://unsend.dev/",
+ "docs": "https://docs.unsend.dev/get-started/"
+ },
+ "tags": [
+ "e-mail",
+ "marketing",
+ "business"
+ ]
+ },
+ {
+ "id": "langflow",
+ "name": "Langflow",
+ "version": "1.1.1",
+ "description": "Langflow is a low-code app builder for RAG and multi-agent AI applications. It's Python-based and agnostic to any model, API, or database. ",
+ "logo": "langflow.svg",
+ "links": {
+ "github": "https://github.com/langflow-ai/langflow/tree/main",
+ "website": "https://www.langflow.org/",
+ "docs": "https://docs.langflow.org/"
+ },
+ "tags": [
+ "ai"
+ ]
+ },
+ {
+ "id": "elastic-search",
+ "name": "Elasticsearch",
+ "version": "8.10.2",
+ "description": "Elasticsearch is an open-source search and analytics engine, used for full-text search and analytics on structured data such as text, web pages, images, and videos.",
+ "logo": "elasticsearch.svg",
+ "links": {
+ "github": "https://github.com/elastic/elasticsearch",
+ "website": "https://www.elastic.co/elasticsearch/",
+ "docs": "https://docs.elastic.co/elasticsearch/"
+ },
+ "tags": [
+ "search",
+ "analytics"
+ ]
+ },
+ {
+ "id": "onedev",
+ "name": "OneDev",
+ "version": "11.6.6",
+ "description": "Git server with CI/CD, kanban, and packages. Seamless integration. Unparalleled experience.",
+ "logo": "onedev.png",
+ "links": {
+ "github": "https://github.com/theonedev/onedev/",
+ "website": "https://onedev.io/",
+ "docs": "https://docs.onedev.io/"
+ },
+ "tags": [
+ "self-hosted",
+ "development"
+ ]
+ },
+ {
+ "id": "unifi",
+ "name": "Unifi Network",
+ "version": "11.6.6",
+ "description": "Unifi Network is an open-source enterprise network management platform for wireless networks.",
+ "logo": "unifi.webp",
+ "links": {
+ "github": "https://github.com/ubiquiti",
+ "website": "https://www.ui.com/",
+ "docs": "https://help.ui.com/hc/en-us/articles/360012282453-Self-Hosting-a-UniFi-Network-Server"
+ },
+ "tags": [
+ "self-hosted",
+ "networking"
+ ]
+ },
+ {
+ "id": "glpi",
+ "name": "GLPI Project",
+ "version": "10.0.16",
+ "description": "The most complete open source service management software",
+ "logo": "glpi.webp",
+ "links": {
+ "github": "https://github.com/glpi-project/glpi",
+ "website": "https://glpi-project.org/",
+ "docs": "https://glpi-project.org/documentation/"
+ },
+ "tags": [
+ "self-hosted",
+ "project-management",
+ "management"
+ ]
+ },
+ {
+ "id": "checkmate",
+ "name": "Checkmate",
+ "version": "2.0.1",
+ "description": "Checkmate is an open-source, self-hosted tool designed to track and monitor server hardware, uptime, response times, and incidents in real-time with beautiful visualizations.",
+ "logo": "checkmate.png",
+ "links": {
+ "github": "https://github.com/bluewave-labs/checkmate",
+ "website": "https://bluewavelabs.ca",
+ "docs": "https://bluewavelabs.gitbook.io/checkmate"
+ },
+ "tags": [
+ "self-hosted",
+ "monitoring",
+ "uptime"
+ ]
+ },
+ {
+ "id": "gotenberg",
+ "name": "Gotenberg",
+ "version": "latest",
+ "description": "Gotenberg is a Docker-powered stateless API for PDF files.",
+ "logo": "gotenberg.png",
+ "links": {
+ "github": "https://github.com/gotenberg/gotenberg",
+ "website": "https://gotenberg.dev",
+ "docs": "https://gotenberg.dev/docs/getting-started/introduction"
+ },
+ "tags": [
+ "api",
+ "backend",
+ "pdf",
+ "tools"
+ ]
+ },
+ {
+ "id": "actualbudget",
+ "name": "Actual Budget",
+ "version": "latest",
+ "description": "A super fast and privacy-focused app for managing your finances.",
+ "logo": "actualbudget.png",
+ "links": {
+ "github": "https://github.com/actualbudget/actual",
+ "website": "https://actualbudget.org",
+ "docs": "https://actualbudget.org/docs"
+ },
+ "tags": [
+ "budgeting",
+ "finance",
+ "money"
+ ]
+ },
+ {
+ "id": "conduit",
+ "name": "Conduit",
+ "version": "v0.9.0",
+ "description": "Conduit is a simple, fast and reliable chat server powered by Matrix",
+ "logo": "conduit.svg",
+ "links": {
+ "github": "https://gitlab.com/famedly/conduit",
+ "website": "https://conduit.rs/",
+ "docs": "https://docs.conduit.rs/"
+ },
+ "tags": [
+ "matrix",
+ "communication"
+ ]
+ },
+ {
+ "id": "evolutionapi",
+ "name": "Evolution API",
+ "version": "v2.1.2",
+ "description": "Evolution API is a robust platform dedicated to empowering small businesses with limited resources, going beyond a simple messaging solution via WhatsApp.",
+ "logo": "evolutionapi.png",
+ "links": {
+ "github": "https://github.com/EvolutionAPI/evolution-api",
+ "docs": "https://doc.evolution-api.com/v2/en/get-started/introduction",
+ "website": "https://evolution-api.com/opensource-whatsapp-api/"
+ },
+ "tags": [
+ "api",
+ "whatsapp",
+ "messaging"
+ ]
+ },
+ {
+ "id": "conduwuit",
+ "name": "Conduwuit",
+ "version": "latest",
+ "description": "Well-maintained, featureful Matrix chat homeserver (fork of Conduit)",
+ "logo": "conduwuit.svg",
+ "links": {
+ "github": "https://github.com/girlbossceo/conduwuit",
+ "website": "https://conduwuit.puppyirl.gay",
+ "docs": "https://conduwuit.puppyirl.gay/configuration.html"
+ },
+ "tags": [
+ "backend",
+ "chat",
+ "communication",
+ "matrix",
+ "server"
+ ]
+ },
+ {
+ "id": "cloudflared",
+ "name": "Cloudflared",
+ "version": "latest",
+ "description": "A lightweight daemon that securely connects local services to the internet through Cloudflare Tunnel.",
+ "logo": "cloudflared.svg",
+ "links": {
+ "github": "https://github.com/cloudflare/cloudflared",
+ "website": "https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/",
+ "docs": "https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/"
+ },
+ "tags": [
+ "cloud",
+ "networking",
+ "security",
+ "tunnel"
+ ]
+ },
+ {
+ "id": "couchdb",
+ "name": "CouchDB",
+ "version": "latest",
+ "description": "CouchDB is a document-oriented NoSQL database that excels at replication and horizontal scaling.",
+ "logo": "couchdb.png",
+ "links": {
+ "github": "https://github.com/apache/couchdb",
+ "website": "https://couchdb.apache.org/",
+ "docs": "https://docs.couchdb.org/en/stable/"
+ },
+ "tags": [
+ "database",
+ "storage"
+ ]
+ },
+ {
+ "id": "it-tools",
+ "name": "IT Tools",
+ "version": "latest",
+ "description": "A collection of handy online it-tools for developers.",
+ "logo": "it-tools.svg",
+ "links": {
+ "github": "https://github.com/CorentinTh/it-tools",
+ "website": "https://it-tools.tech"
+ },
+ "tags": [
+ "developer",
+ "tools"
+ ]
+ },
+ {
+ "id": "superset",
+ "name": "Superset (Unofficial)",
+ "version": "latest",
+ "description": "Data visualization and data exploration platform.",
+ "logo": "superset.svg",
+ "links": {
+ "github": "https://github.com/amancevice/docker-superset",
+ "website": "https://superset.apache.org",
+ "docs": "https://superset.apache.org/docs/intro"
+ },
+ "tags": [
+ "analytics",
+ "bi",
+ "dashboard",
+ "database",
+ "sql"
+ ]
+ },
+ {
+ "id": "glance",
+ "name": "Glance",
+ "version": "latest",
+ "description": "A self-hosted dashboard that puts all your feeds in one place. Features RSS feeds, weather, bookmarks, site monitoring, and more in a minimal, fast interface.",
+ "logo": "glance.png",
+ "links": {
+ "github": "https://github.com/glanceapp/glance",
+ "docs": "https://github.com/glanceapp/glance/blob/main/docs/configuration.md"
+ },
+ "tags": [
+ "dashboard",
+ "monitoring",
+ "widgets",
+ "rss"
+ ]
+ },
+ {
+ "id": "homarr",
+ "name": "Homarr",
+ "version": "latest",
+ "description": "A sleek, modern dashboard that puts all your apps and services in one place with Docker integration.",
+ "logo": "homarr.png",
+ "links": {
+ "github": "https://github.com/homarr-labs/homarr",
+ "docs": "https://homarr.dev/docs/getting-started/installation/docker",
+ "website": "https://homarr.dev/"
+ },
+ "tags": [
+ "dashboard",
+ "monitoring"
+ ]
+ },
+ {
+ "id": "erpnext",
+ "name": "ERPNext",
+ "version": "version-15",
+ "description": "100% Open Source and highly customizable ERP software.",
+ "logo": "erpnext.svg",
+ "links": {
+ "github": "https://github.com/frappe/erpnext",
+ "docs": "https://docs.frappe.io/erpnext",
+ "website": "https://erpnext.com"
+ },
+ "tags": [
+ "erp",
+ "accounts",
+ "manufacturing",
+ "retail",
+ "sales",
+ "pos",
+ "hrms"
+ ]
+ },
+ {
+ "id": "maybe",
+ "name": "Maybe",
+ "version": "latest",
+ "description": "Maybe is a self-hosted finance tracking application designed to simplify budgeting and expenses.",
+ "logo": "maybe.svg",
+ "links": {
+ "github": "https://github.com/maybe-finance/maybe",
+ "website": "https://maybe.finance/",
+ "docs": "https://docs.maybe.finance/"
+ },
+ "tags": [
+ "finance",
+ "self-hosted"
+ ]
+ },
+ {
+ "id": "spacedrive",
+ "name": "Spacedrive",
+ "version": "latest",
+ "description": "Spacedrive is a cross-platform file manager. It connects your devices together to help you organize files from anywhere. powered by a virtual distributed filesystem (VDFS) written in Rust. Organize files across many devices in one place.",
+ "links": {
+ "github": "https://github.com/spacedriveapp/spacedrive",
+ "website": "https://spacedrive.com/",
+ "docs": "https://www.spacedrive.com/docs/product/getting-started/introduction"
+ },
+ "logo": "spacedrive.png",
+ "tags": [
+ "file-manager",
+ "vdfs",
+ "storage"
+ ]
+ },
+ {
+ "id": "registry",
+ "name": "Docker Registry",
+ "version": "2",
+ "description": "Distribution implementation for storing and distributing of Docker container images and artifacts.",
+ "links": {
+ "github": "https://github.com/distribution/distribution",
+ "website": "https://hub.docker.com/_/registry",
+ "docs": "https://distribution.github.io/distribution/"
+ },
+ "logo": "registry.png",
+ "tags": [
+ "registry",
+ "docker",
+ "self-hosted"
+ ]
+ },
+ {
+ "id": "alist",
+ "name": "AList",
+ "version": "v3.41.0",
+ "description": "🗂️A file list/WebDAV program that supports multiple storages, powered by Gin and Solidjs.",
+ "logo": "alist.svg",
+ "links": {
+ "github": "https://github.com/AlistGo/alist",
+ "website": "https://alist.nn.ci",
+ "docs": "https://alist.nn.ci/guide/install/docker.html"
+ },
+ "tags": [
+ "file",
+ "webdav",
+ "storage"
+ ]
+ },
+ {
+ "id": "answer",
+ "name": "Answer",
+ "version": "v1.4.1",
+ "description": "Answer is an open-source Q&A platform for building a self-hosted question-and-answer service.",
+ "logo": "answer.png",
+ "links": {
+ "github": "https://github.com/apache/answer",
+ "website": "https://answer.apache.org/",
+ "docs": "https://answer.apache.org/docs"
+ },
+ "tags": [
+ "q&a",
+ "self-hosted"
+ ]
+ },
+ {
+ "id": "shlink",
+ "name": "Shlink",
+ "version": "stable",
+ "description": "URL shortener that can be used to serve shortened URLs under your own domain.",
+ "logo": "shlink.svg",
+ "links": {
+ "github": "https://github.com/shlinkio/shlink",
+ "website": "https://shlink.io",
+ "docs": "https://shlink.io/documentation"
+ },
+ "tags": [
+ "sharing",
+ "shortener",
+ "url"
+ ]
+ },
+ {
+ "id": "frappe-hr",
+ "name": "Frappe HR",
+ "version": "version-15",
+ "description": "Feature rich HR & Payroll software. 100% FOSS and customizable.",
+ "logo": "frappe-hr.svg",
+ "links": {
+ "github": "https://github.com/frappe/hrms",
+ "docs": "https://docs.frappe.io/hr",
+ "website": "https://frappe.io/hr"
+ },
+ "tags": [
+ "hrms",
+ "payroll",
+ "leaves",
+ "expenses",
+ "attendance",
+ "performace"
+ ]
+ },
+ {
+ "id": "formbricks",
+ "name": "Formbricks",
+ "version": "v3.1.3",
+ "description": "Formbricks is an open-source survey and form platform for collecting user data.",
+ "logo": "formbricks.png",
+ "links": {
+ "github": "https://github.com/formbricks/formbricks",
+ "website": "https://formbricks.com/",
+ "docs": "https://formbricks.com/docs"
+ },
+ "tags": [
+ "forms",
+ "analytics"
+ ]
+ },
+ {
+ "id": "trilium",
+ "name": "Trilium",
+ "description": "Trilium Notes is a hierarchical note taking application with focus on building large personal knowledge bases.",
+ "logo": "trilium.png",
+ "version": "latest",
+ "links": {
+ "github": "https://github.com/zadam/trilium",
+ "website": "https://github.com/zadam/trilium",
+ "docs": "https://github.com/zadam/trilium/wiki/"
+ },
+ "tags": [
+ "self-hosted",
+ "productivity",
+ "personal-use"
+ ]
+ },
+ {
+ "id": "convex",
+ "name": "Convex",
+ "version": "latest",
+ "description": "Convex is an open-source reactive database designed to make life easy for web app developers.",
+ "logo": "convex.svg",
+ "links": {
+ "github": "https://github.com/get-convex/convex",
+ "website": "https://www.convex.dev/",
+ "docs": "https://www.convex.dev/docs"
+ },
+ "tags": [
+ "backend",
+ "database",
+ "api"
+ ]
+ },
+ {
+ "id": "wikijs",
+ "name": "Wiki.js",
+ "version": "2.5",
+ "description": "The most powerful and extensible open source Wiki software.",
+ "logo": "wikijs.svg",
+ "links": {
+ "github": "https://github.com/requarks/wiki",
+ "website": "https://js.wiki/",
+ "docs": "https://docs.requarks.io/"
+ },
+ "tags": [
+ "knowledge-base",
+ "self-hosted",
+ "documentation"
+ ]
}
-]
+ ]
\ No newline at end of file