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/public/templates/discord-tickets.png b/apps/dokploy/public/templates/discord-tickets.png new file mode 100644 index 00000000..030c3a4c Binary files /dev/null and b/apps/dokploy/public/templates/discord-tickets.png differ diff --git a/apps/dokploy/public/templates/discordtickets.png b/apps/dokploy/public/templates/discordtickets.png new file mode 100644 index 00000000..030c3a4c Binary files /dev/null and b/apps/dokploy/public/templates/discordtickets.png differ diff --git a/apps/dokploy/public/templates/invoiceshelf.png b/apps/dokploy/public/templates/invoiceshelf.png new file mode 100644 index 00000000..cee025e0 Binary files /dev/null and b/apps/dokploy/public/templates/invoiceshelf.png differ 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/public/templates/postiz.png b/apps/dokploy/public/templates/postiz.png new file mode 100644 index 00000000..1d435abc Binary files /dev/null and b/apps/dokploy/public/templates/postiz.png differ diff --git a/apps/dokploy/public/templates/slash.png b/apps/dokploy/public/templates/slash.png new file mode 100644 index 00000000..c843b409 Binary files /dev/null and b/apps/dokploy/public/templates/slash.png differ 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/activepieces/docker-compose.yml b/apps/dokploy/templates/activepieces/docker-compose.yml new file mode 100644 index 00000000..e990379b --- /dev/null +++ b/apps/dokploy/templates/activepieces/docker-compose.yml @@ -0,0 +1,67 @@ +version: "3.8" + +services: + activepieces: + image: activepieces/activepieces:0.35.0 + restart: unless-stopped + networks: + - dokploy-network + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + environment: + AP_ENGINE_EXECUTABLE_PATH: dist/packages/engine/main.js + AP_API_KEY: ${AP_API_KEY} + AP_ENCRYPTION_KEY: ${AP_ENCRYPTION_KEY} + AP_JWT_SECRET: ${AP_JWT_SECRET} + AP_ENVIRONMENT: prod + AP_FRONTEND_URL: https://${AP_HOST} + AP_WEBHOOK_TIMEOUT_SECONDS: 30 + AP_TRIGGER_DEFAULT_POLL_INTERVAL: 5 + AP_POSTGRES_DATABASE: activepieces + AP_POSTGRES_HOST: postgres + AP_POSTGRES_PORT: 5432 + AP_POSTGRES_USERNAME: activepieces + AP_POSTGRES_PASSWORD: ${AP_POSTGRES_PASSWORD} + AP_EXECUTION_MODE: UNSANDBOXED + AP_REDIS_HOST: redis + AP_REDIS_PORT: 6379 + AP_SANDBOX_RUN_TIME_SECONDS: 600 + AP_TELEMETRY_ENABLED: "false" + AP_TEMPLATES_SOURCE_URL: https://cloud.activepieces.com/api/v1/flow-templates + + postgres: + image: postgres:14 + restart: unless-stopped + networks: + - dokploy-network + environment: + POSTGRES_DB: activepieces + POSTGRES_PASSWORD: ${AP_POSTGRES_PASSWORD} + POSTGRES_USER: activepieces + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U activepieces -d activepieces"] + interval: 30s + timeout: 30s + retries: 3 + + redis: + image: redis:7 + restart: unless-stopped + networks: + - dokploy-network + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 30s + timeout: 30s + retries: 3 + +volumes: + postgres_data: + redis_data: \ No newline at end of file diff --git a/apps/dokploy/templates/activepieces/index.ts b/apps/dokploy/templates/activepieces/index.ts new file mode 100644 index 00000000..60f8981f --- /dev/null +++ b/apps/dokploy/templates/activepieces/index.ts @@ -0,0 +1,40 @@ +import { + type DomainSchema, + type Schema, + type Template, + generateRandomDomain, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + + 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 domains: DomainSchema[] = [ + { + host: mainDomain, + port: 80, + serviceName: "activepieces", + }, + ]; + + const envs = [ + `AP_HOST=${mainDomain}`, + `AP_API_KEY=${apiKey}`, + `AP_ENCRYPTION_KEY=${encryptionKey}`, + `AP_JWT_SECRET=${jwtSecret}`, + `AP_POSTGRES_PASSWORD=${postgresPassword}`, + ]; + + return { + domains, + envs, + }; +} \ No newline at end of file diff --git a/apps/dokploy/templates/discord-tickets/docker-compose.yml b/apps/dokploy/templates/discord-tickets/docker-compose.yml new file mode 100644 index 00000000..44324e1e --- /dev/null +++ b/apps/dokploy/templates/discord-tickets/docker-compose.yml @@ -0,0 +1,54 @@ +version: "3.8" + +services: + mysql: + image: mysql:8 + restart: unless-stopped + hostname: mysql + networks: + - dokploy-network + volumes: + - tickets-mysql:/var/lib/mysql + environment: + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_USER: ${MYSQL_USER} + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u${MYSQL_USER}", "-p${MYSQL_PASSWORD}"] + interval: 10s + timeout: 5s + retries: 5 + + bot: + image: eartharoid/discord-tickets:4.0.21 + depends_on: + mysql: + condition: service_healthy + restart: unless-stopped + hostname: bot + networks: + - dokploy-network + volumes: + - tickets-bot:/home/container/user + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + tty: true + stdin_open: true + environment: + DB_CONNECTION_URL: mysql://${MYSQL_USER}:${MYSQL_PASSWORD}@mysql/${MYSQL_DATABASE} + DISCORD_SECRET: ${DISCORD_SECRET} + DISCORD_TOKEN: ${DISCORD_TOKEN} + ENCRYPTION_KEY: ${ENCRYPTION_KEY} + DB_PROVIDER: mysql + HTTP_EXTERNAL: https://${TICKETS_HOST} + HTTP_HOST: 0.0.0.0 + HTTP_PORT: 8169 + HTTP_TRUST_PROXY: "true" + PUBLIC_BOT: "false" + PUBLISH_COMMANDS: "true" + SUPER: ${SUPER_USERS} + +volumes: + tickets-mysql: + tickets-bot: \ No newline at end of file diff --git a/apps/dokploy/templates/discord-tickets/index.ts b/apps/dokploy/templates/discord-tickets/index.ts new file mode 100644 index 00000000..e2a42649 --- /dev/null +++ b/apps/dokploy/templates/discord-tickets/index.ts @@ -0,0 +1,46 @@ +import { + type DomainSchema, + type Schema, + type Template, + generatePassword, + generateRandomDomain, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const mysqlPassword = generatePassword(); + const mysqlRootPassword = generatePassword(); + const mysqlUser = "tickets"; + const mysqlDatabase = "tickets"; + + // Generate encryption key in the format they use + const encryptionKey = Array.from({length: 48}, () => + 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/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/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/postiz/docker-compose.yml b/apps/dokploy/templates/postiz/docker-compose.yml new file mode 100644 index 00000000..42a4b976 --- /dev/null +++ b/apps/dokploy/templates/postiz/docker-compose.yml @@ -0,0 +1,64 @@ +version: "3.8" + +services: + postiz: + image: ghcr.io/gitroomhq/postiz-app:latest + restart: always + networks: + - dokploy-network + environment: + MAIN_URL: "https://${POSTIZ_HOST}" + FRONTEND_URL: "https://${POSTIZ_HOST}" + NEXT_PUBLIC_BACKEND_URL: "https://${POSTIZ_HOST}/api" + JWT_SECRET: ${JWT_SECRET} + DATABASE_URL: "postgresql://${DB_USER}:${DB_PASSWORD}@postiz-postgres:5432/${DB_NAME}" + REDIS_URL: "redis://postiz-redis:6379" + BACKEND_INTERNAL_URL: "http://localhost:3000" + IS_GENERAL: "true" + STORAGE_PROVIDER: "local" + UPLOAD_DIRECTORY: "/uploads" + NEXT_PUBLIC_UPLOAD_DIRECTORY: "/uploads" + volumes: + - postiz-config:/config/ + - postiz-uploads:/uploads/ + depends_on: + postiz-postgres: + condition: service_healthy + postiz-redis: + condition: service_healthy + + postiz-postgres: + image: postgres:17-alpine + restart: always + networks: + - dokploy-network + environment: + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_USER: ${DB_USER} + POSTGRES_DB: ${DB_NAME} + volumes: + - postgres-volume:/var/lib/postgresql/data + healthcheck: + test: pg_isready -U ${DB_USER} -d ${DB_NAME} + interval: 10s + timeout: 3s + retries: 3 + + postiz-redis: + image: redis:7.2 + restart: always + networks: + - dokploy-network + healthcheck: + test: redis-cli ping + interval: 10s + timeout: 3s + retries: 3 + volumes: + - postiz-redis-data:/data + +volumes: + postgres-volume: + postiz-redis-data: + postiz-config: + postiz-uploads: \ No newline at end of file diff --git a/apps/dokploy/templates/postiz/index.ts b/apps/dokploy/templates/postiz/index.ts new file mode 100644 index 00000000..44015465 --- /dev/null +++ b/apps/dokploy/templates/postiz/index.ts @@ -0,0 +1,37 @@ +import { + type DomainSchema, + type Schema, + type Template, + generatePassword, + generateRandomDomain, + generateBase64, +} from "../utils"; + +export function generate(schema: Schema): Template { + const mainDomain = generateRandomDomain(schema); + const dbPassword = generatePassword(); + const dbUser = "postiz"; + const dbName = "postiz"; + const jwtSecret = generateBase64(32); + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 5000, + serviceName: "postiz", + }, + ]; + + const envs = [ + `POSTIZ_HOST=${mainDomain}`, + `DB_PASSWORD=${dbPassword}`, + `DB_USER=${dbUser}`, + `DB_NAME=${dbName}`, + `JWT_SECRET=${jwtSecret}`, + ]; + + return { + domains, + envs, + }; +} \ No newline at end of file diff --git a/apps/dokploy/templates/slash/docker-compose.yml b/apps/dokploy/templates/slash/docker-compose.yml new file mode 100644 index 00000000..fce3114e --- /dev/null +++ b/apps/dokploy/templates/slash/docker-compose.yml @@ -0,0 +1,37 @@ +version: "3.8" + +services: + slash: + image: yourselfhosted/slash:latest + networks: + - dokploy-network + volumes: + - slash_data:/var/opt/slash + environment: + - SLASH_DRIVER=postgres + - SLASH_DSN=postgresql://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}?sslmode=disable + depends_on: + db: + condition: service_healthy + restart: unless-stopped + + db: + image: postgres:16-alpine + networks: + - dokploy-network + volumes: + - postgres_data:/var/lib/postgresql/data + environment: + - POSTGRES_USER=${DB_USER} + - POSTGRES_PASSWORD=${DB_PASSWORD} + - POSTGRES_DB=${DB_NAME} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + +volumes: + slash_data: + postgres_data: \ No newline at end of file diff --git a/apps/dokploy/templates/slash/index.ts b/apps/dokploy/templates/slash/index.ts new file mode 100644 index 00000000..5d2bcdb2 --- /dev/null +++ b/apps/dokploy/templates/slash/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 dbPassword = generatePassword(); + const dbUser = "slash"; + const dbName = "slash"; + + const domains: DomainSchema[] = [ + { + host: mainDomain, + port: 5231, + serviceName: "slash", + }, + ]; + + const envs = [ + `DB_USER=${dbUser}`, + `DB_PASSWORD=${dbPassword}`, + `DB_NAME=${dbName}`, + ]; + + return { + domains, + envs, + }; +} \ No newline at end of file diff --git a/apps/dokploy/templates/templates.ts b/apps/dokploy/templates/templates.ts index 322eb8e2..1ad1a012 100644 --- a/apps/dokploy/templates/templates.ts +++ b/apps/dokploy/templates/templates.ts @@ -703,6 +703,104 @@ export const templates: TemplateData[] = [ 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), + }, + { + 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), + }, + { + 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), + }, + { + 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), + }, + { + 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), + }, + { + 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), + }, + { + id: "discord-tickets", + name: "Discord Tickets", + version: "4.0.21", + description: "An open-source Discord bot for creating and managing support ticket channels.", + logo: "discord-tickets.png", + links: { + github: "https://github.com/discord-tickets/bot", + website: "https://discordtickets.app", + docs: "https://discordtickets.app/self-hosting/installation/docker/", + }, + tags: ["discord", "tickets", "support"], + load: () => import("./discord-tickets/index").then((m) => m.generate), + }, + { id: "nextcloud-aio", name: "Nextcloud All in One", version: "30.0.2", diff --git a/apps/dokploy/templates/windmill/docker-compose.yml b/apps/dokploy/templates/windmill/docker-compose.yml new file mode 100644 index 00000000..5646c47a --- /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: + - ../files/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..875b7afa --- /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"] = [ + { + filePath: "Caddyfile", + content: `:80 { + bind 0.0.0.0 + reverse_proxy /ws/* http://lsp:3001 + reverse_proxy /* http://windmill_server:8000 +}`, + }, + ]; + + return { + domains, + envs, + mounts, + }; +} \ No newline at end of file