From ed470ee827ad62f2fe666a97cf7da30d127b0143 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Tue, 12 Nov 2024 12:33:34 -0500 Subject: [PATCH 01/32] Add: Peppermint.sh --- apps/dokploy/public/templates/peppermint.svg | 13 ++++++ .../templates/peppermint/docker-compose.yml | 36 ++++++++++++++++ apps/dokploy/templates/peppermint/index.ts | 43 +++++++++++++++++++ apps/dokploy/templates/templates.ts | 14 ++++++ 4 files changed, 106 insertions(+) create mode 100644 apps/dokploy/public/templates/peppermint.svg create mode 100644 apps/dokploy/templates/peppermint/docker-compose.yml create mode 100644 apps/dokploy/templates/peppermint/index.ts diff --git a/apps/dokploy/public/templates/peppermint.svg b/apps/dokploy/public/templates/peppermint.svg new file mode 100644 index 00000000..b6fff994 --- /dev/null +++ b/apps/dokploy/public/templates/peppermint.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/apps/dokploy/templates/peppermint/docker-compose.yml b/apps/dokploy/templates/peppermint/docker-compose.yml new file mode 100644 index 00000000..a20bedf4 --- /dev/null +++ b/apps/dokploy/templates/peppermint/docker-compose.yml @@ -0,0 +1,36 @@ +version: "3.8" + +services: + peppermint_postgres: + image: postgres:latest + restart: always + networks: + - dokploy-network + volumes: + - pgdata:/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: + image: pepperlabs/peppermint:latest + restart: always + networks: + - dokploy-network + depends_on: + peppermint_postgres: + condition: service_healthy + environment: + DB_USERNAME: "peppermint" + DB_PASSWORD: ${POSTGRES_PASSWORD} + DB_HOST: "peppermint_postgres" + SECRET: ${SECRET} + +volumes: + pgdata: \ No newline at end of file diff --git a/apps/dokploy/templates/peppermint/index.ts b/apps/dokploy/templates/peppermint/index.ts new file mode 100644 index 00000000..867a5254 --- /dev/null +++ b/apps/dokploy/templates/peppermint/index.ts @@ -0,0 +1,43 @@ +import { + type DomainSchema, + type Schema, + type Template, + generateBase64, + generatePassword, + generateRandomDomain, +} from "../utils"; + +export function generate(schema: Schema): Template { + // Generate domains and secrets + const mainDomain = generateRandomDomain(schema); + const apiDomain = generateRandomDomain(schema); + const postgresPassword = generatePassword(); + const secret = generateBase64(32); + + // Configure domain routing + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 3000, + serviceName: "peppermint", + }, + { + host: apiDomain, + port: 5003, + serviceName: "peppermint", + }, + ]; + + // Set environment variables + const envs = [ + `MAIN_DOMAIN=${mainDomain}`, + `API_DOMAIN=${apiDomain}`, + `POSTGRES_PASSWORD=${postgresPassword}`, + `SECRET=${secret}`, + ]; + + return { + domains, + envs, + }; +} \ No newline at end of file diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index 28af7c56..8be8b2ed 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -702,4 +702,18 @@ export const templates: TemplateData[] = [ tags: ["IA", "chat"], load: () => import("./lobe-chat/index").then((m) => m.generate), }, + { + 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"], + load: () => import("./peppermint/index").then((m) => m.generate), + }, ]; From 88f969917fb220e45b41618055f07a1bb633c771 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Tue, 12 Nov 2024 12:50:08 -0500 Subject: [PATCH 02/32] Add: Windmill.dev --- apps/dokploy/public/templates/windmill.svg | 29 +++++ apps/dokploy/templates/templates.ts | 14 +++ .../templates/windmill/docker-compose.yml | 107 ++++++++++++++++++ apps/dokploy/templates/windmill/index.ts | 43 +++++++ 4 files changed, 193 insertions(+) create mode 100644 apps/dokploy/public/templates/windmill.svg create mode 100644 apps/dokploy/templates/windmill/docker-compose.yml create mode 100644 apps/dokploy/templates/windmill/index.ts diff --git a/apps/dokploy/public/templates/windmill.svg b/apps/dokploy/public/templates/windmill.svg new file mode 100644 index 00000000..2b06716f --- /dev/null +++ b/apps/dokploy/public/templates/windmill.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index 8be8b2ed..2e3fbf85 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -716,4 +716,18 @@ export const templates: TemplateData[] = [ tags: ["api", "development", "documentation"], load: () => import("./peppermint/index").then((m) => m.generate), }, + { + 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"], + load: () => import("./windmill/index").then((m) => m.generate), + }, ]; diff --git a/apps/dokploy/templates/windmill/docker-compose.yml b/apps/dokploy/templates/windmill/docker-compose.yml new file mode 100644 index 00000000..de4e61cb --- /dev/null +++ b/apps/dokploy/templates/windmill/docker-compose.yml @@ -0,0 +1,107 @@ +version: "3.8" + +services: + db: + image: postgres:16 + shm_size: 1g + restart: unless-stopped + volumes: + - db_data:/var/lib/postgresql/data + networks: + - dokploy-network + 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 + networks: + - dokploy-network + restart: unless-stopped + environment: + - DATABASE_URL=${DATABASE_URL} + - MODE=server + - BASE_URL=http://${WINDMILL_HOST} + depends_on: + db: + condition: service_healthy + volumes: + - 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 + networks: + - dokploy-network + environment: + - DATABASE_URL=${DATABASE_URL} + - MODE=worker + - WORKER_GROUP=default + depends_on: + db: + condition: service_healthy + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - worker_dependency_cache:/tmp/windmill/cache + - 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 + networks: + - dokploy-network + environment: + - DATABASE_URL=${DATABASE_URL} + - MODE=worker + - WORKER_GROUP=native + - NUM_WORKERS=8 + - SLEEP_QUEUE=200 + depends_on: + db: + condition: service_healthy + volumes: + - worker_logs:/tmp/windmill/logs + + lsp: + image: ghcr.io/windmill-labs/windmill-lsp:latest + restart: unless-stopped + networks: + - dokploy-network + volumes: + - lsp_cache:/root/.cache + + caddy: + image: ghcr.io/windmill-labs/caddy-l4:latest + restart: unless-stopped + networks: + - dokploy-network + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile + environment: + - BASE_URL=":80" + depends_on: + - windmill_server + - lsp + +volumes: + db_data: + worker_dependency_cache: + worker_logs: + lsp_cache: \ No newline at end of file diff --git a/apps/dokploy/templates/windmill/index.ts b/apps/dokploy/templates/windmill/index.ts new file mode 100644 index 00000000..3c8ee719 --- /dev/null +++ b/apps/dokploy/templates/windmill/index.ts @@ -0,0 +1,43 @@ +import { + type DomainSchema, + type Schema, + type Template, + generatePassword, + generateRandomDomain, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const postgresPassword = generatePassword(); + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 80, + serviceName: "caddy", + }, + ]; + + const envs = [ + `WINDMILL_HOST=${mainDomain}`, + `POSTGRES_PASSWORD=${postgresPassword}`, + `DATABASE_URL=postgres://postgres:${postgresPassword}@db/windmill?sslmode=disable`, + ]; + + const mounts: Template["mounts"] = [ + { + mountPath: "./Caddyfile", + content: `{$BASE_URL} { + bind {$ADDRESS} + reverse_proxy /ws/* http://lsp:3001 + reverse_proxy /* http://windmill_server:8000 +}` + }, + ]; + + return { + domains, + envs, + mounts, + }; +} \ No newline at end of file From 59c050b519dcb990e96ce98752d1d9032cf1fec1 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Tue, 12 Nov 2024 13:05:21 -0500 Subject: [PATCH 03/32] Add: Activepieces --- .../dokploy/public/templates/activepieces.svg | 4 ++ .../templates/activepieces/docker-compose.yml | 53 +++++++++++++++++++ apps/dokploy/templates/activepieces/index.ts | 33 ++++++++++++ apps/dokploy/templates/templates.ts | 14 +++++ 4 files changed, 104 insertions(+) create mode 100644 apps/dokploy/public/templates/activepieces.svg create mode 100644 apps/dokploy/templates/activepieces/docker-compose.yml create mode 100644 apps/dokploy/templates/activepieces/index.ts diff --git a/apps/dokploy/public/templates/activepieces.svg b/apps/dokploy/public/templates/activepieces.svg new file mode 100644 index 00000000..dcf0a52b --- /dev/null +++ b/apps/dokploy/public/templates/activepieces.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/apps/dokploy/templates/activepieces/docker-compose.yml b/apps/dokploy/templates/activepieces/docker-compose.yml new file mode 100644 index 00000000..cc9eca49 --- /dev/null +++ b/apps/dokploy/templates/activepieces/docker-compose.yml @@ -0,0 +1,53 @@ +version: "3.8" + +services: + activepieces: + image: ghcr.io/activepieces/activepieces:0.35.0 + restart: unless-stopped + networks: + - dokploy-network + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + environment: + - AP_POSTGRES_DATABASE=${AP_POSTGRES_DATABASE} + - AP_POSTGRES_PASSWORD=${AP_POSTGRES_PASSWORD} + - AP_POSTGRES_USERNAME=${AP_POSTGRES_USERNAME} + - AP_POSTGRES_HOST=postgres + - AP_REDIS_HOST=redis + + postgres: + image: postgres:14.4 + restart: unless-stopped + networks: + - dokploy-network + environment: + - POSTGRES_DB=${AP_POSTGRES_DATABASE} + - POSTGRES_PASSWORD=${AP_POSTGRES_PASSWORD} + - POSTGRES_USER=${AP_POSTGRES_USERNAME} + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${AP_POSTGRES_USERNAME}"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:7.0.7 + restart: unless-stopped + networks: + - dokploy-network + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + postgres_data: + redis_data: \ No newline at end of file diff --git a/apps/dokploy/templates/activepieces/index.ts b/apps/dokploy/templates/activepieces/index.ts new file mode 100644 index 00000000..95f3f632 --- /dev/null +++ b/apps/dokploy/templates/activepieces/index.ts @@ -0,0 +1,33 @@ +import { + type DomainSchema, + type Schema, + type Template, + generatePassword, + generateRandomDomain, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const postgresPassword = generatePassword(); + const postgresUser = "activepieces"; + const postgresDb = "activepieces"; + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 80, + serviceName: "activepieces", + }, + ]; + + const envs = [ + `AP_POSTGRES_DATABASE=${postgresDb}`, + `AP_POSTGRES_PASSWORD=${postgresPassword}`, + `AP_POSTGRES_USERNAME=${postgresUser}`, + ]; + + return { + domains, + envs, + }; +} \ No newline at end of file diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index 2e3fbf85..c41b0e8d 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -730,4 +730,18 @@ export const templates: TemplateData[] = [ tags: ["workflow", "automation", "development"], load: () => import("./windmill/index").then((m) => m.generate), }, + { + 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"], + load: () => import("./activepieces/index").then((m) => m.generate), + }, ]; From 0799f8e04c75c654edab22368497e1c52fbda141 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Tue, 12 Nov 2024 13:05:56 -0500 Subject: [PATCH 04/32] Fix: Windmill Path --- apps/dokploy/templates/windmill/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dokploy/templates/windmill/index.ts b/apps/dokploy/templates/windmill/index.ts index 3c8ee719..7608476b 100644 --- a/apps/dokploy/templates/windmill/index.ts +++ b/apps/dokploy/templates/windmill/index.ts @@ -26,7 +26,7 @@ export function generate(schema: Schema): Template { const mounts: Template["mounts"] = [ { - mountPath: "./Caddyfile", + filePath: "./Caddyfile", content: `{$BASE_URL} { bind {$ADDRESS} reverse_proxy /ws/* http://lsp:3001 From 4f092b2fb335d0c4b38aa8f9b79ee575426d42ec Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Tue, 12 Nov 2024 13:12:31 -0500 Subject: [PATCH 05/32] Add: InvoiceShelf --- .../dokploy/public/templates/invoiceshelf.png | Bin 0 -> 23342 bytes .../templates/invoiceshelf/docker-compose.yml | 55 ++++++++++++++++++ apps/dokploy/templates/invoiceshelf/index.ts | 34 +++++++++++ apps/dokploy/templates/templates.ts | 14 +++++ 4 files changed, 103 insertions(+) create mode 100644 apps/dokploy/public/templates/invoiceshelf.png create mode 100644 apps/dokploy/templates/invoiceshelf/docker-compose.yml create mode 100644 apps/dokploy/templates/invoiceshelf/index.ts diff --git a/apps/dokploy/public/templates/invoiceshelf.png b/apps/dokploy/public/templates/invoiceshelf.png new file mode 100644 index 0000000000000000000000000000000000000000..cee025e02bfe560d72279438c4e9507530e5b233 GIT binary patch literal 23342 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 JPDHLkV1hXjTBra3 literal 0 HcmV?d00001 diff --git a/apps/dokploy/templates/invoiceshelf/docker-compose.yml b/apps/dokploy/templates/invoiceshelf/docker-compose.yml new file mode 100644 index 00000000..ac4c8d26 --- /dev/null +++ b/apps/dokploy/templates/invoiceshelf/docker-compose.yml @@ -0,0 +1,55 @@ +version: "3.8" + +services: + invoiceshelf_db: + image: postgres:15 + networks: + - dokploy-network + volumes: + - 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: + image: invoiceshelf/invoiceshelf:latest + networks: + - dokploy-network + volumes: + - app_data:/data + - 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_db + - 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_db: + condition: service_healthy + +volumes: + postgres_data: + app_data: + app_conf: \ No newline at end of file diff --git a/apps/dokploy/templates/invoiceshelf/index.ts b/apps/dokploy/templates/invoiceshelf/index.ts new file mode 100644 index 00000000..2e7c5cf7 --- /dev/null +++ b/apps/dokploy/templates/invoiceshelf/index.ts @@ -0,0 +1,34 @@ +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 = "invoiceshelf"; + const dbDatabase = "invoiceshelf"; + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 80, + serviceName: "invoiceshelf", + }, + ]; + + const envs = [ + `INVOICESHELF_HOST=${mainDomain}`, + `DB_PASSWORD=${dbPassword}`, + `DB_USERNAME=${dbUsername}`, + `DB_DATABASE=${dbDatabase}`, + ]; + + return { + domains, + envs, + }; +} \ No newline at end of file diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index c41b0e8d..27b4921f 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -744,4 +744,18 @@ export const templates: TemplateData[] = [ tags: ["automation", "workflow", "no-code"], load: () => import("./activepieces/index").then((m) => m.generate), }, + { + 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"], + load: () => import("./invoiceshelf/index").then((m) => m.generate), + }, ]; From 814580ff2c447c5ebc83cccd460ce9a83fd49873 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Tue, 12 Nov 2024 13:21:17 -0500 Subject: [PATCH 06/32] Add: Postiz --- apps/dokploy/public/templates/postiz.png | Bin 0 -> 53615 bytes .../templates/postiz/docker-compose.yml | 64 ++++++++++++++++++ apps/dokploy/templates/postiz/index.ts | 37 ++++++++++ apps/dokploy/templates/templates.ts | 14 ++++ 4 files changed, 115 insertions(+) create mode 100644 apps/dokploy/public/templates/postiz.png create mode 100644 apps/dokploy/templates/postiz/docker-compose.yml create mode 100644 apps/dokploy/templates/postiz/index.ts diff --git a/apps/dokploy/public/templates/postiz.png b/apps/dokploy/public/templates/postiz.png new file mode 100644 index 0000000000000000000000000000000000000000..1d435abcdeb5771c12a8b81c5de269171028ab52 GIT binary patch literal 53615 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 mHqZkdY|X<9f*=UC!v7ED* import("./invoiceshelf/index").then((m) => m.generate), }, + { + 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.io", + docs: "https://docs.postiz.io", + }, + tags: ["cms", "content-management", "publishing"], + load: () => import("./postiz/index").then((m) => m.generate), + }, ]; From faceed12b0cc35275986f845e8c8ff61795821ee Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Tue, 12 Nov 2024 13:27:08 -0500 Subject: [PATCH 07/32] Add: Slash Template --- apps/dokploy/public/templates/slash.png | Bin 0 -> 18137 bytes .../templates/slash/docker-compose.yml | 37 ++++++++++++++++++ apps/dokploy/templates/slash/index.ts | 33 ++++++++++++++++ apps/dokploy/templates/templates.ts | 14 +++++++ 4 files changed, 84 insertions(+) create mode 100644 apps/dokploy/public/templates/slash.png create mode 100644 apps/dokploy/templates/slash/docker-compose.yml create mode 100644 apps/dokploy/templates/slash/index.ts diff --git a/apps/dokploy/public/templates/slash.png b/apps/dokploy/public/templates/slash.png new file mode 100644 index 0000000000000000000000000000000000000000..c843b4095d67ec5fa7c60c4a8bff57a0eb46eb03 GIT binary patch literal 18137 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 import("./postiz/index").then((m) => m.generate), }, + { + 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"], + load: () => import("./slash/index").then((m) => m.generate), + }, ]; From 7b06fd47b8fbcc6fcbeb0747ae7e6ba3cbbbd118 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Tue, 12 Nov 2024 13:34:37 -0500 Subject: [PATCH 08/32] Add: Linkstack --- apps/dokploy/public/templates/linkstack.svg | 105 ++++++++++++++++++ .../templates/linkstack/docker-compose.yml | 51 +++++++++ apps/dokploy/templates/linkstack/index.ts | 36 ++++++ apps/dokploy/templates/templates.ts | 14 +++ 4 files changed, 206 insertions(+) create mode 100644 apps/dokploy/public/templates/linkstack.svg create mode 100644 apps/dokploy/templates/linkstack/docker-compose.yml create mode 100644 apps/dokploy/templates/linkstack/index.ts diff --git a/apps/dokploy/public/templates/linkstack.svg b/apps/dokploy/public/templates/linkstack.svg new file mode 100644 index 00000000..775632d2 --- /dev/null +++ b/apps/dokploy/public/templates/linkstack.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/dokploy/templates/linkstack/docker-compose.yml b/apps/dokploy/templates/linkstack/docker-compose.yml new file mode 100644 index 00000000..53f1456b --- /dev/null +++ b/apps/dokploy/templates/linkstack/docker-compose.yml @@ -0,0 +1,51 @@ +version: "3.8" + +services: + linkstack: + image: linkstackorg/linkstack:latest + networks: + - dokploy-network + volumes: + - linkstack_data:/htdocs + environment: + - TZ=UTC + - SERVER_ADMIN=admin@${LINKSTACK_HOST} + - HTTP_SERVER_NAME=${LINKSTACK_HOST} + - HTTPS_SERVER_NAME=${LINKSTACK_HOST} + - LOG_LEVEL=info + - PHP_MEMORY_LIMIT=256M + - UPLOAD_MAX_FILESIZE=8M + - DB_CONNECTION=mysql + - DB_HOST=mysql + - DB_PORT=3306 + - DB_DATABASE=${MYSQL_DATABASE} + - DB_USERNAME=${MYSQL_USER} + - DB_PASSWORD=${MYSQL_PASSWORD} + - FORCE_HTTPS=true + - APP_URL=https://${LINKSTACK_HOST} + depends_on: + mysql: + condition: service_healthy + restart: unless-stopped + + mysql: + image: mysql:8 + networks: + - dokploy-network + volumes: + - mysql_data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} + - MYSQL_DATABASE=${MYSQL_DATABASE} + - MYSQL_USER=${MYSQL_USER} + - MYSQL_PASSWORD=${MYSQL_PASSWORD} + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u${MYSQL_USER}", "-p${MYSQL_PASSWORD}"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + +volumes: + linkstack_data: + mysql_data: \ No newline at end of file diff --git a/apps/dokploy/templates/linkstack/index.ts b/apps/dokploy/templates/linkstack/index.ts new file mode 100644 index 00000000..38852061 --- /dev/null +++ b/apps/dokploy/templates/linkstack/index.ts @@ -0,0 +1,36 @@ +import { + type DomainSchema, + type Schema, + type Template, + generatePassword, + generateRandomDomain, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const mysqlRootPassword = generatePassword(); + const mysqlPassword = generatePassword(); + const mysqlUser = "linkstack"; + const mysqlDatabase = "linkstack"; + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 443, + serviceName: "linkstack", + }, + ]; + + const envs = [ + `LINKSTACK_HOST=${mainDomain}`, + `MYSQL_ROOT_PASSWORD=${mysqlRootPassword}`, + `MYSQL_DATABASE=${mysqlDatabase}`, + `MYSQL_USER=${mysqlUser}`, + `MYSQL_PASSWORD=${mysqlPassword}`, + ]; + + return { + domains, + envs, + }; +} \ No newline at end of file diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index cdfa312e..74d38c43 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -786,4 +786,18 @@ export const templates: TemplateData[] = [ tags: ["bookmarks", "link-shortener", "self-hosted"], load: () => import("./slash/index").then((m) => m.generate), }, + { + id: "linkstack", + name: "LinkStack", + version: "latest", + description: "LinkStack is a highly customizable link sharing platform with an intuitive, easy to use user interface.", + logo: "linkstack.svg", + links: { + github: "https://github.com/LinkStackOrg/LinkStack", + website: "https://linkstack.org/", + docs: "https://docs.linkstack.org/", + }, + tags: ["links", "sharing", "social"], + load: () => import("./linkstack/index").then((m) => m.generate), + }, ]; From 5c17797749d0206de3a9e3b618fdcbd4aa7e4683 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Tue, 12 Nov 2024 16:19:14 -0500 Subject: [PATCH 09/32] Add: Chatwoot --- apps/dokploy/public/templates/chatwoot.svg | 3 + .../templates/chatwoot/docker-compose.yml | 117 ++++++++++++++++++ apps/dokploy/templates/chatwoot/index.ts | 41 ++++++ apps/dokploy/templates/templates.ts | 14 +++ 4 files changed, 175 insertions(+) create mode 100644 apps/dokploy/public/templates/chatwoot.svg create mode 100644 apps/dokploy/templates/chatwoot/docker-compose.yml create mode 100644 apps/dokploy/templates/chatwoot/index.ts diff --git a/apps/dokploy/public/templates/chatwoot.svg b/apps/dokploy/public/templates/chatwoot.svg new file mode 100644 index 00000000..56c9a7b8 --- /dev/null +++ b/apps/dokploy/public/templates/chatwoot.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml new file mode 100644 index 00000000..27885b8a --- /dev/null +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -0,0 +1,117 @@ +version: "3.8" + +services: + base: &base + image: chatwoot/chatwoot:v3.14.1 + volumes: + - storage_data:/app/storage + networks: + - dokploy-network + + rails: + <<: *base + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + environment: + - NODE_ENV=production + - RAILS_ENV=production + - INSTALLATION_ENV=docker + - FRONTEND_URL=https://${CHATWOOT_HOST} + - SECRET_KEY_BASE=${SECRET_KEY_BASE} + - POSTGRES_HOST=postgres + - POSTGRES_USERNAME=${POSTGRES_USERNAME} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DATABASE=chatwoot_production + - REDIS_URL=redis://redis:6379 + - REDIS_PASSWORD=${REDIS_PASSWORD} + - ENABLE_ACCOUNT_SIGNUP=false + - MAILER_SENDER_EMAIL=Chatwoot + - FORCE_SSL=true + - RAILS_LOG_TO_STDOUT=true + - LOG_LEVEL=info + - LOG_SIZE=500 + - RAILS_MAX_THREADS=5 + - SMTP_DOMAIN=${CHATWOOT_HOST} + - SMTP_ADDRESS=${SMTP_ADDRESS} + - SMTP_PORT=${SMTP_PORT} + - SMTP_USERNAME=${SMTP_USERNAME} + - SMTP_PASSWORD=${SMTP_PASSWORD} + - SMTP_AUTHENTICATION=plain + - SMTP_ENABLE_STARTTLS_AUTO=true + entrypoint: docker/entrypoints/rails.sh + command: ['bundle', 'exec', 'rails', 's', '-p', '3000', '-b', '0.0.0.0'] + restart: always + + sidekiq: + <<: *base + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + environment: + - NODE_ENV=production + - RAILS_ENV=production + - INSTALLATION_ENV=docker + - FRONTEND_URL=https://${CHATWOOT_HOST} + - SECRET_KEY_BASE=${SECRET_KEY_BASE} + - POSTGRES_HOST=postgres + - POSTGRES_USERNAME=${POSTGRES_USERNAME} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DATABASE=chatwoot_production + - REDIS_URL=redis://redis:6379 + - REDIS_PASSWORD=${REDIS_PASSWORD} + - FORCE_SSL=true + - RAILS_LOG_TO_STDOUT=true + - LOG_LEVEL=info + - LOG_SIZE=500 + - RAILS_MAX_THREADS=5 + - SMTP_DOMAIN=${CHATWOOT_HOST} + - SMTP_ADDRESS=${SMTP_ADDRESS} + - SMTP_PORT=${SMTP_PORT} + - SMTP_USERNAME=${SMTP_USERNAME} + - SMTP_PASSWORD=${SMTP_PASSWORD} + - SMTP_AUTHENTICATION=plain + - SMTP_ENABLE_STARTTLS_AUTO=true + - MAILER_SENDER_EMAIL=Chatwoot + command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml'] + restart: always + + postgres: + image: postgres:12 + networks: + - dokploy-network + volumes: + - postgres_data:/var/lib/postgresql/data + environment: + - POSTGRES_DB=chatwoot_production + - POSTGRES_USER=${POSTGRES_USERNAME} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USERNAME}"] + interval: 10s + timeout: 5s + retries: 5 + restart: always + + redis: + image: redis:alpine + networks: + - dokploy-network + command: ["sh", "-c", "redis-server --requirepass \"${REDIS_PASSWORD}\""] + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + restart: always + +volumes: + storage_data: + postgres_data: + redis_data: \ No newline at end of file diff --git a/apps/dokploy/templates/chatwoot/index.ts b/apps/dokploy/templates/chatwoot/index.ts new file mode 100644 index 00000000..599b82f5 --- /dev/null +++ b/apps/dokploy/templates/chatwoot/index.ts @@ -0,0 +1,41 @@ +import { + type DomainSchema, + type Schema, + type Template, + generatePassword, + generateRandomDomain, + generateBase64, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const postgresUsername = "chatwoot"; + const postgresPassword = generatePassword(); + const redisPassword = generatePassword(); + const secretKeyBase = generateBase64(64); + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 3000, + serviceName: "rails", + }, + ]; + + const envs = [ + `CHATWOOT_HOST=${mainDomain}`, + `POSTGRES_USERNAME=${postgresUsername}`, + `POSTGRES_PASSWORD=${postgresPassword}`, + `REDIS_PASSWORD=${redisPassword}`, + `SECRET_KEY_BASE=${secretKeyBase}`, + `SMTP_ADDRESS=${process.env.SMTP_ADDRESS || ''}`, + `SMTP_PORT=${process.env.SMTP_PORT || '587'}`, + `SMTP_USERNAME=${process.env.SMTP_USERNAME || ''}`, + `SMTP_PASSWORD=${process.env.SMTP_PASSWORD || ''}`, + ]; + + return { + domains, + envs, + }; +} \ No newline at end of file diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index 74d38c43..bae9a8f7 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -800,4 +800,18 @@ export const templates: TemplateData[] = [ tags: ["links", "sharing", "social"], load: () => import("./linkstack/index").then((m) => m.generate), }, + { + id: "chatwoot", + name: "Chatwoot", + version: "v3.14.1", + description: "Open-source customer engagement suite, an alternative to Intercom, Zendesk, Salesforce Service Cloud etc.", + logo: "chatwoot.svg", + links: { + github: "https://github.com/chatwoot/chatwoot", + website: "https://www.chatwoot.com", + docs: "https://www.chatwoot.com/docs", + }, + tags: ["customer-support", "live-chat", "helpdesk"], + load: () => import("./chatwoot/index").then((m) => m.generate), + }, ]; From deeea114281a12795eb60983d0c738db060c3667 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Tue, 12 Nov 2024 16:37:51 -0500 Subject: [PATCH 10/32] Add: Discord Tickets --- .../public/templates/discordtickets.png | Bin 0 -> 15188 bytes .../discord-tickets/docker-compose.yml | 54 ++++++++++++++++++ .../templates/discord-tickets/index.ts | 46 +++++++++++++++ apps/dokploy/templates/templates.ts | 14 +++++ 4 files changed, 114 insertions(+) create mode 100644 apps/dokploy/public/templates/discordtickets.png create mode 100644 apps/dokploy/templates/discord-tickets/docker-compose.yml create mode 100644 apps/dokploy/templates/discord-tickets/index.ts diff --git a/apps/dokploy/public/templates/discordtickets.png b/apps/dokploy/public/templates/discordtickets.png new file mode 100644 index 0000000000000000000000000000000000000000..030c3a4ca194bd1eeb8fcce764b4decdf460f32b GIT binary patch literal 15188 zcmeHuRYP1&(=8HQLxQ^of}W4em~G2KT@OcXtc!?hKrr=e_xU#JQN8 zo;^LgyQ;cstyLYNC@+DAOn?jp1%)OhDXI(w1wH!jg9rnREVN=wK|%2nN{I@qdS;!h zdHH@+Yx{bkBBODe7{Z7|B?M!%frScfHk+>W(Tw!nO>CeB83h?r8T}wOI3%!niv0B4oZ9X4D+eh;uaw7J zjY6*XxXVMk^Dq(=)Iku3H}ERzq497~lkY`vpoAn4wVS{GUeAB*Q+T-|XHL=YUA+y0 zMw#LN6nR_--r7QOqqzOpm!g;U26~JCNu~$OU*AwD6ptCK#Dgx z!H#uYugDwBAXFtPJc57zF}O{APBR6cm(Bi0afe|Rl^jKpU1`!>eph8B;`UW4#Y_TC zcwA)cViP3~{?JN$+>^CYPY(qyb=%ARruKnTs%!V0&TOC6NaEw|lk|Yoi9=|gnFWREDGE8t-5hJOeCEL~p9R~Q zItHH&2R$jIjOsUJQO00~#hS zIk6=DsI7gBTp8L`b7bY^cI#(8CU8%_D=6hCzx73xd~82&w1<7Vdiyd^w_rBVpm5p! zfbnSRBzjGZ8mypN`(7BZ1S^dZv$T{u|I>Fo(kN=}cA>#QzsZDV7e8oYvu+j-n%Q6HX@wMoxwH5~TRY;2`E& zzKk4k=d<@JD`Cq&c-b^lh}kKs?LZ!f$k-4IM!*l|#p|Ce<<9lXKBSnz-^Cry3O~(k zn9aIrVXte{f=)(RZo=ktj00VIxzLZ{)kEUpMvl_T#|E7wyn5B!n{q8?Pd(Ai<$xC} zInt|-5fG#41^kSi0_PS!1voTNu;A?WV0{lP#>9hA_9HRAjcdnn3+zLSEYQhi@(I{l z5Q$<<)E9>JH_P92bxK3(P(P4G0ZUJweDyoLk!tf`p2ZkpTfhiEoE(4qqarMQ!7z$^ zVTF_;T+c=^Mal^SYz*v^(bR7WU>DvKs~iR;x$hqn~1=hrLGoCOCz8~PC@X7G_X{hCXAy;RY=!jUDu31`* zc|yjU6iq;2b3==&qFplP)n^dA{YMUtU5f=JBm39*VBJVkb?&uy<5JB7I!TZAk0D?~ zh0#v6bcNMRSvzl4nfGTe)6&qTEpC*dM#*`c5*k~hag=>GI z4;oLi%{~i3Q*+n%^Y0Qor=2$%8!Jg=7VY-OcWn!K0(1UcC>`_fOZAvNa1u&dxcpN$Ym3i z)`mMyziGA8nVQeoaM^|oFe7l7V$(C0u`xDC<#x+^2A5q^LEkTg2StA7Eu}9<6Fr|D zmb;g8)mnN9C0=6B@LcGNe942b*>&19Wt2>L%s?@LX$~^PLr{>wFbhSC-SYBXOhU^= zn8*Sj8ww+8v4pM^^Zx`}+<+Fi^%^f_j#4-19?Y$zfN$RUJ@~KNe-(xXBdCW?)C9B7- z%eNoX6+Qj9sHcX3K}z7@<_;N1s%|?SVdU^e%%dD-7W&js4%^J$NQ~7)!gaQ?3_OOg z%$y{j8?GG~e}SI$#l%dL>HEdV_-uS_{_$F2>(nP4%JK>%n%GcF~bU8 zA`j9@RC?uI z$c!>+8?(W{LiI60lT?)U+fO&Ywd&>OsEJWPDIxJ8z|VMKO1;9qm7-^n;qfC*B8cD+ z{4y!OoBaSIe~lisH%7$Yw)u|0rZd3A$&xl5i1zpT~zBp2~#yn{>39P6fkPb*QX-b-02>7w0qM~-Szo@vMOf?*! zFvn6hza;u>>ZcBX*-&R1lj5hfxqp^QInSbTl#`j}`vcKqGGnaWC`w&=h8J4Y^nu9N zP@#J2TWey_r?*Ga*eS4Xpd-1mR*F?B#m%Xh$0>@ppQdLewmv}_;n?^rkoogqJ*d#S zhNzL18vfEDn!a#t?Gf5MkR&CZ5O}r29@hh9jEEjj(?W@Y2*R1@5deiB3l*i}2>jkYB zi(gpjpm~FAz9Sf1xHOo2&gPz5YOEhQNLbXa_mp_ES&Wo!d}x3k2<7$k9${{M{?uZ^ zM=sa**O(XTS>@}2gtyVW;%r*95!#tIrYT#j5VTkLOl{Gw`< z2?j(G2<9%`c)xECl@>k=$9$1{b}u}yQnU7=?xHsMp3b2Ack^%*;lW@7GiY5~saQ?M zUMNLK@?!ISxyNOIE`y(Gq{#teHK$Z;D2=Te5&;kmmUALY9YI)ubd17-z1aPz76ER4 z(Nl%r30P2Ps_N6G#rc)W)I4vIYj);urV##|>1D}MUfr_M*?Ec-!G>Kb$zg&V-vf4{ zSv@q;TE$a}G?H8~9f*PTDups~*aC*IL00 zs`p{QnbDueEPUf~VS7&U_qT0{8jAN{s#_Vkw;x|BF#I<4FPHtd_-xaR($4fk${!g_ zuCw}rnDe@c2IV_esMEH-oKLgat$n&828+cJvfC>wN*l*mUklT1bo~>tSG75c+dZcb0 zTwaRJzR>-6yiPi6(R^NS7SzyZ+Q%&$P?*earyu#8_0!pGS2ZQzsoOKB!FIehI%Dzk zWM@UG9h=oksEjOTM#}|3TawsosRe@ci0zXNkwSIHhCiZ)Q+EnGbYCp#`t;u z^`3iUYTK=mn2t-z<4o!4ZcEVt6M`3NwV{5nl6kUfQz)?E{>Yz?Ja%M~@med^cl7qM z=5r~fL5!?0RcdhI<7WwNhE8Xf72x{^pVT7tpIs=I(oMzXE9suVIS{4i5tLVHhq8dK z9aOy+^Q7Y|a^*y<><|4;oOI~IgUe#T=|?$W7a2?)+;NxkahT}NnXtL+SRjFx=O*({ zBZLpO-tN+#+|(}r=!?VD$BK796BjlTn$GQI-)5UN-~?YjUTe7+YMGxP=DQW#;-Xz_ zj$B!)@mF$NBT0`maMwI_Z_GZJXx!~si}hL8oMmm+4tOZBM_pb(o{PP_KQPZXu@`HexRD%IcwrBGQ0|4*6eB0>h z$g@0BgFbaXg-}KdV!HN$PKd$A;uv#y{npe7X+zqI?j@Xl#?cX2DVTp<*|gGM&LGla zW_bP?L7x-^{+`VC$ksq##AulBk1k zMmAp`%1X7ev<#rj&K%;GlI)jD2BGP97^=la^1i`e;&<`^^)9M7`g@0#Cf4gonEPX*I%Da~&@p4464p4rO=m-lK((9h zetz$8?3^HS)2iRw^JlqaJlXSFA<~=R}h(}t`r#LycCK*V}_yzCG;ID z5ch%#ME+-+vabiJL;R2NK)m~s*RzEhEf*vD`6P_- z1}55e-7ou6hJFTU1P-Nu#S%k2wiETswv&qeatK?i1gYb;RH|GN74JFzHp_M!V8EaM z)%9aek+LnaT{;~v+?rvkclkuBHcKOJOZMz%?R{d_0tJSR+JTBKYbOC?t{Mw&+@5Tw z0`FZk+l{o$XXCkMb{XbPyR3HJ z&d6Is!pI^wzHGy3>Z}Ga`jif07H;{|2Z|HG+*3xDqXZ(gYpLwTKa`%e=gDT(99Ojg zVUrIa`O_mK$J9q6^kK(ot4FGNNBDDBlr-Z`{IPoJUZJgNgqCsxiwbC z#8D@mIo*x8rgid0z9$N`E@n z2#s$S=M`TyAFyscsI%z44}mK;9j}I)V-brK=c^gZ8m2S?pZT`l?eB|7Yl~xDgip0unf?M~LVB+6+$h|m2=ux3w<~PZ{OD2$f&#CaNUr~sLBuQk6D>D!)?0>gU9i}oc*xBc9=`&Fc5|@&%)wW} z8LQz=)VrWdsY%*St`QzbwJD?kSi zJjk4n&3kBX@vZv|<78sZkuk-!_Z+O?%X^2%A093=DE^byTIEcP@rTiq8PD019IQ3$ zGF1Z7c9v!sTKkL1bejUl$jMuS3Nk!f9Mh{aRnJkhaPQ+T?Sw)Jvg#58IImPt&8 ztMU5k(7dpZBi-V1Ft<&GaE?B8g3h( z@+NaD(RPDWd7Pu`q#D&@YVV5vq2O4OP&F7V#7Pxu?Q3({=rFTFE^A{x+j}M>l8x7( zp6*VnM$3M_TV9X)2in(Nx1<1BAcmP3>$lJSxkpXG%mAazId#@PLRQT9J}f zf{q|%H_~JWc0c)TcDM6ETkEZQC4lAO#dm1`?J(dIHA{g1v|aP#Ne*P48wH#9B%=yf zgmZLyrs2)2*JR&&F{yO+ULgLforcYE#Vl)bCsSrO)5;X6mE-((lGre5&K&|XZ~RuM zP3y1w)>9QX9aW--no?@1rZHySPtWE*NU{o2T;eQOf*I)-1YW2vmIQ--@L>2330Cit zVstb!O$vl`Zt+OGb@}Qt*rY=t!ympZ>})32{B9O3J5?^)3d#;eqYwNjrqiS>-m4#+ zZo3#x;b;4Kp*@UP#&`l!R`smR9q0f7Ns_5p%0Autt5=9a&?ax0<_MN}TCwjq+3H7b}^< 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 + Math.floor(Math.random() * 16).toString(16)).join(''); + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 8169, + serviceName: "bot", + }, + ]; + + const envs = [ + `TICKETS_HOST=${mainDomain}`, + `MYSQL_DATABASE=${mysqlDatabase}`, + `MYSQL_PASSWORD=${mysqlPassword}`, + `MYSQL_ROOT_PASSWORD=${mysqlRootPassword}`, + `MYSQL_USER=${mysqlUser}`, + `ENCRYPTION_KEY=${encryptionKey}`, + // These need to be set by the user through the UI + `# 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`, // Default super user + ]; + + return { + domains, + envs, + }; +} \ No newline at end of file diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index bae9a8f7..d3ba44e8 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -814,4 +814,18 @@ export const templates: TemplateData[] = [ tags: ["customer-support", "live-chat", "helpdesk"], load: () => import("./chatwoot/index").then((m) => m.generate), }, + { + 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.svg", + links: { + github: "https://github.com/discord-tickets/bot", + website: "https://discordtickets.app", + docs: "https://discordtickets.app/self-hosting/installation/docker/", + }, + tags: ["discord", "tickets", "support"], + load: () => import("./discord-tickets/index").then((m) => m.generate), + }, ]; From e57efa2e316551ae20a924cdb9eecc9a6f32012a Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 02:47:30 -0500 Subject: [PATCH 11/32] fix: AP Ports --- apps/dokploy/templates/activepieces/docker-compose.yml | 2 ++ apps/dokploy/templates/activepieces/index.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/apps/dokploy/templates/activepieces/docker-compose.yml b/apps/dokploy/templates/activepieces/docker-compose.yml index cc9eca49..4193b87a 100644 --- a/apps/dokploy/templates/activepieces/docker-compose.yml +++ b/apps/dokploy/templates/activepieces/docker-compose.yml @@ -16,7 +16,9 @@ services: - AP_POSTGRES_PASSWORD=${AP_POSTGRES_PASSWORD} - AP_POSTGRES_USERNAME=${AP_POSTGRES_USERNAME} - AP_POSTGRES_HOST=postgres + - AP_POSTGRES_PORT=5432 - AP_REDIS_HOST=redis + - AP_REDIS_PORT=6379 postgres: image: postgres:14.4 diff --git a/apps/dokploy/templates/activepieces/index.ts b/apps/dokploy/templates/activepieces/index.ts index 95f3f632..91a46cf6 100644 --- a/apps/dokploy/templates/activepieces/index.ts +++ b/apps/dokploy/templates/activepieces/index.ts @@ -24,6 +24,8 @@ export function generate(schema: Schema): Template { `AP_POSTGRES_DATABASE=${postgresDb}`, `AP_POSTGRES_PASSWORD=${postgresPassword}`, `AP_POSTGRES_USERNAME=${postgresUser}`, + `AP_POSTGRES_PORT=5432`, + `AP_REDIS_PORT=6379`, ]; return { From 3457de4f36f0a8208a9e4fa6104bfdac3c072419 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 02:48:36 -0500 Subject: [PATCH 12/32] fix: Chatwoot SSL Termination --- apps/dokploy/templates/chatwoot/docker-compose.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml index 27885b8a..ef8e3ab1 100644 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -19,7 +19,7 @@ services: - NODE_ENV=production - RAILS_ENV=production - INSTALLATION_ENV=docker - - FRONTEND_URL=https://${CHATWOOT_HOST} + - FRONTEND_URL=http://${CHATWOOT_HOST} - SECRET_KEY_BASE=${SECRET_KEY_BASE} - POSTGRES_HOST=postgres - POSTGRES_USERNAME=${POSTGRES_USERNAME} @@ -29,7 +29,7 @@ services: - REDIS_PASSWORD=${REDIS_PASSWORD} - ENABLE_ACCOUNT_SIGNUP=false - MAILER_SENDER_EMAIL=Chatwoot - - FORCE_SSL=true + - FORCE_SSL=false - RAILS_LOG_TO_STDOUT=true - LOG_LEVEL=info - LOG_SIZE=500 @@ -56,7 +56,7 @@ services: - NODE_ENV=production - RAILS_ENV=production - INSTALLATION_ENV=docker - - FRONTEND_URL=https://${CHATWOOT_HOST} + - FRONTEND_URL=http://${CHATWOOT_HOST} - SECRET_KEY_BASE=${SECRET_KEY_BASE} - POSTGRES_HOST=postgres - POSTGRES_USERNAME=${POSTGRES_USERNAME} @@ -64,7 +64,7 @@ services: - POSTGRES_DATABASE=chatwoot_production - REDIS_URL=redis://redis:6379 - REDIS_PASSWORD=${REDIS_PASSWORD} - - FORCE_SSL=true + - FORCE_SSL=false - RAILS_LOG_TO_STDOUT=true - LOG_LEVEL=info - LOG_SIZE=500 From 46219e1b3d1cac3cd410f5adb44d047655d8561f Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 02:52:22 -0500 Subject: [PATCH 13/32] fix: Caddyfile for Windmill --- apps/dokploy/templates/windmill/docker-compose.yml | 2 +- apps/dokploy/templates/windmill/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/templates/windmill/docker-compose.yml b/apps/dokploy/templates/windmill/docker-compose.yml index de4e61cb..0dd286fe 100644 --- a/apps/dokploy/templates/windmill/docker-compose.yml +++ b/apps/dokploy/templates/windmill/docker-compose.yml @@ -93,7 +93,7 @@ services: networks: - dokploy-network volumes: - - ./Caddyfile:/etc/caddy/Caddyfile + - ../files/config:/etc/caddy environment: - BASE_URL=":80" depends_on: diff --git a/apps/dokploy/templates/windmill/index.ts b/apps/dokploy/templates/windmill/index.ts index 7608476b..75f7e3f9 100644 --- a/apps/dokploy/templates/windmill/index.ts +++ b/apps/dokploy/templates/windmill/index.ts @@ -26,7 +26,7 @@ export function generate(schema: Schema): Template { const mounts: Template["mounts"] = [ { - filePath: "./Caddyfile", + filePath: "files/config/Caddyfile", content: `{$BASE_URL} { bind {$ADDRESS} reverse_proxy /ws/* http://lsp:3001 From 8d33ff5fb57c30ec89bd6f017df88596e447256e Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 03:20:20 -0500 Subject: [PATCH 14/32] fix: Change Windmill Volume Path --- apps/dokploy/templates/windmill/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dokploy/templates/windmill/docker-compose.yml b/apps/dokploy/templates/windmill/docker-compose.yml index 0dd286fe..aeebfe64 100644 --- a/apps/dokploy/templates/windmill/docker-compose.yml +++ b/apps/dokploy/templates/windmill/docker-compose.yml @@ -93,7 +93,7 @@ services: networks: - dokploy-network volumes: - - ../files/config:/etc/caddy + - ./files/config/Caddyfile:/etc/caddy/Caddyfile environment: - BASE_URL=":80" depends_on: From 3d59e289bea63b990e314bd00929dc82ad088c29 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 04:13:58 -0500 Subject: [PATCH 15/32] fix: ENV Variables in LinkStack --- apps/dokploy/templates/linkstack/docker-compose.yml | 4 +--- apps/dokploy/templates/linkstack/index.ts | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/dokploy/templates/linkstack/docker-compose.yml b/apps/dokploy/templates/linkstack/docker-compose.yml index 53f1456b..2f54bf74 100644 --- a/apps/dokploy/templates/linkstack/docker-compose.yml +++ b/apps/dokploy/templates/linkstack/docker-compose.yml @@ -9,9 +9,7 @@ services: - linkstack_data:/htdocs environment: - TZ=UTC - - SERVER_ADMIN=admin@${LINKSTACK_HOST} - - HTTP_SERVER_NAME=${LINKSTACK_HOST} - - HTTPS_SERVER_NAME=${LINKSTACK_HOST} + - SERVER_ADMIN=${LINKSTACK_SERVER_ADMIN} - LOG_LEVEL=info - PHP_MEMORY_LIMIT=256M - UPLOAD_MAX_FILESIZE=8M diff --git a/apps/dokploy/templates/linkstack/index.ts b/apps/dokploy/templates/linkstack/index.ts index 38852061..af0858d6 100644 --- a/apps/dokploy/templates/linkstack/index.ts +++ b/apps/dokploy/templates/linkstack/index.ts @@ -23,6 +23,7 @@ export function generate(schema: Schema): Template { const envs = [ `LINKSTACK_HOST=${mainDomain}`, + `LINKSTACK_SERVER_ADMIN=admin@example.com`, `MYSQL_ROOT_PASSWORD=${mysqlRootPassword}`, `MYSQL_DATABASE=${mysqlDatabase}`, `MYSQL_USER=${mysqlUser}`, From 69c9e86a137992fe6b9724590150dd96e6b5bcd5 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 04:19:34 -0500 Subject: [PATCH 16/32] fix: Windmill Caddyfile --- apps/dokploy/templates/windmill/docker-compose.yml | 2 +- apps/dokploy/templates/windmill/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/templates/windmill/docker-compose.yml b/apps/dokploy/templates/windmill/docker-compose.yml index aeebfe64..aea5d183 100644 --- a/apps/dokploy/templates/windmill/docker-compose.yml +++ b/apps/dokploy/templates/windmill/docker-compose.yml @@ -93,7 +93,7 @@ services: networks: - dokploy-network volumes: - - ./files/config/Caddyfile:/etc/caddy/Caddyfile + - ../files/stacks/windmill:/etc/caddy environment: - BASE_URL=":80" depends_on: diff --git a/apps/dokploy/templates/windmill/index.ts b/apps/dokploy/templates/windmill/index.ts index 75f7e3f9..2e0a0a9f 100644 --- a/apps/dokploy/templates/windmill/index.ts +++ b/apps/dokploy/templates/windmill/index.ts @@ -26,7 +26,7 @@ export function generate(schema: Schema): Template { const mounts: Template["mounts"] = [ { - filePath: "files/config/Caddyfile", + filePath: "files/stacks/windmill/Caddyfile", content: `{$BASE_URL} { bind {$ADDRESS} reverse_proxy /ws/* http://lsp:3001 From 82afd486da226618bcc55bcd2c945d116d94d113 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 04:21:16 -0500 Subject: [PATCH 17/32] fix: Chatwoot Setup Service --- .../templates/chatwoot/docker-compose.yml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml index ef8e3ab1..d708e039 100644 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -1,6 +1,26 @@ version: "3.8" services: + setup: + image: chatwoot/chatwoot:v3.14.1 + networks: + - dokploy-network + environment: + - NODE_ENV=production + - RAILS_ENV=production + - POSTGRES_HOST=postgres + - POSTGRES_USERNAME=${POSTGRES_USERNAME} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DATABASE=chatwoot_production + - REDIS_URL=redis://redis:6379 + - REDIS_PASSWORD=${REDIS_PASSWORD} + command: bundle exec rails db:chatwoot_prepare + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + base: &base image: chatwoot/chatwoot:v3.14.1 volumes: From 7bef3a0c298e3bd45d3949d10840c2544999fbdd Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 04:26:21 -0500 Subject: [PATCH 18/32] fix: ActivePieces ENV --- .../templates/activepieces/docker-compose.yml | 11 +++++++++++ apps/dokploy/templates/activepieces/index.ts | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/apps/dokploy/templates/activepieces/docker-compose.yml b/apps/dokploy/templates/activepieces/docker-compose.yml index 4193b87a..92779bb6 100644 --- a/apps/dokploy/templates/activepieces/docker-compose.yml +++ b/apps/dokploy/templates/activepieces/docker-compose.yml @@ -19,6 +19,17 @@ services: - AP_POSTGRES_PORT=5432 - AP_REDIS_HOST=redis - AP_REDIS_PORT=6379 + - AP_ENVIRONMENT=prod + - AP_FRONTEND_URL=https://${AP_HOST} + - AP_ENCRYPTION_KEY=${AP_ENCRYPTION_KEY} + - AP_JWT_SECRET=${AP_JWT_SECRET} + - AP_ENGINE_EXECUTABLE_PATH=dist/packages/engine/main.js + - AP_EXECUTION_MODE=UNSANDBOXED + - AP_WEBHOOK_TIMEOUT_SECONDS=30 + - AP_TRIGGER_DEFAULT_POLL_INTERVAL=5 + - AP_FLOW_TIMEOUT_SECONDS=600 + - AP_TELEMETRY_ENABLED=true + - AP_TEMPLATES_SOURCE_URL="https://cloud.activepieces.com/api/v1/flow-templates" postgres: image: postgres:14.4 diff --git a/apps/dokploy/templates/activepieces/index.ts b/apps/dokploy/templates/activepieces/index.ts index 91a46cf6..b191bb52 100644 --- a/apps/dokploy/templates/activepieces/index.ts +++ b/apps/dokploy/templates/activepieces/index.ts @@ -2,13 +2,19 @@ import { type DomainSchema, type Schema, type Template, - generatePassword, + generateBase64, generateRandomDomain, } from "../utils"; export function generate(schema: Schema): Template { const mainDomain = generateRandomDomain(schema); - const postgresPassword = generatePassword(); + + + const apiKey = generateBase64(48); + const postgresPassword = generateBase64(24); + const jwtSecret = generateBase64(24); + const encryptionKey = generateBase64(12); + const postgresUser = "activepieces"; const postgresDb = "activepieces"; @@ -24,8 +30,10 @@ export function generate(schema: Schema): Template { `AP_POSTGRES_DATABASE=${postgresDb}`, `AP_POSTGRES_PASSWORD=${postgresPassword}`, `AP_POSTGRES_USERNAME=${postgresUser}`, - `AP_POSTGRES_PORT=5432`, - `AP_REDIS_PORT=6379`, + `AP_HOST=${mainDomain}`, + `AP_API_KEY=${apiKey}`, + `AP_ENCRYPTION_KEY=${encryptionKey}`, + `AP_JWT_SECRET=${jwtSecret}`, ]; return { From de315124c334bcda72280e88406077444ab36fbf Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 04:38:27 -0500 Subject: [PATCH 19/32] fix: Multiple Tests --- apps/dokploy/templates/activepieces/docker-compose.yml | 1 - apps/dokploy/templates/chatwoot/docker-compose.yml | 9 +++++++++ apps/dokploy/templates/windmill/docker-compose.yml | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/templates/activepieces/docker-compose.yml b/apps/dokploy/templates/activepieces/docker-compose.yml index 92779bb6..62906b2f 100644 --- a/apps/dokploy/templates/activepieces/docker-compose.yml +++ b/apps/dokploy/templates/activepieces/docker-compose.yml @@ -20,7 +20,6 @@ services: - AP_REDIS_HOST=redis - AP_REDIS_PORT=6379 - AP_ENVIRONMENT=prod - - AP_FRONTEND_URL=https://${AP_HOST} - AP_ENCRYPTION_KEY=${AP_ENCRYPTION_KEY} - AP_JWT_SECRET=${AP_JWT_SECRET} - AP_ENGINE_EXECUTABLE_PATH=dist/packages/engine/main.js diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml index d708e039..69547be5 100644 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -8,12 +8,21 @@ services: environment: - NODE_ENV=production - RAILS_ENV=production + - INSTALLATION_ENV=docker + - FRONTEND_URL=http://${CHATWOOT_HOST} + - SECRET_KEY_BASE=${SECRET_KEY_BASE} - POSTGRES_HOST=postgres - POSTGRES_USERNAME=${POSTGRES_USERNAME} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DATABASE=chatwoot_production - REDIS_URL=redis://redis:6379 - REDIS_PASSWORD=${REDIS_PASSWORD} + - ENABLE_ACCOUNT_SIGNUP=false + - FORCE_SSL=false + - RAILS_LOG_TO_STDOUT=true + - LOG_LEVEL=info + - LOG_SIZE=500 + - RAILS_MAX_THREADS=5 command: bundle exec rails db:chatwoot_prepare depends_on: postgres: diff --git a/apps/dokploy/templates/windmill/docker-compose.yml b/apps/dokploy/templates/windmill/docker-compose.yml index aea5d183..ab748a8f 100644 --- a/apps/dokploy/templates/windmill/docker-compose.yml +++ b/apps/dokploy/templates/windmill/docker-compose.yml @@ -93,7 +93,7 @@ services: networks: - dokploy-network volumes: - - ../files/stacks/windmill:/etc/caddy + - ../files/stacks:/etc/caddy environment: - BASE_URL=":80" depends_on: From cab9443d25d70a8c888fae63cc19eee0a7e1d2d9 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 04:44:13 -0500 Subject: [PATCH 20/32] fix: Remove LinkStack Removed due to https://docs.linkstack.org/docker/reverse-proxies/#traefik --- apps/dokploy/public/templates/linkstack.svg | 105 ------------------ .../templates/linkstack/docker-compose.yml | 49 -------- apps/dokploy/templates/linkstack/index.ts | 37 ------ apps/dokploy/templates/templates.ts | 14 --- 4 files changed, 205 deletions(-) delete mode 100644 apps/dokploy/public/templates/linkstack.svg delete mode 100644 apps/dokploy/templates/linkstack/docker-compose.yml delete mode 100644 apps/dokploy/templates/linkstack/index.ts diff --git a/apps/dokploy/public/templates/linkstack.svg b/apps/dokploy/public/templates/linkstack.svg deleted file mode 100644 index 775632d2..00000000 --- a/apps/dokploy/public/templates/linkstack.svg +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/apps/dokploy/templates/linkstack/docker-compose.yml b/apps/dokploy/templates/linkstack/docker-compose.yml deleted file mode 100644 index 2f54bf74..00000000 --- a/apps/dokploy/templates/linkstack/docker-compose.yml +++ /dev/null @@ -1,49 +0,0 @@ -version: "3.8" - -services: - linkstack: - image: linkstackorg/linkstack:latest - networks: - - dokploy-network - volumes: - - linkstack_data:/htdocs - environment: - - TZ=UTC - - SERVER_ADMIN=${LINKSTACK_SERVER_ADMIN} - - LOG_LEVEL=info - - PHP_MEMORY_LIMIT=256M - - UPLOAD_MAX_FILESIZE=8M - - DB_CONNECTION=mysql - - DB_HOST=mysql - - DB_PORT=3306 - - DB_DATABASE=${MYSQL_DATABASE} - - DB_USERNAME=${MYSQL_USER} - - DB_PASSWORD=${MYSQL_PASSWORD} - - FORCE_HTTPS=true - - APP_URL=https://${LINKSTACK_HOST} - depends_on: - mysql: - condition: service_healthy - restart: unless-stopped - - mysql: - image: mysql:8 - networks: - - dokploy-network - volumes: - - mysql_data:/var/lib/mysql - environment: - - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - - MYSQL_DATABASE=${MYSQL_DATABASE} - - MYSQL_USER=${MYSQL_USER} - - MYSQL_PASSWORD=${MYSQL_PASSWORD} - healthcheck: - test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u${MYSQL_USER}", "-p${MYSQL_PASSWORD}"] - interval: 10s - timeout: 5s - retries: 5 - restart: unless-stopped - -volumes: - linkstack_data: - mysql_data: \ No newline at end of file diff --git a/apps/dokploy/templates/linkstack/index.ts b/apps/dokploy/templates/linkstack/index.ts deleted file mode 100644 index af0858d6..00000000 --- a/apps/dokploy/templates/linkstack/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - type DomainSchema, - type Schema, - type Template, - generatePassword, - generateRandomDomain, -} from "../utils"; - -export function generate(schema: Schema): Template { - const mainDomain = generateRandomDomain(schema); - const mysqlRootPassword = generatePassword(); - const mysqlPassword = generatePassword(); - const mysqlUser = "linkstack"; - const mysqlDatabase = "linkstack"; - - const domains: DomainSchema[] = [ - { - host: mainDomain, - port: 443, - serviceName: "linkstack", - }, - ]; - - const envs = [ - `LINKSTACK_HOST=${mainDomain}`, - `LINKSTACK_SERVER_ADMIN=admin@example.com`, - `MYSQL_ROOT_PASSWORD=${mysqlRootPassword}`, - `MYSQL_DATABASE=${mysqlDatabase}`, - `MYSQL_USER=${mysqlUser}`, - `MYSQL_PASSWORD=${mysqlPassword}`, - ]; - - return { - domains, - envs, - }; -} \ No newline at end of file diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index d3ba44e8..e0711b75 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -786,20 +786,6 @@ export const templates: TemplateData[] = [ tags: ["bookmarks", "link-shortener", "self-hosted"], load: () => import("./slash/index").then((m) => m.generate), }, - { - id: "linkstack", - name: "LinkStack", - version: "latest", - description: "LinkStack is a highly customizable link sharing platform with an intuitive, easy to use user interface.", - logo: "linkstack.svg", - links: { - github: "https://github.com/LinkStackOrg/LinkStack", - website: "https://linkstack.org/", - docs: "https://docs.linkstack.org/", - }, - tags: ["links", "sharing", "social"], - load: () => import("./linkstack/index").then((m) => m.generate), - }, { id: "chatwoot", name: "Chatwoot", From b5fa411093ac35c51af7cc8ca5fd49ea9799f624 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 04:48:11 -0500 Subject: [PATCH 21/32] Add: Redis Password to AP --- apps/dokploy/templates/activepieces/docker-compose.yml | 6 ++++-- apps/dokploy/templates/activepieces/index.ts | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/dokploy/templates/activepieces/docker-compose.yml b/apps/dokploy/templates/activepieces/docker-compose.yml index 62906b2f..6ce10a13 100644 --- a/apps/dokploy/templates/activepieces/docker-compose.yml +++ b/apps/dokploy/templates/activepieces/docker-compose.yml @@ -19,7 +19,9 @@ services: - AP_POSTGRES_PORT=5432 - AP_REDIS_HOST=redis - AP_REDIS_PORT=6379 + - AP_REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379 - AP_ENVIRONMENT=prod + - AP_FRONTEND_URL=https://${AP_HOST} - AP_ENCRYPTION_KEY=${AP_ENCRYPTION_KEY} - AP_JWT_SECRET=${AP_JWT_SECRET} - AP_ENGINE_EXECUTABLE_PATH=dist/packages/engine/main.js @@ -49,13 +51,13 @@ services: redis: image: redis:7.0.7 - restart: unless-stopped + command: redis-server --requirepass ${REDIS_PASSWORD} networks: - dokploy-network volumes: - redis_data:/data healthcheck: - test: ["CMD", "redis-cli", "ping"] + test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] interval: 10s timeout: 5s retries: 5 diff --git a/apps/dokploy/templates/activepieces/index.ts b/apps/dokploy/templates/activepieces/index.ts index b191bb52..8757e83e 100644 --- a/apps/dokploy/templates/activepieces/index.ts +++ b/apps/dokploy/templates/activepieces/index.ts @@ -9,11 +9,11 @@ import { export function generate(schema: Schema): Template { const mainDomain = generateRandomDomain(schema); - const apiKey = generateBase64(48); const postgresPassword = generateBase64(24); const jwtSecret = generateBase64(24); const encryptionKey = generateBase64(12); + const redisPassword = generateBase64(24); const postgresUser = "activepieces"; const postgresDb = "activepieces"; @@ -34,6 +34,7 @@ export function generate(schema: Schema): Template { `AP_API_KEY=${apiKey}`, `AP_ENCRYPTION_KEY=${encryptionKey}`, `AP_JWT_SECRET=${jwtSecret}`, + `REDIS_PASSWORD=${redisPassword}`, ]; return { From 8900e30ae716523db7d0f056b0171789d2dc8a38 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 04:49:23 -0500 Subject: [PATCH 22/32] fix: Update Chatwoot Compose --- .../templates/chatwoot/docker-compose.yml | 81 ++++++++++--------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml index 69547be5..3edf2338 100644 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -1,6 +1,37 @@ version: "3.8" services: + postgres: + image: postgres:12 + networks: + - dokploy-network + volumes: + - postgres_data:/var/lib/postgresql/data + environment: + - POSTGRES_DB=chatwoot_production + - POSTGRES_USER=${POSTGRES_USERNAME} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USERNAME}"] + interval: 10s + timeout: 5s + retries: 5 + restart: always + + redis: + image: redis:alpine + networks: + - dokploy-network + command: ["sh", "-c", "redis-server --requirepass \"${REDIS_PASSWORD}\""] + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + restart: always + setup: image: chatwoot/chatwoot:v3.14.1 networks: @@ -23,23 +54,26 @@ services: - LOG_LEVEL=info - LOG_SIZE=500 - RAILS_MAX_THREADS=5 - command: bundle exec rails db:chatwoot_prepare + command: > + sh -c " + until PGPASSWORD=${POSTGRES_PASSWORD} psql -h postgres -U ${POSTGRES_USERNAME} -d chatwoot_production -c '\q'; do + echo 'Waiting for postgres...' + sleep 5 + done + echo 'PostgreSQL is ready!' + bundle exec rails db:chatwoot_prepare + " depends_on: postgres: condition: service_healthy redis: condition: service_healthy - base: &base - image: chatwoot/chatwoot:v3.14.1 - volumes: - - storage_data:/app/storage - networks: - - dokploy-network - rails: <<: *base depends_on: + setup: + condition: service_completed_successfully postgres: condition: service_healthy redis: @@ -109,37 +143,6 @@ services: command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml'] restart: always - postgres: - image: postgres:12 - networks: - - dokploy-network - volumes: - - postgres_data:/var/lib/postgresql/data - environment: - - POSTGRES_DB=chatwoot_production - - POSTGRES_USER=${POSTGRES_USERNAME} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USERNAME}"] - interval: 10s - timeout: 5s - retries: 5 - restart: always - - redis: - image: redis:alpine - networks: - - dokploy-network - command: ["sh", "-c", "redis-server --requirepass \"${REDIS_PASSWORD}\""] - volumes: - - redis_data:/data - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 10s - timeout: 5s - retries: 5 - restart: always - volumes: storage_data: postgres_data: From 06af2042ee372cb29e9c0970608f7935ef900810 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 05:06:42 -0500 Subject: [PATCH 23/32] fix: Testing ENV Variables --- apps/dokploy/templates/activepieces/index.ts | 14 +++++++++----- apps/dokploy/templates/chatwoot/docker-compose.yml | 11 ++++++++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/apps/dokploy/templates/activepieces/index.ts b/apps/dokploy/templates/activepieces/index.ts index 8757e83e..c15f3f78 100644 --- a/apps/dokploy/templates/activepieces/index.ts +++ b/apps/dokploy/templates/activepieces/index.ts @@ -9,14 +9,18 @@ import { export function generate(schema: Schema): Template { const mainDomain = generateRandomDomain(schema); - const apiKey = generateBase64(48); - const postgresPassword = generateBase64(24); - const jwtSecret = generateBase64(24); - const encryptionKey = generateBase64(12); - const redisPassword = generateBase64(24); + const apiKey = Array.from({length: 64}, () => + Math.floor(Math.random() * 16).toString(16)).join(''); + const postgresPassword = Array.from({length: 32}, () => + Math.floor(Math.random() * 16).toString(16)).join(''); + const jwtSecret = Array.from({length: 32}, () => + Math.floor(Math.random() * 16).toString(16)).join(''); + const encryptionKey = Array.from({length: 16}, () => + Math.floor(Math.random() * 16).toString(16)).join(''); const postgresUser = "activepieces"; const postgresDb = "activepieces"; + const redisPassword = generateBase64(24); const domains: DomainSchema[] = [ { diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml index 3edf2338..d55ae7a1 100644 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -1,6 +1,13 @@ version: "3.8" services: + base: &base + image: chatwoot/chatwoot:v3.14.1 + networks: + - dokploy-network + volumes: + - storage_data:/app/storage + postgres: image: postgres:12 networks: @@ -33,9 +40,7 @@ services: restart: always setup: - image: chatwoot/chatwoot:v3.14.1 - networks: - - dokploy-network + <<: *base environment: - NODE_ENV=production - RAILS_ENV=production From f1fc3f161aa9f2370d1bed7735635b68fbbb6ef6 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 05:07:15 -0500 Subject: [PATCH 24/32] Update index.ts --- apps/dokploy/templates/chatwoot/index.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/dokploy/templates/chatwoot/index.ts b/apps/dokploy/templates/chatwoot/index.ts index 599b82f5..0e051de2 100644 --- a/apps/dokploy/templates/chatwoot/index.ts +++ b/apps/dokploy/templates/chatwoot/index.ts @@ -9,7 +9,7 @@ import { export function generate(schema: Schema): Template { const mainDomain = generateRandomDomain(schema); - const postgresUsername = "chatwoot"; + const postgresUsername = "postgres"; const postgresPassword = generatePassword(); const redisPassword = generatePassword(); const secretKeyBase = generateBase64(64); @@ -23,15 +23,16 @@ export function generate(schema: Schema): Template { ]; const envs = [ - `CHATWOOT_HOST=${mainDomain}`, - `POSTGRES_USERNAME=${postgresUsername}`, + `POSTGRES_DB=chatwoot`, + `POSTGRES_USER=${postgresUsername}`, `POSTGRES_PASSWORD=${postgresPassword}`, `REDIS_PASSWORD=${redisPassword}`, + `CHATWOOT_HOST=${mainDomain}`, `SECRET_KEY_BASE=${secretKeyBase}`, - `SMTP_ADDRESS=${process.env.SMTP_ADDRESS || ''}`, - `SMTP_PORT=${process.env.SMTP_PORT || '587'}`, - `SMTP_USERNAME=${process.env.SMTP_USERNAME || ''}`, - `SMTP_PASSWORD=${process.env.SMTP_PASSWORD || ''}`, + `SMTP_ADDRESS=`, + `SMTP_PORT=587`, + `SMTP_USERNAME=`, + `SMTP_PASSWORD=`, ]; return { From 8157dd9eaac9c57ad833b70982f8864099ce610b Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 05:21:07 -0500 Subject: [PATCH 25/32] fix: More Config Fixes --- apps/dokploy/templates/activepieces/docker-compose.yml | 6 ++++-- apps/dokploy/templates/chatwoot/docker-compose.yml | 4 ++-- apps/dokploy/templates/chatwoot/index.ts | 6 +++--- apps/dokploy/templates/windmill/docker-compose.yml | 2 +- apps/dokploy/templates/windmill/index.ts | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/apps/dokploy/templates/activepieces/docker-compose.yml b/apps/dokploy/templates/activepieces/docker-compose.yml index 6ce10a13..1c303f41 100644 --- a/apps/dokploy/templates/activepieces/docker-compose.yml +++ b/apps/dokploy/templates/activepieces/docker-compose.yml @@ -12,14 +12,16 @@ services: redis: condition: service_healthy environment: + - AP_DB_TYPE=POSTGRES - AP_POSTGRES_DATABASE=${AP_POSTGRES_DATABASE} - AP_POSTGRES_PASSWORD=${AP_POSTGRES_PASSWORD} - AP_POSTGRES_USERNAME=${AP_POSTGRES_USERNAME} - AP_POSTGRES_HOST=postgres - AP_POSTGRES_PORT=5432 + - AP_QUEUE_MODE=REDIS - AP_REDIS_HOST=redis - AP_REDIS_PORT=6379 - - AP_REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379 + - AP_REDIS_PASSWORD=${REDIS_PASSWORD} - AP_ENVIRONMENT=prod - AP_FRONTEND_URL=https://${AP_HOST} - AP_ENCRYPTION_KEY=${AP_ENCRYPTION_KEY} @@ -30,7 +32,7 @@ services: - AP_TRIGGER_DEFAULT_POLL_INTERVAL=5 - AP_FLOW_TIMEOUT_SECONDS=600 - AP_TELEMETRY_ENABLED=true - - AP_TEMPLATES_SOURCE_URL="https://cloud.activepieces.com/api/v1/flow-templates" + - AP_TEMPLATES_SOURCE_URL=https://cloud.activepieces.com/api/v1/flow-templates postgres: image: postgres:14.4 diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml index d55ae7a1..9f6309ac 100644 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -16,10 +16,10 @@ services: - postgres_data:/var/lib/postgresql/data environment: - POSTGRES_DB=chatwoot_production - - POSTGRES_USER=${POSTGRES_USERNAME} + - POSTGRES_USER=postgres - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USERNAME}"] + test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 10s timeout: 5s retries: 5 diff --git a/apps/dokploy/templates/chatwoot/index.ts b/apps/dokploy/templates/chatwoot/index.ts index 0e051de2..b51fc520 100644 --- a/apps/dokploy/templates/chatwoot/index.ts +++ b/apps/dokploy/templates/chatwoot/index.ts @@ -9,7 +9,6 @@ import { export function generate(schema: Schema): Template { const mainDomain = generateRandomDomain(schema); - const postgresUsername = "postgres"; const postgresPassword = generatePassword(); const redisPassword = generatePassword(); const secretKeyBase = generateBase64(64); @@ -23,9 +22,10 @@ export function generate(schema: Schema): Template { ]; const envs = [ - `POSTGRES_DB=chatwoot`, - `POSTGRES_USER=${postgresUsername}`, + `POSTGRES_USERNAME=postgres`, + `POSTGRES_USER=postgres`, `POSTGRES_PASSWORD=${postgresPassword}`, + `POSTGRES_DB=chatwoot_production`, `REDIS_PASSWORD=${redisPassword}`, `CHATWOOT_HOST=${mainDomain}`, `SECRET_KEY_BASE=${secretKeyBase}`, diff --git a/apps/dokploy/templates/windmill/docker-compose.yml b/apps/dokploy/templates/windmill/docker-compose.yml index ab748a8f..5646c47a 100644 --- a/apps/dokploy/templates/windmill/docker-compose.yml +++ b/apps/dokploy/templates/windmill/docker-compose.yml @@ -93,7 +93,7 @@ services: networks: - dokploy-network volumes: - - ../files/stacks:/etc/caddy + - ../files/Caddyfile:/etc/caddy/Caddyfile environment: - BASE_URL=":80" depends_on: diff --git a/apps/dokploy/templates/windmill/index.ts b/apps/dokploy/templates/windmill/index.ts index 2e0a0a9f..44b1f37e 100644 --- a/apps/dokploy/templates/windmill/index.ts +++ b/apps/dokploy/templates/windmill/index.ts @@ -26,7 +26,7 @@ export function generate(schema: Schema): Template { const mounts: Template["mounts"] = [ { - filePath: "files/stacks/windmill/Caddyfile", + filePath: "Caddyfile", content: `{$BASE_URL} { bind {$ADDRESS} reverse_proxy /ws/* http://lsp:3001 From 9b7757326996ce5ffe46e176d78cbd4aa97bc029 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 05:32:05 -0500 Subject: [PATCH 26/32] fix: ENV Testing --- .../templates/activepieces/docker-compose.yml | 20 ++++++++--- apps/dokploy/templates/activepieces/index.ts | 20 +++++------ .../templates/chatwoot/docker-compose.yml | 33 +++---------------- apps/dokploy/templates/windmill/index.ts | 6 ++-- 4 files changed, 31 insertions(+), 48 deletions(-) diff --git a/apps/dokploy/templates/activepieces/docker-compose.yml b/apps/dokploy/templates/activepieces/docker-compose.yml index 1c303f41..abed5844 100644 --- a/apps/dokploy/templates/activepieces/docker-compose.yml +++ b/apps/dokploy/templates/activepieces/docker-compose.yml @@ -18,21 +18,31 @@ services: - AP_POSTGRES_USERNAME=${AP_POSTGRES_USERNAME} - AP_POSTGRES_HOST=postgres - AP_POSTGRES_PORT=5432 + - AP_POSTGRES_USE_SSL=false - AP_QUEUE_MODE=REDIS - AP_REDIS_HOST=redis - AP_REDIS_PORT=6379 - - AP_REDIS_PASSWORD=${REDIS_PASSWORD} + - AP_REDIS_PASSWORD=${AP_REDIS_PASSWORD} + - AP_REDIS_DB=0 + - AP_REDIS_USE_SSL=false - AP_ENVIRONMENT=prod - AP_FRONTEND_URL=https://${AP_HOST} - AP_ENCRYPTION_KEY=${AP_ENCRYPTION_KEY} - AP_JWT_SECRET=${AP_JWT_SECRET} - AP_ENGINE_EXECUTABLE_PATH=dist/packages/engine/main.js - AP_EXECUTION_MODE=UNSANDBOXED + - AP_FLOW_WORKER_CONCURRENCY=10 + - AP_SCHEDULED_WORKER_CONCURRENCY=10 + - AP_TELEMETRY_ENABLED=false + - AP_PIECES_SOURCE=DB + - AP_PIECES_SYNC_MODE=OFFICIAL_AUTO - AP_WEBHOOK_TIMEOUT_SECONDS=30 - AP_TRIGGER_DEFAULT_POLL_INTERVAL=5 - AP_FLOW_TIMEOUT_SECONDS=600 - - AP_TELEMETRY_ENABLED=true - - AP_TEMPLATES_SOURCE_URL=https://cloud.activepieces.com/api/v1/flow-templates + - AP_EXECUTION_DATA_RETENTION_DAYS=30 + - AP_PROJECT_RATE_LIMITER_ENABLED=true + - AP_MAX_CONCURRENT_JOBS_PER_PROJECT=100 + - AP_FILE_STORAGE_LOCATION=DB postgres: image: postgres:14.4 @@ -53,13 +63,13 @@ services: redis: image: redis:7.0.7 - command: redis-server --requirepass ${REDIS_PASSWORD} + command: redis-server --requirepass ${AP_REDIS_PASSWORD} networks: - dokploy-network volumes: - redis_data:/data healthcheck: - test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] + test: ["CMD", "redis-cli", "-a", "${AP_REDIS_PASSWORD}", "ping"] interval: 10s timeout: 5s retries: 5 diff --git a/apps/dokploy/templates/activepieces/index.ts b/apps/dokploy/templates/activepieces/index.ts index c15f3f78..b11df36d 100644 --- a/apps/dokploy/templates/activepieces/index.ts +++ b/apps/dokploy/templates/activepieces/index.ts @@ -9,18 +9,16 @@ import { export function generate(schema: Schema): Template { const mainDomain = generateRandomDomain(schema); - const apiKey = Array.from({length: 64}, () => - Math.floor(Math.random() * 16).toString(16)).join(''); - const postgresPassword = Array.from({length: 32}, () => + const encryptionKey = Array.from({length: 16}, () => Math.floor(Math.random() * 16).toString(16)).join(''); const jwtSecret = Array.from({length: 32}, () => Math.floor(Math.random() * 16).toString(16)).join(''); - const encryptionKey = Array.from({length: 16}, () => + const postgresPassword = Array.from({length: 32}, () => Math.floor(Math.random() * 16).toString(16)).join(''); - + const redisPassword = generateBase64(32); + const postgresUser = "activepieces"; const postgresDb = "activepieces"; - const redisPassword = generateBase64(24); const domains: DomainSchema[] = [ { @@ -31,14 +29,14 @@ export function generate(schema: Schema): Template { ]; const envs = [ + `AP_HOST=${mainDomain}`, + `AP_FRONTEND_URL=https://${mainDomain}`, + `AP_ENCRYPTION_KEY=${encryptionKey}`, + `AP_JWT_SECRET=${jwtSecret}`, `AP_POSTGRES_DATABASE=${postgresDb}`, `AP_POSTGRES_PASSWORD=${postgresPassword}`, `AP_POSTGRES_USERNAME=${postgresUser}`, - `AP_HOST=${mainDomain}`, - `AP_API_KEY=${apiKey}`, - `AP_ENCRYPTION_KEY=${encryptionKey}`, - `AP_JWT_SECRET=${jwtSecret}`, - `REDIS_PASSWORD=${redisPassword}`, + `AP_REDIS_PASSWORD=${redisPassword}`, ]; return { diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml index 9f6309ac..cf20a46a 100644 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -48,7 +48,7 @@ services: - FRONTEND_URL=http://${CHATWOOT_HOST} - SECRET_KEY_BASE=${SECRET_KEY_BASE} - POSTGRES_HOST=postgres - - POSTGRES_USERNAME=${POSTGRES_USERNAME} + - POSTGRES_USERNAME=postgres - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DATABASE=chatwoot_production - REDIS_URL=redis://redis:6379 @@ -56,12 +56,9 @@ services: - ENABLE_ACCOUNT_SIGNUP=false - FORCE_SSL=false - RAILS_LOG_TO_STDOUT=true - - LOG_LEVEL=info - - LOG_SIZE=500 - - RAILS_MAX_THREADS=5 command: > sh -c " - until PGPASSWORD=${POSTGRES_PASSWORD} psql -h postgres -U ${POSTGRES_USERNAME} -d chatwoot_production -c '\q'; do + until PGPASSWORD=${POSTGRES_PASSWORD} psql -h postgres -U postgres -d chatwoot_production -c '\q'; do echo 'Waiting for postgres...' sleep 5 done @@ -90,25 +87,14 @@ services: - FRONTEND_URL=http://${CHATWOOT_HOST} - SECRET_KEY_BASE=${SECRET_KEY_BASE} - POSTGRES_HOST=postgres - - POSTGRES_USERNAME=${POSTGRES_USERNAME} + - POSTGRES_USERNAME=postgres - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DATABASE=chatwoot_production - REDIS_URL=redis://redis:6379 - REDIS_PASSWORD=${REDIS_PASSWORD} - ENABLE_ACCOUNT_SIGNUP=false - - MAILER_SENDER_EMAIL=Chatwoot - FORCE_SSL=false - RAILS_LOG_TO_STDOUT=true - - LOG_LEVEL=info - - LOG_SIZE=500 - - RAILS_MAX_THREADS=5 - - SMTP_DOMAIN=${CHATWOOT_HOST} - - SMTP_ADDRESS=${SMTP_ADDRESS} - - SMTP_PORT=${SMTP_PORT} - - SMTP_USERNAME=${SMTP_USERNAME} - - SMTP_PASSWORD=${SMTP_PASSWORD} - - SMTP_AUTHENTICATION=plain - - SMTP_ENABLE_STARTTLS_AUTO=true entrypoint: docker/entrypoints/rails.sh command: ['bundle', 'exec', 'rails', 's', '-p', '3000', '-b', '0.0.0.0'] restart: always @@ -127,24 +113,13 @@ services: - FRONTEND_URL=http://${CHATWOOT_HOST} - SECRET_KEY_BASE=${SECRET_KEY_BASE} - POSTGRES_HOST=postgres - - POSTGRES_USERNAME=${POSTGRES_USERNAME} + - POSTGRES_USERNAME=postgres - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DATABASE=chatwoot_production - REDIS_URL=redis://redis:6379 - REDIS_PASSWORD=${REDIS_PASSWORD} - FORCE_SSL=false - RAILS_LOG_TO_STDOUT=true - - LOG_LEVEL=info - - LOG_SIZE=500 - - RAILS_MAX_THREADS=5 - - SMTP_DOMAIN=${CHATWOOT_HOST} - - SMTP_ADDRESS=${SMTP_ADDRESS} - - SMTP_PORT=${SMTP_PORT} - - SMTP_USERNAME=${SMTP_USERNAME} - - SMTP_PASSWORD=${SMTP_PASSWORD} - - SMTP_AUTHENTICATION=plain - - SMTP_ENABLE_STARTTLS_AUTO=true - - MAILER_SENDER_EMAIL=Chatwoot command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml'] restart: always diff --git a/apps/dokploy/templates/windmill/index.ts b/apps/dokploy/templates/windmill/index.ts index 44b1f37e..875b7afa 100644 --- a/apps/dokploy/templates/windmill/index.ts +++ b/apps/dokploy/templates/windmill/index.ts @@ -27,11 +27,11 @@ export function generate(schema: Schema): Template { const mounts: Template["mounts"] = [ { filePath: "Caddyfile", - content: `{$BASE_URL} { - bind {$ADDRESS} + content: `:80 { + bind 0.0.0.0 reverse_proxy /ws/* http://lsp:3001 reverse_proxy /* http://windmill_server:8000 -}` +}`, }, ]; From 444302e7b9edd6398ba5d3d53ee095fe297f7e20 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 05:33:37 -0500 Subject: [PATCH 27/32] fix: chatwoot ENV --- .../dokploy/templates/chatwoot/docker-compose.yml | 8 ++++---- apps/dokploy/templates/chatwoot/index.ts | 15 ++++----------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml index cf20a46a..9d062437 100644 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -19,7 +19,7 @@ services: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] + test: ["CMD-SHELL", "pg_isready -U postgres -h localhost -d chatwoot_production"] interval: 10s timeout: 5s retries: 5 @@ -58,9 +58,9 @@ services: - RAILS_LOG_TO_STDOUT=true command: > sh -c " - until PGPASSWORD=${POSTGRES_PASSWORD} psql -h postgres -U postgres -d chatwoot_production -c '\q'; do - echo 'Waiting for postgres...' - sleep 5 + echo 'Waiting for postgres...' + while ! PGPASSWORD='${POSTGRES_PASSWORD}' psql -h postgres -U postgres -d chatwoot_production -c 'SELECT 1' > /dev/null 2>&1; do + sleep 1 done echo 'PostgreSQL is ready!' bundle exec rails db:chatwoot_prepare diff --git a/apps/dokploy/templates/chatwoot/index.ts b/apps/dokploy/templates/chatwoot/index.ts index b51fc520..234b802a 100644 --- a/apps/dokploy/templates/chatwoot/index.ts +++ b/apps/dokploy/templates/chatwoot/index.ts @@ -2,9 +2,9 @@ import { type DomainSchema, type Schema, type Template, - generatePassword, - generateRandomDomain, generateBase64, + generateRandomDomain, + generatePassword, } from "../utils"; export function generate(schema: Schema): Template { @@ -22,17 +22,10 @@ export function generate(schema: Schema): Template { ]; const envs = [ - `POSTGRES_USERNAME=postgres`, - `POSTGRES_USER=postgres`, - `POSTGRES_PASSWORD=${postgresPassword}`, - `POSTGRES_DB=chatwoot_production`, - `REDIS_PASSWORD=${redisPassword}`, `CHATWOOT_HOST=${mainDomain}`, + `POSTGRES_PASSWORD=${postgresPassword}`, + `REDIS_PASSWORD=${redisPassword}`, `SECRET_KEY_BASE=${secretKeyBase}`, - `SMTP_ADDRESS=`, - `SMTP_PORT=587`, - `SMTP_USERNAME=`, - `SMTP_PASSWORD=`, ]; return { From 6866c3b116922d07898c67a81f5b2760bdba2fdd Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 05:40:19 -0500 Subject: [PATCH 28/32] fix: Envs --- apps/dokploy/templates/activepieces/index.ts | 4 +- .../templates/chatwoot/docker-compose.yml | 97 ++++++++++--------- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/apps/dokploy/templates/activepieces/index.ts b/apps/dokploy/templates/activepieces/index.ts index b11df36d..575ee8cd 100644 --- a/apps/dokploy/templates/activepieces/index.ts +++ b/apps/dokploy/templates/activepieces/index.ts @@ -2,7 +2,6 @@ import { type DomainSchema, type Schema, type Template, - generateBase64, generateRandomDomain, } from "../utils"; @@ -15,7 +14,8 @@ export function generate(schema: Schema): Template { Math.floor(Math.random() * 16).toString(16)).join(''); const postgresPassword = Array.from({length: 32}, () => Math.floor(Math.random() * 16).toString(16)).join(''); - const redisPassword = generateBase64(32); + const redisPassword = Array.from({length: 32}, () => + Math.floor(Math.random() * 16).toString(16)).join(''); const postgresUser = "activepieces"; const postgresDb = "activepieces"; diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml index 9d062437..e4b45d29 100644 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -15,9 +15,9 @@ services: volumes: - postgres_data:/var/lib/postgresql/data environment: - - POSTGRES_DB=chatwoot_production - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + POSTGRES_DB: chatwoot_production + POSTGRES_USER: postgres + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -h localhost -d chatwoot_production"] interval: 10s @@ -29,11 +29,11 @@ services: image: redis:alpine networks: - dokploy-network - command: ["sh", "-c", "redis-server --requirepass \"${REDIS_PASSWORD}\""] + command: redis-server --requirepass ${REDIS_PASSWORD} volumes: - redis_data:/data healthcheck: - test: ["CMD", "redis-cli", "ping"] + test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] interval: 10s timeout: 5s retries: 5 @@ -42,25 +42,26 @@ services: setup: <<: *base environment: - - NODE_ENV=production - - RAILS_ENV=production - - INSTALLATION_ENV=docker - - FRONTEND_URL=http://${CHATWOOT_HOST} - - SECRET_KEY_BASE=${SECRET_KEY_BASE} - - POSTGRES_HOST=postgres - - POSTGRES_USERNAME=postgres - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_DATABASE=chatwoot_production - - REDIS_URL=redis://redis:6379 - - REDIS_PASSWORD=${REDIS_PASSWORD} - - ENABLE_ACCOUNT_SIGNUP=false - - FORCE_SSL=false - - RAILS_LOG_TO_STDOUT=true + NODE_ENV: production + RAILS_ENV: production + INSTALLATION_ENV: docker + FRONTEND_URL: http://${CHATWOOT_HOST} + SECRET_KEY_BASE: ${SECRET_KEY_BASE} + POSTGRES_HOST: postgres + POSTGRES_USER: postgres + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: chatwoot_production + REDIS_URL: redis://redis:6379 + REDIS_PASSWORD: ${REDIS_PASSWORD} + ENABLE_ACCOUNT_SIGNUP: "false" + FORCE_SSL: "false" + RAILS_LOG_TO_STDOUT: "true" command: > sh -c " echo 'Waiting for postgres...' - while ! PGPASSWORD='${POSTGRES_PASSWORD}' psql -h postgres -U postgres -d chatwoot_production -c 'SELECT 1' > /dev/null 2>&1; do - sleep 1 + until PGPASSWORD=${POSTGRES_PASSWORD} psql -h postgres -U postgres -d chatwoot_production -c '\q' > /dev/null 2>&1; do + sleep 5 + echo 'Waiting for postgres...' done echo 'PostgreSQL is ready!' bundle exec rails db:chatwoot_prepare @@ -81,20 +82,20 @@ services: redis: condition: service_healthy environment: - - NODE_ENV=production - - RAILS_ENV=production - - INSTALLATION_ENV=docker - - FRONTEND_URL=http://${CHATWOOT_HOST} - - SECRET_KEY_BASE=${SECRET_KEY_BASE} - - POSTGRES_HOST=postgres - - POSTGRES_USERNAME=postgres - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_DATABASE=chatwoot_production - - REDIS_URL=redis://redis:6379 - - REDIS_PASSWORD=${REDIS_PASSWORD} - - ENABLE_ACCOUNT_SIGNUP=false - - FORCE_SSL=false - - RAILS_LOG_TO_STDOUT=true + NODE_ENV: production + RAILS_ENV: production + INSTALLATION_ENV: docker + FRONTEND_URL: http://${CHATWOOT_HOST} + SECRET_KEY_BASE: ${SECRET_KEY_BASE} + POSTGRES_HOST: postgres + POSTGRES_USER: postgres + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: chatwoot_production + REDIS_URL: redis://redis:6379 + REDIS_PASSWORD: ${REDIS_PASSWORD} + ENABLE_ACCOUNT_SIGNUP: "false" + FORCE_SSL: "false" + RAILS_LOG_TO_STDOUT: "true" entrypoint: docker/entrypoints/rails.sh command: ['bundle', 'exec', 'rails', 's', '-p', '3000', '-b', '0.0.0.0'] restart: always @@ -107,19 +108,19 @@ services: redis: condition: service_healthy environment: - - NODE_ENV=production - - RAILS_ENV=production - - INSTALLATION_ENV=docker - - FRONTEND_URL=http://${CHATWOOT_HOST} - - SECRET_KEY_BASE=${SECRET_KEY_BASE} - - POSTGRES_HOST=postgres - - POSTGRES_USERNAME=postgres - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_DATABASE=chatwoot_production - - REDIS_URL=redis://redis:6379 - - REDIS_PASSWORD=${REDIS_PASSWORD} - - FORCE_SSL=false - - RAILS_LOG_TO_STDOUT=true + NODE_ENV: production + RAILS_ENV: production + INSTALLATION_ENV: docker + FRONTEND_URL: http://${CHATWOOT_HOST} + SECRET_KEY_BASE: ${SECRET_KEY_BASE} + POSTGRES_HOST: postgres + POSTGRES_USER: postgres + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: chatwoot_production + REDIS_URL: redis://redis:6379 + REDIS_PASSWORD: ${REDIS_PASSWORD} + FORCE_SSL: "false" + RAILS_LOG_TO_STDOUT: "true" command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml'] restart: always From a5c1f8ef4909713b362d522a31c94f065c68f916 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 05:45:16 -0500 Subject: [PATCH 29/32] fix: AP Env Testing --- .../templates/activepieces/docker-compose.yml | 80 ++++++++----------- apps/dokploy/templates/activepieces/index.ts | 14 +--- 2 files changed, 38 insertions(+), 56 deletions(-) diff --git a/apps/dokploy/templates/activepieces/docker-compose.yml b/apps/dokploy/templates/activepieces/docker-compose.yml index abed5844..e990379b 100644 --- a/apps/dokploy/templates/activepieces/docker-compose.yml +++ b/apps/dokploy/templates/activepieces/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.8" services: activepieces: - image: ghcr.io/activepieces/activepieces:0.35.0 + image: activepieces/activepieces:0.35.0 restart: unless-stopped networks: - dokploy-network @@ -12,67 +12,55 @@ services: redis: condition: service_healthy environment: - - AP_DB_TYPE=POSTGRES - - AP_POSTGRES_DATABASE=${AP_POSTGRES_DATABASE} - - AP_POSTGRES_PASSWORD=${AP_POSTGRES_PASSWORD} - - AP_POSTGRES_USERNAME=${AP_POSTGRES_USERNAME} - - AP_POSTGRES_HOST=postgres - - AP_POSTGRES_PORT=5432 - - AP_POSTGRES_USE_SSL=false - - AP_QUEUE_MODE=REDIS - - AP_REDIS_HOST=redis - - AP_REDIS_PORT=6379 - - AP_REDIS_PASSWORD=${AP_REDIS_PASSWORD} - - AP_REDIS_DB=0 - - AP_REDIS_USE_SSL=false - - AP_ENVIRONMENT=prod - - AP_FRONTEND_URL=https://${AP_HOST} - - AP_ENCRYPTION_KEY=${AP_ENCRYPTION_KEY} - - AP_JWT_SECRET=${AP_JWT_SECRET} - - AP_ENGINE_EXECUTABLE_PATH=dist/packages/engine/main.js - - AP_EXECUTION_MODE=UNSANDBOXED - - AP_FLOW_WORKER_CONCURRENCY=10 - - AP_SCHEDULED_WORKER_CONCURRENCY=10 - - AP_TELEMETRY_ENABLED=false - - AP_PIECES_SOURCE=DB - - AP_PIECES_SYNC_MODE=OFFICIAL_AUTO - - AP_WEBHOOK_TIMEOUT_SECONDS=30 - - AP_TRIGGER_DEFAULT_POLL_INTERVAL=5 - - AP_FLOW_TIMEOUT_SECONDS=600 - - AP_EXECUTION_DATA_RETENTION_DAYS=30 - - AP_PROJECT_RATE_LIMITER_ENABLED=true - - AP_MAX_CONCURRENT_JOBS_PER_PROJECT=100 - - AP_FILE_STORAGE_LOCATION=DB + 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.4 + image: postgres:14 restart: unless-stopped networks: - dokploy-network environment: - - POSTGRES_DB=${AP_POSTGRES_DATABASE} - - POSTGRES_PASSWORD=${AP_POSTGRES_PASSWORD} - - POSTGRES_USER=${AP_POSTGRES_USERNAME} + 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 ${AP_POSTGRES_USERNAME}"] - interval: 10s - timeout: 5s - retries: 5 + test: ["CMD-SHELL", "pg_isready -U activepieces -d activepieces"] + interval: 30s + timeout: 30s + retries: 3 redis: - image: redis:7.0.7 - command: redis-server --requirepass ${AP_REDIS_PASSWORD} + image: redis:7 + restart: unless-stopped networks: - dokploy-network volumes: - redis_data:/data healthcheck: - test: ["CMD", "redis-cli", "-a", "${AP_REDIS_PASSWORD}", "ping"] - interval: 10s - timeout: 5s - retries: 5 + test: ["CMD", "redis-cli", "ping"] + interval: 30s + timeout: 30s + retries: 3 volumes: postgres_data: diff --git a/apps/dokploy/templates/activepieces/index.ts b/apps/dokploy/templates/activepieces/index.ts index 575ee8cd..60f8981f 100644 --- a/apps/dokploy/templates/activepieces/index.ts +++ b/apps/dokploy/templates/activepieces/index.ts @@ -8,17 +8,14 @@ import { export function generate(schema: Schema): Template { const mainDomain = generateRandomDomain(schema); - const encryptionKey = Array.from({length: 16}, () => + const apiKey = Array.from({length: 32}, () => + Math.floor(Math.random() * 16).toString(16)).join(''); + const encryptionKey = Array.from({length: 32}, () => Math.floor(Math.random() * 16).toString(16)).join(''); const jwtSecret = Array.from({length: 32}, () => Math.floor(Math.random() * 16).toString(16)).join(''); const postgresPassword = Array.from({length: 32}, () => Math.floor(Math.random() * 16).toString(16)).join(''); - const redisPassword = Array.from({length: 32}, () => - Math.floor(Math.random() * 16).toString(16)).join(''); - - const postgresUser = "activepieces"; - const postgresDb = "activepieces"; const domains: DomainSchema[] = [ { @@ -30,13 +27,10 @@ export function generate(schema: Schema): Template { const envs = [ `AP_HOST=${mainDomain}`, - `AP_FRONTEND_URL=https://${mainDomain}`, + `AP_API_KEY=${apiKey}`, `AP_ENCRYPTION_KEY=${encryptionKey}`, `AP_JWT_SECRET=${jwtSecret}`, - `AP_POSTGRES_DATABASE=${postgresDb}`, `AP_POSTGRES_PASSWORD=${postgresPassword}`, - `AP_POSTGRES_USERNAME=${postgresUser}`, - `AP_REDIS_PASSWORD=${redisPassword}`, ]; return { From fa791706a09e6c8413e69b79e239b2ffed8875ed Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 13 Nov 2024 05:49:07 -0500 Subject: [PATCH 30/32] fix: chatwoot DB --- .../templates/chatwoot/docker-compose.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml index e4b45d29..f1b2d2c6 100644 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ b/apps/dokploy/templates/chatwoot/docker-compose.yml @@ -16,10 +16,10 @@ services: - postgres_data:/var/lib/postgresql/data environment: POSTGRES_DB: chatwoot_production - POSTGRES_USER: postgres + POSTGRES_USER: admin POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres -h localhost -d chatwoot_production"] + test: ["CMD-SHELL", "pg_isready -U admin -h localhost -d chatwoot_production"] interval: 10s timeout: 5s retries: 5 @@ -48,9 +48,9 @@ services: FRONTEND_URL: http://${CHATWOOT_HOST} SECRET_KEY_BASE: ${SECRET_KEY_BASE} POSTGRES_HOST: postgres - POSTGRES_USER: postgres + POSTGRES_USERNAME: admin POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DB: chatwoot_production + POSTGRES_DATABASE: chatwoot_production REDIS_URL: redis://redis:6379 REDIS_PASSWORD: ${REDIS_PASSWORD} ENABLE_ACCOUNT_SIGNUP: "false" @@ -59,7 +59,7 @@ services: command: > sh -c " echo 'Waiting for postgres...' - until PGPASSWORD=${POSTGRES_PASSWORD} psql -h postgres -U postgres -d chatwoot_production -c '\q' > /dev/null 2>&1; do + until PGPASSWORD=${POSTGRES_PASSWORD} psql -h postgres -U admin -d chatwoot_production -c '\q' > /dev/null 2>&1; do sleep 5 echo 'Waiting for postgres...' done @@ -88,9 +88,9 @@ services: FRONTEND_URL: http://${CHATWOOT_HOST} SECRET_KEY_BASE: ${SECRET_KEY_BASE} POSTGRES_HOST: postgres - POSTGRES_USER: postgres + POSTGRES_USERNAME: admin POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DB: chatwoot_production + POSTGRES_DATABASE: chatwoot_production REDIS_URL: redis://redis:6379 REDIS_PASSWORD: ${REDIS_PASSWORD} ENABLE_ACCOUNT_SIGNUP: "false" @@ -114,9 +114,9 @@ services: FRONTEND_URL: http://${CHATWOOT_HOST} SECRET_KEY_BASE: ${SECRET_KEY_BASE} POSTGRES_HOST: postgres - POSTGRES_USER: postgres + POSTGRES_USERNAME: admin POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DB: chatwoot_production + POSTGRES_DATABASE: chatwoot_production REDIS_URL: redis://redis:6379 REDIS_PASSWORD: ${REDIS_PASSWORD} FORCE_SSL: "false" From 70ca219c0abb50d69fdce56581f37e89839d1697 Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Sun, 17 Nov 2024 11:12:45 -0500 Subject: [PATCH 31/32] Remove Chatwoot --- apps/dokploy/public/templates/chatwoot.svg | 3 - .../templates/chatwoot/docker-compose.yml | 130 ------------------ apps/dokploy/templates/chatwoot/index.ts | 35 ----- apps/dokploy/templates/templates.ts | 14 -- 4 files changed, 182 deletions(-) delete mode 100644 apps/dokploy/public/templates/chatwoot.svg delete mode 100644 apps/dokploy/templates/chatwoot/docker-compose.yml delete mode 100644 apps/dokploy/templates/chatwoot/index.ts diff --git a/apps/dokploy/public/templates/chatwoot.svg b/apps/dokploy/public/templates/chatwoot.svg deleted file mode 100644 index 56c9a7b8..00000000 --- a/apps/dokploy/public/templates/chatwoot.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/apps/dokploy/templates/chatwoot/docker-compose.yml b/apps/dokploy/templates/chatwoot/docker-compose.yml deleted file mode 100644 index f1b2d2c6..00000000 --- a/apps/dokploy/templates/chatwoot/docker-compose.yml +++ /dev/null @@ -1,130 +0,0 @@ -version: "3.8" - -services: - base: &base - image: chatwoot/chatwoot:v3.14.1 - networks: - - dokploy-network - volumes: - - storage_data:/app/storage - - postgres: - image: postgres:12 - networks: - - dokploy-network - volumes: - - postgres_data:/var/lib/postgresql/data - environment: - POSTGRES_DB: chatwoot_production - POSTGRES_USER: admin - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - healthcheck: - test: ["CMD-SHELL", "pg_isready -U admin -h localhost -d chatwoot_production"] - interval: 10s - timeout: 5s - retries: 5 - restart: always - - redis: - image: redis:alpine - networks: - - dokploy-network - command: redis-server --requirepass ${REDIS_PASSWORD} - volumes: - - redis_data:/data - healthcheck: - test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] - interval: 10s - timeout: 5s - retries: 5 - restart: always - - setup: - <<: *base - environment: - NODE_ENV: production - RAILS_ENV: production - INSTALLATION_ENV: docker - FRONTEND_URL: http://${CHATWOOT_HOST} - SECRET_KEY_BASE: ${SECRET_KEY_BASE} - POSTGRES_HOST: postgres - POSTGRES_USERNAME: admin - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DATABASE: chatwoot_production - REDIS_URL: redis://redis:6379 - REDIS_PASSWORD: ${REDIS_PASSWORD} - ENABLE_ACCOUNT_SIGNUP: "false" - FORCE_SSL: "false" - RAILS_LOG_TO_STDOUT: "true" - command: > - sh -c " - echo 'Waiting for postgres...' - until PGPASSWORD=${POSTGRES_PASSWORD} psql -h postgres -U admin -d chatwoot_production -c '\q' > /dev/null 2>&1; do - sleep 5 - echo 'Waiting for postgres...' - done - echo 'PostgreSQL is ready!' - bundle exec rails db:chatwoot_prepare - " - depends_on: - postgres: - condition: service_healthy - redis: - condition: service_healthy - - rails: - <<: *base - depends_on: - setup: - condition: service_completed_successfully - postgres: - condition: service_healthy - redis: - condition: service_healthy - environment: - NODE_ENV: production - RAILS_ENV: production - INSTALLATION_ENV: docker - FRONTEND_URL: http://${CHATWOOT_HOST} - SECRET_KEY_BASE: ${SECRET_KEY_BASE} - POSTGRES_HOST: postgres - POSTGRES_USERNAME: admin - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DATABASE: chatwoot_production - REDIS_URL: redis://redis:6379 - REDIS_PASSWORD: ${REDIS_PASSWORD} - ENABLE_ACCOUNT_SIGNUP: "false" - FORCE_SSL: "false" - RAILS_LOG_TO_STDOUT: "true" - entrypoint: docker/entrypoints/rails.sh - command: ['bundle', 'exec', 'rails', 's', '-p', '3000', '-b', '0.0.0.0'] - restart: always - - sidekiq: - <<: *base - depends_on: - postgres: - condition: service_healthy - redis: - condition: service_healthy - environment: - NODE_ENV: production - RAILS_ENV: production - INSTALLATION_ENV: docker - FRONTEND_URL: http://${CHATWOOT_HOST} - SECRET_KEY_BASE: ${SECRET_KEY_BASE} - POSTGRES_HOST: postgres - POSTGRES_USERNAME: admin - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DATABASE: chatwoot_production - REDIS_URL: redis://redis:6379 - REDIS_PASSWORD: ${REDIS_PASSWORD} - FORCE_SSL: "false" - RAILS_LOG_TO_STDOUT: "true" - command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml'] - restart: always - -volumes: - storage_data: - postgres_data: - redis_data: \ No newline at end of file diff --git a/apps/dokploy/templates/chatwoot/index.ts b/apps/dokploy/templates/chatwoot/index.ts deleted file mode 100644 index 234b802a..00000000 --- a/apps/dokploy/templates/chatwoot/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - type DomainSchema, - type Schema, - type Template, - generateBase64, - generateRandomDomain, - generatePassword, -} from "../utils"; - -export function generate(schema: Schema): Template { - const mainDomain = generateRandomDomain(schema); - const postgresPassword = generatePassword(); - const redisPassword = generatePassword(); - const secretKeyBase = generateBase64(64); - - const domains: DomainSchema[] = [ - { - host: mainDomain, - port: 3000, - serviceName: "rails", - }, - ]; - - const envs = [ - `CHATWOOT_HOST=${mainDomain}`, - `POSTGRES_PASSWORD=${postgresPassword}`, - `REDIS_PASSWORD=${redisPassword}`, - `SECRET_KEY_BASE=${secretKeyBase}`, - ]; - - return { - domains, - envs, - }; -} \ No newline at end of file diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index e0711b75..df2d77f5 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -786,20 +786,6 @@ export const templates: TemplateData[] = [ tags: ["bookmarks", "link-shortener", "self-hosted"], load: () => import("./slash/index").then((m) => m.generate), }, - { - id: "chatwoot", - name: "Chatwoot", - version: "v3.14.1", - description: "Open-source customer engagement suite, an alternative to Intercom, Zendesk, Salesforce Service Cloud etc.", - logo: "chatwoot.svg", - links: { - github: "https://github.com/chatwoot/chatwoot", - website: "https://www.chatwoot.com", - docs: "https://www.chatwoot.com/docs", - }, - tags: ["customer-support", "live-chat", "helpdesk"], - load: () => import("./chatwoot/index").then((m) => m.generate), - }, { id: "discord-tickets", name: "Discord Tickets", From 01a882497fa5156f3ee9c4d04f4cbd603611160c Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Sun, 17 Nov 2024 11:47:05 -0500 Subject: [PATCH 32/32] Add: Discord Tickets Logo --- .../public/templates/discord-tickets.png | Bin 0 -> 15188 bytes apps/dokploy/templates/templates.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 apps/dokploy/public/templates/discord-tickets.png diff --git a/apps/dokploy/public/templates/discord-tickets.png b/apps/dokploy/public/templates/discord-tickets.png new file mode 100644 index 0000000000000000000000000000000000000000..030c3a4ca194bd1eeb8fcce764b4decdf460f32b GIT binary patch literal 15188 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%0Autt5=9a&?ax0<_MN}TCwjq+3H7b}^< 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