diff --git a/apps/dokploy/public/templates/huly.svg b/apps/dokploy/public/templates/huly.svg new file mode 100644 index 00000000..55a98587 --- /dev/null +++ b/apps/dokploy/public/templates/huly.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/dokploy/public/templates/langflow.svg b/apps/dokploy/public/templates/langflow.svg new file mode 100644 index 00000000..3665f824 --- /dev/null +++ b/apps/dokploy/public/templates/langflow.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/dokploy/public/templates/unsend.png b/apps/dokploy/public/templates/unsend.png new file mode 100644 index 00000000..0bbe5e0f Binary files /dev/null and b/apps/dokploy/public/templates/unsend.png differ diff --git a/apps/dokploy/templates/huly/docker-compose.yml b/apps/dokploy/templates/huly/docker-compose.yml new file mode 100644 index 00000000..471ee7e9 --- /dev/null +++ b/apps/dokploy/templates/huly/docker-compose.yml @@ -0,0 +1,184 @@ +name: ${DOCKER_NAME} +version: "3" +services: + nginx: + networks: + - dokploy-network + image: "nginx:1.21.3" + ports: + - 80 + volumes: + - ../files/volumes/nginx/.huly.nginx:/etc/nginx/conf.d/default.conf + restart: unless-stopped + + mongodb: + networks: + - dokploy-network + image: "mongo:7-jammy" + environment: + - PUID=1000 + - PGID=1000 + volumes: + - db:/data/db + restart: unless-stopped + + minio: + networks: + - dokploy-network + image: "minio/minio:RELEASE.2024-11-07T00-52-20Z" + command: server /data --address ":9000" --console-address ":9001" + volumes: + - files:/data + restart: unless-stopped + + elastic: + networks: + - dokploy-network + image: "elasticsearch:7.14.2" + command: | + /bin/sh -c "./bin/elasticsearch-plugin list | grep -q ingest-attachment || yes | ./bin/elasticsearch-plugin install --silent ingest-attachment; + /usr/local/bin/docker-entrypoint.sh eswrapper" + volumes: + - elastic:/usr/share/elasticsearch/data + environment: + - ELASTICSEARCH_PORT_NUMBER=9200 + - BITNAMI_DEBUG=true + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms1024m -Xmx1024m + - http.cors.enabled=true + - http.cors.allow-origin=http://localhost:8082 + healthcheck: + interval: 20s + retries: 10 + test: curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"' + restart: unless-stopped + + rekoni: + networks: + - dokploy-network + image: hardcoreeng/rekoni-service:${HULY_VERSION} + environment: + - SECRET=${SECRET} + deploy: + resources: + limits: + memory: 500M + restart: unless-stopped + + transactor: + networks: + - dokploy-network + image: hardcoreeng/transactor:${HULY_VERSION} + environment: + - SERVER_PORT=3333 + - SERVER_SECRET=${SECRET} + - SERVER_CURSOR_MAXTIMEMS=30000 + - DB_URL=mongodb://mongodb:27017 + - MONGO_URL=mongodb://mongodb:27017 + - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin + - FRONT_URL=http://localhost:8087 + - ACCOUNTS_URL=http://account:3000 + - FULLTEXT_URL=http://fulltext:4700 + - STATS_URL=http://stats:4900 + - LAST_NAME_FIRST=${LAST_NAME_FIRST:-true} + restart: unless-stopped + + collaborator: + networks: + - dokploy-network + image: hardcoreeng/collaborator:${HULY_VERSION} + environment: + - COLLABORATOR_PORT=3078 + - SECRET=${SECRET} + - ACCOUNTS_URL=http://account:3000 + - DB_URL=mongodb://mongodb:27017 + - STATS_URL=http://stats:4900 + - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin + restart: unless-stopped + + account: + networks: + - dokploy-network + image: hardcoreeng/account:${HULY_VERSION} + environment: + - SERVER_PORT=3000 + - SERVER_SECRET=${SECRET} + - DB_URL=mongodb://mongodb:27017 + - MONGO_URL=mongodb://mongodb:27017 + - TRANSACTOR_URL=ws://transactor:3333;ws${SECURE:+s}://${HOST_ADDRESS}/_transactor + - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin + - FRONT_URL=http://front:8080 + - STATS_URL=http://stats:4900 + - MODEL_ENABLED=* + - ACCOUNTS_URL=http://localhost:3000 + - ACCOUNT_PORT=3000 + restart: unless-stopped + + workspace: + networks: + - dokploy-network + image: hardcoreeng/workspace:${HULY_VERSION} + environment: + - SERVER_SECRET=${SECRET} + - DB_URL=mongodb://mongodb:27017 + - MONGO_URL=mongodb://mongodb:27017 + - TRANSACTOR_URL=ws://transactor:3333;ws${SECURE:+s}://${HOST_ADDRESS}/_transactor + - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin + - MODEL_ENABLED=* + - ACCOUNTS_URL=http://account:3000 + - STATS_URL=http://stats:4900 + restart: unless-stopped + + front: + networks: + - dokploy-network + image: hardcoreeng/front:${HULY_VERSION} + environment: + - SERVER_PORT=8080 + - SERVER_SECRET=${SECRET} + - LOVE_ENDPOINT=http${SECURE:+s}://${HOST_ADDRESS}/_love + - ACCOUNTS_URL=http${SECURE:+s}://${HOST_ADDRESS}/_accounts + - REKONI_URL=http${SECURE:+s}://${HOST_ADDRESS}/_rekoni + - CALENDAR_URL=http${SECURE:+s}://${HOST_ADDRESS}/_calendar + - GMAIL_URL=http${SECURE:+s}://${HOST_ADDRESS}/_gmail + - TELEGRAM_URL=http${SECURE:+s}://${HOST_ADDRESS}/_telegram + - STATS_URL=http${SECURE:+s}://${HOST_ADDRESS}/_stats + - UPLOAD_URL=/files + - ELASTIC_URL=http://elastic:9200 + - COLLABORATOR_URL=ws${SECURE:+s}://${HOST_ADDRESS}/_collaborator + - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin + - DB_URL=mongodb://mongodb:27017 + - MONGO_URL=mongodb://mongodb:27017 + - TITLE=${TITLE:-Huly Self Host} + - DEFAULT_LANGUAGE=${DEFAULT_LANGUAGE:-en} + - LAST_NAME_FIRST=${LAST_NAME_FIRST:-true} + - DESKTOP_UPDATES_CHANNEL=selfhost + restart: unless-stopped + + fulltext: + networks: + - dokploy-network + image: hardcoreeng/fulltext:${HULY_VERSION} + environment: + - SERVER_SECRET=${SECRET} + - DB_URL=mongodb://mongodb:27017 + - FULLTEXT_DB_URL=http://elastic:9200 + - ELASTIC_INDEX_NAME=huly_storage_index + - STORAGE_CONFIG=minio|minio?accessKey=minioadmin&secretKey=minioadmin + - REKONI_URL=http://rekoni:4004 + - ACCOUNTS_URL=http://account:3000 + - STATS_URL=http://stats:4900 + restart: unless-stopped + + stats: + networks: + - dokploy-network + image: hardcoreeng/stats:${HULY_VERSION} + environment: + - PORT=4900 + - SERVER_SECRET=${SECRET} + restart: unless-stopped +volumes: + db: + elastic: + files: diff --git a/apps/dokploy/templates/huly/index.ts b/apps/dokploy/templates/huly/index.ts new file mode 100644 index 00000000..deb5c7db --- /dev/null +++ b/apps/dokploy/templates/huly/index.ts @@ -0,0 +1,152 @@ +import { + type DomainSchema, + type Schema, + type Template, + generateBase64, + generateRandomDomain, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const hulySecret = generateBase64(64); + const domains: DomainSchema[] = [ + { + host: generateRandomDomain(schema), + port: 80, + serviceName: "nginx", + }, + ]; + + const envs = [ + "HULY_VERSION=v0.6.377", + "DOCKER_NAME=huly", + "", + "# The address of the host or server from which you will access your Huly instance.", + "# This can be a domain name (e.g., huly.example.com) or an IP address (e.g., 192.168.1.1).", + `HOST_ADDRESS=${mainDomain}`, + "", + "# Set this variable to 'true' to enable SSL (HTTPS/WSS). ", + "# Leave it empty to use non-SSL (HTTP/WS).", + "SECURE=", + "", + "# Specify the IP address to bind to; leave blank to bind to all interfaces (0.0.0.0).", + "# Do not use IP:PORT format in HTTP_BIND or HTTP_PORT.", + "HTTP_PORT=80", + "HTTP_BIND=", + "", + "# Huly specific variables", + "TITLE=Huly", + "DEFAULT_LANGUAGE=en", + "LAST_NAME_FIRST=true", + "", + "# The following configs are auto-generated by the setup script. ", + "# Please do not manually overwrite.", + "", + "# Run with --secret to regenerate.", + `SECRET=${hulySecret}`, + ]; + + const mounts: Template["mounts"] = [ + { + filePath: "/volumes/nginx/.huly.nginx", + content: `server { + listen 80; + server_name _; + location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://front:8080; + } + + location /_accounts { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + rewrite ^/_accounts(/.*)$ $1 break; + proxy_pass http://account:3000/; + } + + #location /_love { + # proxy_set_header Host $host; + # proxy_set_header X-Real-IP $remote_addr; + # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # proxy_set_header X-Forwarded-Proto $scheme; + + # proxy_http_version 1.1; + # proxy_set_header Upgrade $http_upgrade; + # proxy_set_header Connection "upgrade"; + # rewrite ^/_love(/.*)$ $1 break; + # proxy_pass http://love:8096/; + #} + + location /_collaborator { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + rewrite ^/_collaborator(/.*)$ $1 break; + proxy_pass http://collaborator:3078/; + } + + location /_transactor { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + rewrite ^/_transactor(/.*)$ $1 break; + proxy_pass http://transactor:3333/; + } + + location ~ ^/eyJ { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_pass http://transactor:3333; + } + + location /_rekoni { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + rewrite ^/_rekoni(/.*)$ $1 break; + proxy_pass http://rekoni:4004/; + } + + location /_stats { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + rewrite ^/_stats(/.*)$ $1 break; + proxy_pass http://stats:4900/; + } +}`, + }, + ]; + + return { + domains, + envs, + mounts, + }; +} diff --git a/apps/dokploy/templates/langflow/docker-compose.yml b/apps/dokploy/templates/langflow/docker-compose.yml new file mode 100644 index 00000000..75bb73dd --- /dev/null +++ b/apps/dokploy/templates/langflow/docker-compose.yml @@ -0,0 +1,33 @@ +version: "3.8" + +services: + langflow: + image: langflowai/langflow:v1.1.1 + ports: + - 7860 + depends_on: + - postgres-langflow + environment: + - LANGFLOW_DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres-langflow:5432/langflow + # This variable defines where the logs, file storage, monitor data and secret keys are stored. + volumes: + - langflow-data:/app/langflow + networks: + - dokploy-network + + postgres-langflow: + image: postgres:16 + environment: + POSTGRES_USER: ${DB_USERNAME} + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_DB: langflow + ports: + - 5432 + volumes: + - langflow-postgres:/var/lib/postgresql/data + networks: + - dokploy-network + +volumes: + langflow-postgres: + langflow-data: \ No newline at end of file diff --git a/apps/dokploy/templates/langflow/index.ts b/apps/dokploy/templates/langflow/index.ts new file mode 100644 index 00000000..75f6db58 --- /dev/null +++ b/apps/dokploy/templates/langflow/index.ts @@ -0,0 +1,28 @@ +import { + type DomainSchema, + type Schema, + type Template, + generatePassword, + generateRandomDomain, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const dbPassword = generatePassword(); + const dbUsername = "langflow"; + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 7860, + serviceName: "langflow", + }, + ]; + + const envs = [`DB_PASSWORD=${dbPassword}`, `DB_USERNAME=${dbUsername}`]; + + return { + domains, + envs, + }; +} diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index 79b5889c..9aaf1ee0 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -1077,4 +1077,48 @@ export const templates: TemplateData[] = [ tags: ["desing", "collaboration"], load: () => import("./penpot/index").then((m) => m.generate), }, + { + id: "huly", + name: "Huly", + version: "0.6.377", + description: + "Huly — All-in-One Project Management Platform (alternative to Linear, Jira, Slack, Notion, Motion)", + logo: "huly.svg", + links: { + github: "https://github.com/hcengineering/huly-selfhost", + website: "https://huly.io/", + docs: "https://docs.huly.io/", + }, + tags: ["project-management", "community", "discussion"], + load: () => import("./huly/index").then((m) => m.generate), + }, + { + id: "unsend", + name: "Unsend", + version: "v1.2.4", + description: "Open source alternative to Resend,Sendgrid, Postmark etc. ", + logo: "unsend.png", // we defined the name and the extension of the logo + links: { + github: "https://github.com/unsend-dev/unsend", + website: "https://unsend.dev/", + docs: "https://docs.unsend.dev/get-started/", + }, + tags: ["e-mail", "marketing", "business"], + load: () => import("./unsend/index").then((m) => m.generate), + }, + { + id: "langflow", + name: "Langflow", + version: "1.1.1", + description: + "Langflow is a low-code app builder for RAG and multi-agent AI applications. It’s Python-based and agnostic to any model, API, or database. ", + logo: "langflow.svg", + links: { + github: "https://github.com/langflow-ai/langflow/tree/main", + website: "https://www.langflow.org/", + docs: "https://docs.langflow.org/", + }, + tags: ["ai"], + load: () => import("./langflow/index").then((m) => m.generate), + }, ]; diff --git a/apps/dokploy/templates/unsend/docker-compose.yml b/apps/dokploy/templates/unsend/docker-compose.yml new file mode 100644 index 00000000..cdf02de6 --- /dev/null +++ b/apps/dokploy/templates/unsend/docker-compose.yml @@ -0,0 +1,78 @@ +name: unsend-prod + +services: + unsend-db-prod: + image: postgres:16 + networks: + - dokploy-network + restart: always + environment: + - POSTGRES_USER=${POSTGRES_USER:?err} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?err} + - POSTGRES_DB=${POSTGRES_DB:?err} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + interval: 10s + timeout: 5s + retries: 5 + # ports: + # - "5432:5432" + volumes: + - database:/var/lib/postgresql/data + + unsend-redis-prod: + image: redis:7 + networks: + - dokploy-network + restart: always + # ports: + # - "6379:6379" + volumes: + - cache:/data + command: ["redis-server", "--maxmemory-policy", "noeviction"] + + unsend-storage-prod: + image: minio/minio:RELEASE.2024-11-07T00-52-20Z + networks: + - dokploy-network + ports: + - 9002 + - 9001 + volumes: + - storage:/data + environment: + MINIO_ROOT_USER: unsend + MINIO_ROOT_PASSWORD: password + entrypoint: sh + command: -c 'mkdir -p /data/unsend && minio server /data --console-address ":9001" --address ":9002"' + + unsend: + image: unsend/unsend:v1.2.4 + networks: + - dokploy-network + restart: always + ports: + - ${PORT:-3000} + environment: + - PORT=${PORT:-3000} + - DATABASE_URL=${DATABASE_URL:?err} + - NEXTAUTH_URL=${NEXTAUTH_URL:?err} + - NEXTAUTH_SECRET=${NEXTAUTH_SECRET:?err} + - AWS_ACCESS_KEY=${AWS_ACCESS_KEY:?err} + - AWS_SECRET_KEY=${AWS_SECRET_KEY:?err} + - AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION:?err} + - GITHUB_ID=${GITHUB_ID:?err} + - GITHUB_SECRET=${GITHUB_SECRET:?err} + - REDIS_URL=${REDIS_URL:?err} + - NEXT_PUBLIC_IS_CLOUD=${NEXT_PUBLIC_IS_CLOUD:-false} + - API_RATE_LIMIT=${API_RATE_LIMIT:-1} + depends_on: + unsend-db-prod: + condition: service_healthy + unsend-redis-prod: + condition: service_started + +volumes: + database: + cache: + storage: diff --git a/apps/dokploy/templates/unsend/index.ts b/apps/dokploy/templates/unsend/index.ts new file mode 100644 index 00000000..a383b771 --- /dev/null +++ b/apps/dokploy/templates/unsend/index.ts @@ -0,0 +1,44 @@ +import { + generateHash, + generateRandomDomain, + generateBase64, + type Template, + type Schema, + type DomainSchema, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const secretBase = generateBase64(64); + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 3000, + serviceName: "unsend", + }, + ]; + + const envs = [ + "REDIS_URL=redis://unsend-redis-prod:6379", + "POSTGRES_USER=postgres", + "POSTGRES_PASSWORD=postgres", + "POSTGRES_DB=unsend", + "DATABASE_URL=postgresql://postgres:postgres@unsend-db-prod:5432/unsend", + "NEXTAUTH_URL=http://localhost:3000", + `NEXTAUTH_SECRET=${secretBase}`, + "GITHUB_ID='Fill'", + "GITHUB_SECRET='Fill'", + "AWS_DEFAULT_REGION=us-east-1", + "AWS_SECRET_KEY='Fill'", + "AWS_ACCESS_KEY='Fill'", + "DOCKER_OUTPUT=1", + "API_RATE_LIMIT=1", + "DISCORD_WEBHOOK_URL=", + ]; + + return { + envs, + domains, + }; +}