diff --git a/apps/dokploy/public/templates/huly.svg b/apps/dokploy/public/templates/huly.svg
new file mode 100644
index 00000000..55a98587
--- /dev/null
+++ b/apps/dokploy/public/templates/huly.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/dokploy/public/templates/langflow.svg b/apps/dokploy/public/templates/langflow.svg
new file mode 100644
index 00000000..3665f824
--- /dev/null
+++ b/apps/dokploy/public/templates/langflow.svg
@@ -0,0 +1,6 @@
+
diff --git a/apps/dokploy/public/templates/unsend.png b/apps/dokploy/public/templates/unsend.png
new file mode 100644
index 00000000..0bbe5e0f
Binary files /dev/null and b/apps/dokploy/public/templates/unsend.png differ
diff --git a/apps/dokploy/templates/huly/docker-compose.yml b/apps/dokploy/templates/huly/docker-compose.yml
new file mode 100644
index 00000000..471ee7e9
--- /dev/null
+++ b/apps/dokploy/templates/huly/docker-compose.yml
@@ -0,0 +1,184 @@
+name: ${DOCKER_NAME}
+version: "3"
+services:
+ nginx:
+ networks:
+ - dokploy-network
+ image: "nginx:1.21.3"
+ ports:
+ - 80
+ volumes:
+ - ../files/volumes/nginx/.huly.nginx:/etc/nginx/conf.d/default.conf
+ restart: unless-stopped
+
+ mongodb:
+ networks:
+ - dokploy-network
+ image: "mongo:7-jammy"
+ environment:
+ - PUID=1000
+ - PGID=1000
+ volumes:
+ - db:/data/db
+ restart: unless-stopped
+
+ minio:
+ networks:
+ - dokploy-network
+ image: "minio/minio:RELEASE.2024-11-07T00-52-20Z"
+ command: server /data --address ":9000" --console-address ":9001"
+ volumes:
+ - files:/data
+ restart: unless-stopped
+
+ elastic:
+ networks:
+ - dokploy-network
+ 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:
+ networks:
+ - dokploy-network
+ image: hardcoreeng/rekoni-service:${HULY_VERSION}
+ environment:
+ - SECRET=${SECRET}
+ deploy:
+ resources:
+ limits:
+ memory: 500M
+ restart: unless-stopped
+
+ transactor:
+ networks:
+ - dokploy-network
+ 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:
+ networks:
+ - dokploy-network
+ 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:
+ networks:
+ - dokploy-network
+ 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:
+ networks:
+ - dokploy-network
+ 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:
+ networks:
+ - dokploy-network
+ 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:
+ networks:
+ - dokploy-network
+ 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:
+ networks:
+ - dokploy-network
+ image: hardcoreeng/stats:${HULY_VERSION}
+ environment:
+ - PORT=4900
+ - SERVER_SECRET=${SECRET}
+ restart: unless-stopped
+volumes:
+ db:
+ elastic:
+ files:
diff --git a/apps/dokploy/templates/huly/index.ts b/apps/dokploy/templates/huly/index.ts
new file mode 100644
index 00000000..deb5c7db
--- /dev/null
+++ b/apps/dokploy/templates/huly/index.ts
@@ -0,0 +1,152 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generateBase64,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const mainDomain = generateRandomDomain(schema);
+ const hulySecret = generateBase64(64);
+ const domains: DomainSchema[] = [
+ {
+ host: generateRandomDomain(schema),
+ port: 80,
+ serviceName: "nginx",
+ },
+ ];
+
+ const envs = [
+ "HULY_VERSION=v0.6.377",
+ "DOCKER_NAME=huly",
+ "",
+ "# The address of the host or server from which you will access your Huly instance.",
+ "# This can be a domain name (e.g., huly.example.com) or an IP address (e.g., 192.168.1.1).",
+ `HOST_ADDRESS=${mainDomain}`,
+ "",
+ "# Set this variable to 'true' to enable SSL (HTTPS/WSS). ",
+ "# Leave it empty to use non-SSL (HTTP/WS).",
+ "SECURE=",
+ "",
+ "# Specify the IP address to bind to; leave blank to bind to all interfaces (0.0.0.0).",
+ "# Do not use IP:PORT format in HTTP_BIND or HTTP_PORT.",
+ "HTTP_PORT=80",
+ "HTTP_BIND=",
+ "",
+ "# Huly specific variables",
+ "TITLE=Huly",
+ "DEFAULT_LANGUAGE=en",
+ "LAST_NAME_FIRST=true",
+ "",
+ "# The following configs are auto-generated by the setup script. ",
+ "# Please do not manually overwrite.",
+ "",
+ "# Run with --secret to regenerate.",
+ `SECRET=${hulySecret}`,
+ ];
+
+ const mounts: Template["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 /_love {
+ # 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 ^/_love(/.*)$ $1 break;
+ # proxy_pass http://love:8096/;
+ #}
+
+ 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/;
+ }
+}`,
+ },
+ ];
+
+ return {
+ domains,
+ envs,
+ mounts,
+ };
+}
diff --git a/apps/dokploy/templates/langflow/docker-compose.yml b/apps/dokploy/templates/langflow/docker-compose.yml
new file mode 100644
index 00000000..75bb73dd
--- /dev/null
+++ b/apps/dokploy/templates/langflow/docker-compose.yml
@@ -0,0 +1,33 @@
+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
+ networks:
+ - dokploy-network
+
+ 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
+ networks:
+ - dokploy-network
+
+volumes:
+ langflow-postgres:
+ langflow-data:
\ No newline at end of file
diff --git a/apps/dokploy/templates/langflow/index.ts b/apps/dokploy/templates/langflow/index.ts
new file mode 100644
index 00000000..75f6db58
--- /dev/null
+++ b/apps/dokploy/templates/langflow/index.ts
@@ -0,0 +1,28 @@
+import {
+ type DomainSchema,
+ type Schema,
+ type Template,
+ generatePassword,
+ generateRandomDomain,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const mainDomain = generateRandomDomain(schema);
+ const dbPassword = generatePassword();
+ const dbUsername = "langflow";
+
+ const domains: DomainSchema[] = [
+ {
+ host: mainDomain,
+ port: 7860,
+ serviceName: "langflow",
+ },
+ ];
+
+ const envs = [`DB_PASSWORD=${dbPassword}`, `DB_USERNAME=${dbUsername}`];
+
+ return {
+ domains,
+ envs,
+ };
+}
diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts
index 79b5889c..9aaf1ee0 100644
--- a/apps/dokploy/templates/templates.ts
+++ b/apps/dokploy/templates/templates.ts
@@ -1077,4 +1077,48 @@ export const templates: TemplateData[] = [
tags: ["desing", "collaboration"],
load: () => import("./penpot/index").then((m) => m.generate),
},
+ {
+ 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"],
+ load: () => import("./huly/index").then((m) => m.generate),
+ },
+ {
+ id: "unsend",
+ name: "Unsend",
+ version: "v1.2.4",
+ description: "Open source alternative to Resend,Sendgrid, Postmark etc. ",
+ logo: "unsend.png", // we defined the name and the extension of the logo
+ links: {
+ github: "https://github.com/unsend-dev/unsend",
+ website: "https://unsend.dev/",
+ docs: "https://docs.unsend.dev/get-started/",
+ },
+ tags: ["e-mail", "marketing", "business"],
+ load: () => import("./unsend/index").then((m) => m.generate),
+ },
+ {
+ 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"],
+ load: () => import("./langflow/index").then((m) => m.generate),
+ },
];
diff --git a/apps/dokploy/templates/unsend/docker-compose.yml b/apps/dokploy/templates/unsend/docker-compose.yml
new file mode 100644
index 00000000..cdf02de6
--- /dev/null
+++ b/apps/dokploy/templates/unsend/docker-compose.yml
@@ -0,0 +1,78 @@
+name: unsend-prod
+
+services:
+ unsend-db-prod:
+ image: postgres:16
+ networks:
+ - dokploy-network
+ restart: always
+ environment:
+ - POSTGRES_USER=${POSTGRES_USER:?err}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?err}
+ - POSTGRES_DB=${POSTGRES_DB:?err}
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ # ports:
+ # - "5432:5432"
+ volumes:
+ - database:/var/lib/postgresql/data
+
+ unsend-redis-prod:
+ image: redis:7
+ networks:
+ - dokploy-network
+ restart: always
+ # ports:
+ # - "6379:6379"
+ volumes:
+ - cache:/data
+ command: ["redis-server", "--maxmemory-policy", "noeviction"]
+
+ unsend-storage-prod:
+ image: minio/minio:RELEASE.2024-11-07T00-52-20Z
+ networks:
+ - dokploy-network
+ ports:
+ - 9002
+ - 9001
+ volumes:
+ - storage:/data
+ environment:
+ MINIO_ROOT_USER: unsend
+ MINIO_ROOT_PASSWORD: password
+ entrypoint: sh
+ command: -c 'mkdir -p /data/unsend && minio server /data --console-address ":9001" --address ":9002"'
+
+ unsend:
+ image: unsend/unsend:v1.2.4
+ networks:
+ - dokploy-network
+ restart: always
+ ports:
+ - ${PORT:-3000}
+ environment:
+ - PORT=${PORT:-3000}
+ - DATABASE_URL=${DATABASE_URL:?err}
+ - NEXTAUTH_URL=${NEXTAUTH_URL:?err}
+ - NEXTAUTH_SECRET=${NEXTAUTH_SECRET:?err}
+ - AWS_ACCESS_KEY=${AWS_ACCESS_KEY:?err}
+ - AWS_SECRET_KEY=${AWS_SECRET_KEY:?err}
+ - AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION:?err}
+ - GITHUB_ID=${GITHUB_ID:?err}
+ - GITHUB_SECRET=${GITHUB_SECRET:?err}
+ - REDIS_URL=${REDIS_URL:?err}
+ - NEXT_PUBLIC_IS_CLOUD=${NEXT_PUBLIC_IS_CLOUD:-false}
+ - API_RATE_LIMIT=${API_RATE_LIMIT:-1}
+ depends_on:
+ unsend-db-prod:
+ condition: service_healthy
+ unsend-redis-prod:
+ condition: service_started
+
+volumes:
+ database:
+ cache:
+ storage:
diff --git a/apps/dokploy/templates/unsend/index.ts b/apps/dokploy/templates/unsend/index.ts
new file mode 100644
index 00000000..a383b771
--- /dev/null
+++ b/apps/dokploy/templates/unsend/index.ts
@@ -0,0 +1,44 @@
+import {
+ generateHash,
+ generateRandomDomain,
+ generateBase64,
+ type Template,
+ type Schema,
+ type DomainSchema,
+} from "../utils";
+
+export function generate(schema: Schema): Template {
+ const mainDomain = generateRandomDomain(schema);
+ const secretBase = generateBase64(64);
+
+ const domains: DomainSchema[] = [
+ {
+ host: mainDomain,
+ port: 3000,
+ serviceName: "unsend",
+ },
+ ];
+
+ const envs = [
+ "REDIS_URL=redis://unsend-redis-prod:6379",
+ "POSTGRES_USER=postgres",
+ "POSTGRES_PASSWORD=postgres",
+ "POSTGRES_DB=unsend",
+ "DATABASE_URL=postgresql://postgres:postgres@unsend-db-prod:5432/unsend",
+ "NEXTAUTH_URL=http://localhost:3000",
+ `NEXTAUTH_SECRET=${secretBase}`,
+ "GITHUB_ID='Fill'",
+ "GITHUB_SECRET='Fill'",
+ "AWS_DEFAULT_REGION=us-east-1",
+ "AWS_SECRET_KEY='Fill'",
+ "AWS_ACCESS_KEY='Fill'",
+ "DOCKER_OUTPUT=1",
+ "API_RATE_LIMIT=1",
+ "DISCORD_WEBHOOK_URL=",
+ ];
+
+ return {
+ envs,
+ domains,
+ };
+}