From 2eeb4017acb4c454373e0c4d1845ae3aea12e59f Mon Sep 17 00:00:00 2001 From: DrMxrcy Date: Wed, 20 Nov 2024 11:12:31 -0500 Subject: [PATCH] feat(add): Twenty CRM --- apps/dokploy/public/templates/twenty.svg | 6 ++ apps/dokploy/templates/templates.ts | 15 +++ .../templates/twenty/docker-compose.yml | 98 +++++++++++++++++++ apps/dokploy/templates/twenty/index.ts | 37 +++++++ 4 files changed, 156 insertions(+) create mode 100644 apps/dokploy/public/templates/twenty.svg create mode 100644 apps/dokploy/templates/twenty/docker-compose.yml create mode 100644 apps/dokploy/templates/twenty/index.ts diff --git a/apps/dokploy/public/templates/twenty.svg b/apps/dokploy/public/templates/twenty.svg new file mode 100644 index 000000000..cf5223b96 --- /dev/null +++ b/apps/dokploy/public/templates/twenty.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index 46806a8a3..b5a57dc55 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -867,4 +867,19 @@ export const templates: TemplateData[] = [ tags: ["support", "chat", "customer-service"], load: () => import("./chatwoot/index").then((m) => m.generate), }, + { + id: "twenty", + name: "Twenty CRM", + version: "latest", + description: + "Twenty is a modern CRM offering a powerful spreadsheet interface and open-source alternative to Salesforce.", + logo: "twenty.svg", + links: { + github: "https://github.com/twentyhq/twenty", + website: "https://twenty.com", + docs: "https://docs.twenty.com", + }, + tags: ["crm", "sales", "business"], + load: () => import("./twenty/index.ts").then((m) => m.generate), + }, ]; diff --git a/apps/dokploy/templates/twenty/docker-compose.yml b/apps/dokploy/templates/twenty/docker-compose.yml new file mode 100644 index 000000000..3a30e13be --- /dev/null +++ b/apps/dokploy/templates/twenty/docker-compose.yml @@ -0,0 +1,98 @@ +version: "3.9" + +services: + twenty-change-vol-ownership: + image: ubuntu + user: root + networks: + - dokploy-network + volumes: + - twenty-server-local-data:/tmp/server-local-data + - twenty-docker-data:/tmp/docker-data + command: > + bash -c " + chown -R 1000:1000 /tmp/server-local-data + && chown -R 1000:1000 /tmp/docker-data" + + twenty-server: + image: twentycrm/twenty:latest + networks: + - dokploy-network + volumes: + - twenty-server-local-data:/app/packages/twenty-server/${STORAGE_LOCAL_PATH:-.local-storage} + - twenty-docker-data:/app/docker-data + environment: + PORT: 3000 + PG_DATABASE_URL: postgres://${PGUSER}:${PGPASSWORD}@twenty-db:5432/default + SERVER_URL: https://${TWENTY_HOST} + FRONT_BASE_URL: https://${TWENTY_HOST} + REDIS_URL: redis://twenty-redis:6379 + ENABLE_DB_MIGRATIONS: "true" + SIGN_IN_PREFILLED: "true" + STORAGE_TYPE: local + APP_SECRET: ${APP_SECRET} + depends_on: + twenty-change-vol-ownership: + condition: service_completed_successfully + twenty-db: + condition: service_healthy + healthcheck: + test: curl --fail http://localhost:3000/healthz + interval: 5s + timeout: 5s + retries: 10 + restart: always + + twenty-worker: + image: twentycrm/twenty:latest + networks: + - dokploy-network + command: ["yarn", "worker:prod"] + environment: + PG_DATABASE_URL: postgres://${PGUSER}:${PGPASSWORD}@twenty-db:5432/default + SERVER_URL: https://${TWENTY_HOST} + FRONT_BASE_URL: https://${TWENTY_HOST} + REDIS_URL: redis://twenty-redis:6379 + ENABLE_DB_MIGRATIONS: "false" + STORAGE_TYPE: local + APP_SECRET: ${APP_SECRET} + depends_on: + twenty-db: + condition: service_healthy + twenty-server: + condition: service_healthy + restart: always + + twenty-db: + image: twentycrm/twenty-postgres-spilo:latest + networks: + - dokploy-network + volumes: + - twenty-db-data:/home/postgres/pgdata + environment: + PGUSER_SUPERUSER: ${PGUSER} + PGPASSWORD_SUPERUSER: ${PGPASSWORD} + ALLOW_NOSSL: "true" + SPILO_PROVIDER: "local" + healthcheck: + test: pg_isready -U ${PGUSER} -h localhost -d postgres + interval: 5s + timeout: 5s + retries: 10 + restart: always + + twenty-redis: + image: redis:latest + networks: + - dokploy-network + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 5s + retries: 10 + restart: always + +volumes: + twenty-docker-data: + twenty-db-data: + twenty-server-local-data: \ No newline at end of file diff --git a/apps/dokploy/templates/twenty/index.ts b/apps/dokploy/templates/twenty/index.ts new file mode 100644 index 000000000..932e98cd2 --- /dev/null +++ b/apps/dokploy/templates/twenty/index.ts @@ -0,0 +1,37 @@ +import { + type DomainSchema, + type Schema, + type Template, + generateBase64, + generatePassword, + generateRandomDomain, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const pgPassword = generatePassword(); + const pgUser = "twenty"; + const appSecret = generateBase64(32); + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 3000, + serviceName: "twenty-server", + }, + ]; + + const envs = [ + `TWENTY_HOST=${mainDomain}`, + `PGUSER=${pgUser}`, + `PGPASSWORD=${pgPassword}`, + `APP_SECRET=${appSecret}`, + "# Optional: Configure storage path", + "# STORAGE_LOCAL_PATH=.local-storage", + ]; + + return { + domains, + envs, + }; +}