From 98844f7d838f8f17a591286f7f91e4627d7c8c9a Mon Sep 17 00:00:00 2001 From: "Bill Nice G. Havugukuri" <18003647+billnice250@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:47:33 +0200 Subject: [PATCH 01/15] feat: Add Ollama Chat Tone Template (#973) * Add Ollama Chat Tone blueprint with Docker configuration, SVG logo, and metadata * Update .gitignore and replace Ollama Chat Tone SVG with new design * Add Ollama Chat Tone metadata to meta.json * Update GitHub link in meta.json for Ollama Chat Tone * Fix environment variable casing in docker-compose.yml and update template.toml with default values * Remove duplicate .DS_Store entry from .gitignore * Delete .DS_Store Delete .DS_Store --- .gitignore | 2 +- .../ollama-chat-tone/docker-compose.yml | 21 ++++++++++++ .../ollama-chat-tone/ollama-chat-tone.svg | 8 +++++ blueprints/ollama-chat-tone/template.toml | 32 +++++++++++++++++++ meta.json | 18 +++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 blueprints/ollama-chat-tone/docker-compose.yml create mode 100644 blueprints/ollama-chat-tone/ollama-chat-tone.svg create mode 100644 blueprints/ollama-chat-tone/template.toml diff --git a/.gitignore b/.gitignore index 2f8606a3..904891b2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ node_modules package-lock.json -meta.json.backup.* +meta.json.backup.* \ No newline at end of file diff --git a/blueprints/ollama-chat-tone/docker-compose.yml b/blueprints/ollama-chat-tone/docker-compose.yml new file mode 100644 index 00000000..8605f824 --- /dev/null +++ b/blueprints/ollama-chat-tone/docker-compose.yml @@ -0,0 +1,21 @@ +services: + ollama-chat-tone: + image: billnice250/chattone:latest + ports: + - 8080 + environment: + APP_NAME: "Ollama Chat Tone" + ADDR: ":8080" + SESSION_SECRET: "${SESSION_SECRET}" + DB_PATH: "/data/app.db" + OLLAMA_URL: "${OLLAMA_URL}" + OLLAMA_TIMEOUT: "${OLLAMA_TIMEOUT}" + DEFAULT_MODEL: "${DEFAULT_MODEL}" + OPEN_BROWSER: "false" + BASIC_AUTH_USER: "${BASIC_AUTH_USER}" + BASIC_AUTH_PASSWORD: "${BASIC_AUTH_PASSWORD}" + volumes: + - ollama-chat-tone-data:/data + +volumes: + ollama-chat-tone-data: {} diff --git a/blueprints/ollama-chat-tone/ollama-chat-tone.svg b/blueprints/ollama-chat-tone/ollama-chat-tone.svg new file mode 100644 index 00000000..b90a86a1 --- /dev/null +++ b/blueprints/ollama-chat-tone/ollama-chat-tone.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/blueprints/ollama-chat-tone/template.toml b/blueprints/ollama-chat-tone/template.toml new file mode 100644 index 00000000..2ab6ae27 --- /dev/null +++ b/blueprints/ollama-chat-tone/template.toml @@ -0,0 +1,32 @@ +[variables] +main_domain = "${domain}" +session_secret = "change-me......32charsOrMore" +ollama_url = "http://your-ollama-host:11434" +ollama_timeout = "5" +default_model = "llama3.2" +basic_auth_user = "admin" +basic_auth_password = "change-me" + +[config] +[[config.domains]] +serviceName = "ollama-chat-tone" +port = 8080 +host = "${main_domain}" +path = "/" + +[config.env] +APP_NAME = "Ollama Chat Tone" +ADDR = ":8080" +SESSION_SECRET = "${session_secret}" +DB_PATH = "/data/app.db" +OLLAMA_URL = "${ollama_url}" +OLLAMA_TIMEOUT = "${ollama_timeout}" +DEFAULT_MODEL = "${default_model}" +OPEN_BROWSER = "false" +BASIC_AUTH_USER = "${basic_auth_user}" +BASIC_AUTH_PASSWORD = "${basic_auth_password}" + +[[config.mounts]] +serviceName = "ollama-chat-tone" +filePath = "/data/app.db" +content = "" diff --git a/meta.json b/meta.json index 8be7825d..361203fd 100644 --- a/meta.json +++ b/meta.json @@ -4532,6 +4532,24 @@ "academic" ] }, + { + "id": "ollama-chat-tone", + "name": "Ollama Chat Tone", + "version": "latest", + "description": "Self-contained Ollama chat client with local auth, streaming responses, and per-user conversations.", + "logo": "ollama-chat-tone.svg", + "links": { + "github": "https://github.com/billnice250/ollama-chat-client", + "website": "https://hub.docker.com/r/billnice250/chattone", + "docs": "https://hub.docker.com/r/billnice250/chattone" + }, + "tags": [ + "chatbot", + "ai", + "ollama", + "docker" + ] + }, { "id": "omni-tools", "name": "Omni-Tools", From 51f0b08b21f593afb528358550959b0033452b7c Mon Sep 17 00:00:00 2001 From: Khiet Tam Nguyen <86177399+nktnet1@users.noreply.github.com> Date: Wed, 8 Jul 2026 04:47:42 +1000 Subject: [PATCH 02/15] feat: update registry template to v3 (#972) --- blueprints/registry/docker-compose.yml | 44 +++++++++++++++-------- blueprints/registry/template.toml | 48 +++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 19 deletions(-) diff --git a/blueprints/registry/docker-compose.yml b/blueprints/registry/docker-compose.yml index 08c5c368..a86455d4 100644 --- a/blueprints/registry/docker-compose.yml +++ b/blueprints/registry/docker-compose.yml @@ -1,19 +1,35 @@ services: registry: - restart: always - image: registry:2 - ports: - - 5000 - volumes: - - ../files/auth/registry.password:/auth/registry.password - - registry-data:/var/lib/registry + image: registry:3 + restart: unless-stopped environment: - REGISTRY_STORAGE_DELETE_ENABLED: true - REGISTRY_HEALTH_STORAGEDRIVER_ENABLED: false - REGISTRY_HTTP_SECRET: ${REGISTRY_HTTP_SECRET} - REGISTRY_AUTH: htpasswd - REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm - REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password + - USERNAME=${USERNAME} + - PASSWORD=${PASSWORD} + - REGISTRY_AUTH=htpasswd + - REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm + - REGISTRY_AUTH_HTPASSWD_PATH=/auth/registry.password + - REGISTRY_HTTP_RELATIVEURLS=true + entrypoint: ["sh", "/entrypoint.sh"] + volumes: + - registry-data:/var/lib/registry + - type: bind + source: ../files/entrypoint.sh + target: /entrypoint.sh + - type: bind + source: ../files/config.yml + target: /etc/docker/registry/config.yml + expose: + - 5000 + healthcheck: + test: + - CMD + - wget + - "-q" + - "--spider" + - "http://localhost:5000/" + interval: 5s + timeout: 20s + retries: 10 volumes: - registry-data: \ No newline at end of file + registry-data: diff --git a/blueprints/registry/template.toml b/blueprints/registry/template.toml index a61ca406..a2a16530 100644 --- a/blueprints/registry/template.toml +++ b/blueprints/registry/template.toml @@ -1,6 +1,7 @@ [variables] main_domain = "${domain}" -registry_http_secret = "${password:30}" +username = "${username}" +password = "${password:32}" [[config.domains]] serviceName = "registry" @@ -8,11 +9,48 @@ port = 5_000 host = "${main_domain}" [config.env] -REGISTRY_HTTP_SECRET = "${registry_http_secret}" +USERNAME = "${username}" +PASSWORD = "${password}" [[config.mounts]] -filePath = "/auth/registry.password" +filePath = "./config.yml" content = """ -# from: docker run --rm --entrypoint htpasswd httpd:2 -Bbn docker password -docker:$2y$10$qWZoWev/u5PV7WneFoRAMuoGpRcAQOgUuIIdLnU7pJXogrBSY23/2 +version: 0.1 + +log: + fields: + service: registry +storage: + cache: + blobdescriptor: inmemory + filesystem: + rootdirectory: /var/lib/registry +http: + addr: :5000 + headers: + X-Content-Type-Options: [nosniff] +health: + storagedriver: + enabled: true + interval: 10s + threshold: 3 +""" + +[[config.mounts]] +filePath = "./entrypoint.sh" +content = """ +#!/usr/bin/env sh + +set -e + +if [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then + echo "Error: USERNAME and PASSWORD environment variables must be set" + exit 1 +fi + +apk add --no-cache apache2-utils +mkdir -p "$(dirname "$REGISTRY_AUTH_HTPASSWD_PATH")" +chmod 755 "$(dirname "$REGISTRY_AUTH_HTPASSWD_PATH")" +htpasswd -Bbc "$REGISTRY_AUTH_HTPASSWD_PATH" "$USERNAME" "$PASSWORD" +registry serve /etc/docker/registry/config.yml """ From cdd996f73a05401dbcfa438bb0b4f28ba89ae628 Mon Sep 17 00:00:00 2001 From: Julian Gerhards <96697201+juliangerhards@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:53:45 +0200 Subject: [PATCH 03/15] feat: alarik template blueprint (#971) --- blueprints/alarik/alarik.png | Bin 0 -> 56684 bytes blueprints/alarik/docker-compose.yml | 30 +++++++++++++++++++++++++++ blueprints/alarik/template.toml | 26 +++++++++++++++++++++++ meta.json | 17 +++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 blueprints/alarik/alarik.png create mode 100644 blueprints/alarik/docker-compose.yml create mode 100644 blueprints/alarik/template.toml diff --git a/blueprints/alarik/alarik.png b/blueprints/alarik/alarik.png new file mode 100644 index 0000000000000000000000000000000000000000..cc05be94b4135b00ac40179ee56f4841d517198e GIT binary patch literal 56684 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

y3p1U3JS%xDzj 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 Date: Tue, 7 Jul 2026 14:55:31 -0400 Subject: [PATCH 04/15] Add Dokploy configuration template for Spliit with environment variable (#969) * Add Dokploy configuration template for Spliit with environment variables and domain setup * Fix : add double quote * Fix : remove container name * Fix : service name * Fix : use good name of database * Fix : change db name --- blueprints/spliit/docker-compose.yml | 28 +++++++++++++++++++++++++++ blueprints/spliit/spliit.png | Bin 0 -> 9769 bytes blueprints/spliit/template.toml | 24 +++++++++++++++++++++++ meta.json | 17 ++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 blueprints/spliit/docker-compose.yml create mode 100644 blueprints/spliit/spliit.png create mode 100644 blueprints/spliit/template.toml diff --git a/blueprints/spliit/docker-compose.yml b/blueprints/spliit/docker-compose.yml new file mode 100644 index 00000000..69b4acd9 --- /dev/null +++ b/blueprints/spliit/docker-compose.yml @@ -0,0 +1,28 @@ +services: + spliit: + image: ghcr.io/spliit-app/spliit:1.19.0 + restart: unless-stopped + env_file: + - .env + depends_on: + spliit-db: + condition: service_healthy + spliit-db: + image: pgvector/pgvector:pg16 + volumes: + - ${DB_DATA_LOCATION}:/var/lib/DBql/data + environment: + POSTGRES_USER: ${DB_USERNAME} + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_DB: ${DB_DATABASE:-spliit} + POSTGRES_INITDB_ARGS: '--data-checksums' + POSTGRES_HOST_AUTH_METHOD: trust + healthcheck: + test: + ['CMD', 'pg_isready', '-U', "${DB_USERNAME}", '-d', "${DB_DATABASE:-spliit}"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + env_file: + - .env \ No newline at end of file diff --git a/blueprints/spliit/spliit.png b/blueprints/spliit/spliit.png new file mode 100644 index 0000000000000000000000000000000000000000..3ac8cdb4ddc3c1e098ca7ffdeff0a7409d7d0cfe GIT binary patch literal 9769 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 DQ8SuX literal 0 HcmV?d00001 diff --git a/blueprints/spliit/template.toml b/blueprints/spliit/template.toml new file mode 100644 index 00000000..528072ab --- /dev/null +++ b/blueprints/spliit/template.toml @@ -0,0 +1,24 @@ + +[variables] +main_domain = "${domain}" +secret_key = "${password}" +project_name = "spliit" + +[config] +mounts = [] + +[[config.domains]] +serviceName = "spliit" +port = 3000 +host = "${main_domain}" + +[config.env] + +DB_USERNAME = "${project_name}-admin" +DB_PASSWORD = "${secret_key}" +DB_DATA_LOCATION = "/data/${project_name}/database" +DB_DATABASE = "${project_name}" + +# --- PostgreSQL --- +POSTGRES_PRISMA_URL = "postgresql://${DB_USERNAME}:${DB_PASSWORD}@${project_name}-db:5432/${DB_DATABASE}" +POSTGRES_URL_NON_POOLING = "postgresql://${DB_USERNAME}:${DB_PASSWORD}@${project_name}-db:5432/${DB_DATABASE}" \ No newline at end of file diff --git a/meta.json b/meta.json index ce662453..204d1c79 100644 --- a/meta.json +++ b/meta.json @@ -5899,6 +5899,23 @@ "storage" ] }, + { + "id": "spliit", + "name": "Spliit", + "version": "latest", + "description": "Spliit is a lightweight, self-hosted alternative to Auth0 and Clerk. Open-source, cost-effective, and developer-friendly, it provides secure authentication (OAuth, email/password, social logins) with full control over your data. No per-user fees, easy to integrate, and perfect for startups or privacy-focused projects.", + "logo": "spliit.png", + "links": { + "github": "https://github.com/spliit-app/spliit", + "website": "https://spliit.app/", + "docs": "https://github.com/spliit-app" + }, + "tags": [ + "budgeting", + "finance", + "money" + ] + }, { "id": "stack-auth", "name": "Stack Auth", From 39d6d0430a798cc646b0c0122fd80c96ad31fc7e Mon Sep 17 00:00:00 2001 From: Marios Antonoudiou Date: Tue, 7 Jul 2026 22:02:09 +0300 Subject: [PATCH 05/15] Introduce chatto app template (#962) * Introduce chatto app template * Clean up template * Update chatto env vars --- blueprints/chatto/docker-compose.yml | 29 +++++++++++++++++++++++++++ blueprints/chatto/logo.png | Bin 0 -> 37271 bytes blueprints/chatto/template.toml | 21 +++++++++++++++++++ meta.json | 18 +++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 blueprints/chatto/docker-compose.yml create mode 100644 blueprints/chatto/logo.png create mode 100644 blueprints/chatto/template.toml diff --git a/blueprints/chatto/docker-compose.yml b/blueprints/chatto/docker-compose.yml new file mode 100644 index 00000000..3edb99d3 --- /dev/null +++ b/blueprints/chatto/docker-compose.yml @@ -0,0 +1,29 @@ +version: "3.8" + +services: + chatto: + image: ghcr.io/chattocorp/chatto:0.3.8 + restart: unless-stopped + expose: + - "4000" + environment: + CHATTO_WEBSERVER_URL: https://${CHATTO_HOST} + CHATTO_WEBSERVER_PORT: "4000" + CHATTO_WEBSERVER_COOKIE_SIGNING_SECRET: ${CHATTO_COOKIE_SECRET} + CHATTO_CORE_SECRET_KEY: ${CHATTO_CORE_SECRET} + CHATTO_CORE_ASSETS_SIGNING_SECRET: ${CHATTO_ASSETS_SECRET} + CHATTO_NATS_EMBEDDED_ENABLED: true + CHATTO_NATS_EMBEDDED_DATA_DIR: /data + CHATTO_OWNERS_EMAILS: ${CHATTO_OWNER_EMAIL} + CHATTO_SMTP_ENABLED: ${CHATTO_SMTP_ENABLED:-false} + CHATTO_SMTP_HOST: ${CHATTO_SMTP_HOST:-} + CHATTO_SMTP_PORT: ${CHATTO_SMTP_PORT:-587} + CHATTO_SMTP_TLS: ${CHATTO_SMTP_TLS:-mandatory} + CHATTO_SMTP_USERNAME: ${CHATTO_SMTP_USERNAME:-} + CHATTO_SMTP_PASSWORD: ${CHATTO_SMTP_PASSWORD:-} + CHATTO_SMTP_FROM: ${CHATTO_SMTP_FROM:-} + volumes: + - chatto-data:/data + +volumes: + chatto-data: diff --git a/blueprints/chatto/logo.png b/blueprints/chatto/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..81928507b36891f7a3d698c8f756812cafc3da37 GIT binary patch literal 37271 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 Date: Wed, 8 Jul 2026 03:02:43 +0800 Subject: [PATCH 06/15] feat: add Hermes agent template (#960) Hermes is an open agent runtime from Nous Research. This template runs the supervised gateway with: - web dashboard (9119) behind Traefik, protected by the bundled basic-auth provider (auth-gated mode triggers automatically once reachable off-loopback); username admin, generated 128-char password - OpenAI-compatible gateway API (8642), enabled and bound to 0.0.0.0 with a generated bearer token (both off by default upstream) Image pinned to v2026.6.19. Provider keys are configured from the dashboard after deploy and persist in the hermes_data volume. Co-authored-by: Claude Opus 4.8 (1M context) --- blueprints/hermes/docker-compose.yml | 27 ++++++++++++++++++++++ blueprints/hermes/logo.png | Bin 0 -> 4100 bytes blueprints/hermes/template.toml | 33 +++++++++++++++++++++++++++ meta.json | 18 +++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 blueprints/hermes/docker-compose.yml create mode 100644 blueprints/hermes/logo.png create mode 100644 blueprints/hermes/template.toml diff --git a/blueprints/hermes/docker-compose.yml b/blueprints/hermes/docker-compose.yml new file mode 100644 index 00000000..6e915e33 --- /dev/null +++ b/blueprints/hermes/docker-compose.yml @@ -0,0 +1,27 @@ +version: "3.8" +services: + hermes: + image: nousresearch/hermes-agent:v2026.6.19 + restart: unless-stopped + command: gateway run + ports: + - 9119 + - 8642 + environment: + - HERMES_DASHBOARD=${HERMES_DASHBOARD} + - HERMES_DASHBOARD_BASIC_AUTH_USERNAME=${HERMES_DASHBOARD_BASIC_AUTH_USERNAME} + - HERMES_DASHBOARD_BASIC_AUTH_PASSWORD=${HERMES_DASHBOARD_BASIC_AUTH_PASSWORD} + - HERMES_DASHBOARD_BASIC_AUTH_SECRET=${HERMES_DASHBOARD_BASIC_AUTH_SECRET} + - API_SERVER_ENABLED=${API_SERVER_ENABLED} + - API_SERVER_HOST=${API_SERVER_HOST} + - API_SERVER_KEY=${API_SERVER_KEY} + volumes: + - hermes_data:/opt/data + deploy: + resources: + limits: + memory: 4G + cpus: "2.0" + +volumes: + hermes_data: diff --git a/blueprints/hermes/logo.png b/blueprints/hermes/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2d629d2f2452f00a7bc5a3252c1c1829c0b476bd GIT binary patch literal 4100 zcmV+f5c}_mP){X5y4f#U|SWXSdQz;Y7iAvkSIm5gc6mu zg2#wQKp<;D1O!4+2%z*90!UHP_kNfB!_1@*(K++}|NZyXd*AIZEIvLy?VWet$xlg1 z$^ARZlqpkkr%judJAL}}+|<-mE7XC}_IIqo9B;q zii(QlT#6L`PMyk;tb#x5`Mn;A#TC`A<(lUJbaM4AiPoF;0y?b}L<(6BdYu7F^ zc<>NOOZ!~1vkw=~Am_Bcx92ebEETLc=cJ&ZKz{!DXWQtDBSy%m(WB(U4?mRc+qcV& zH{K{?$BdQFKmS}(Ql{8p|Ja|x6tXLrvCXAQ9eeY1Dy2*R*y(dSH9u?(^K2 z%=xbj8Z<~MRjTA){nV*bvV8e+gL6vE>D;*?Q6U7Jb4J0JUw&D7C_7A?I8k=*-ff%o z?@B9ddfT>bGIHcd-F!c#_)4i;w~mY+J=&0th=|Z$Xa0G4d3I9$`t_3q3l^NyNmK}d zWy_Y?hLVz!WcQvuXLe9d?VE4Dk;KG%<=bz+6%}TA?z!h|j?f|D;o$<(!-fr0gjf7& zB+5mgprBA@%$Okq`uCUg^mHjKEEE=WuJq%sT)DD9Wj5Tnabw%~*s)_JGjog7s8Pe% zEG8z#kArj0`Zs9MK=M>hmM&c?hYlV3Q%IDF0Gmxsoi0gA^}YM{NmzK8RH;%$>eQ(t zKA+DP4hswOZ-$DhOS$HnYvkgKFBart)~wm0YFZ{voFF+lxze<0Q+fRH$8Bs>RFn|| z*#LouA9+MtwQ6N2mXnjibQLPWJ18FFoRcL>mdGcce4@hVGwRi-UR|!f`f7p7)v8sK zh7F^IO@IuW;AEiuqmMqSs&cS&>())GRjVpL{q&P*nqPj|X0s^rx0ed20WZYV6#+DXG`bKouzrR=5qe|=SxgXOX=0C zm(;6YU+Qa7qa8DNj1`Zr39XfQ7IkRW0E}vlP5*BLH=3061!3X87x89P(d+#;MRnrqf z$4{6r!L-+`S+iush$K01V889;(n~Kj=LGe*c<~b1uwlI(WrngrHD#MfS+{PT$piZSrI%ikS6+EVo_+RNY1giu zJoC&ml9-q%k0>8wfm5eXmlG#WDBtJE$&)8d_&0CfY;%bInlx!@^6=SbpP5l~&iPrb zP>tlyojYae(k0sS?EfGH=>Glp-^<*&pUBfnc?1sr9I1xsqmMqaBgRcYKEC_zJHa5K zH8yP6V8W*kn_Ax#nW+>%cI+6_+2*Ox_v^2}*3+A)i2q9>BO?LJ(W6J@!V52ytp28Pd`$#_cEJS~Q1utoI`+d42&t4nfOaNz z&Iyy@$76ihI8jreEvTe%Zj&ZW)bVR;1uvDc%t1jgQIXUuQaAzT$7T2WgCrh-_Z|8! z6@kD`+1ZCIvWkm~H&+-6o@p;KYO`stoM{tt49i2nxnQ7aTVBQ-9^3~EJ#2yR+aVppyPK-XloO8k{ zfz%H_ESJ)L5$kfuawI!yUapD=gLN4*REaWHZzuTrH&(SNXDkK~ zVJ5cTB9*|&wA+tDxx;EYJa>?0)9T6 zb2gE4XWk-Cyx$%TcDy>83rdo~W+NV)w{uRD29-_dJp}S~(|-BV;D+QFd)%lwrehjA z)6conYlV4}q^B>{$mj^4{z9-$XAgij7&Yn@%~)(Sl}aEEuj6nnTlRgipTy~i<(0f~ zIAbF<;k$qTezWc#oHqnx!}Res?S0dZO@ILO+o`8|NbM4N*L+nlv>O72g+&%hu3Wj& z!b#_x@h|xq>!c|}=T2jcHt62Ho4M3+8r4uH3yXhDl3GOB>#W}7eYZ0 zCb*Ao7%i!(AF5#ADtbq(F>;%;o?P&3r@v6)9>MUFxO-r4WIbSOWG9TS@S)EaAx}K< zq$2RX<>@mu0YwKcEePs~w$|zeAN@-!$O!s6I=Z2Sid(j1Y7D)|E(0e`dfS3{pI(gM zg0$3&42&A5Ri{o}X{t)1O`A4?M!VsL8-mi6-dY&5E$U371>q7-mVFxnbmAi-B3yI* z@iJ%596Nz~?zzV(2tR{46se;bw9*6_N)hW;uTfpD(Oa6>*jNoWYgs&v?SNva(*NlF zaU+$b7`6>7)0~5S0DW z=0|`J3Jp+->r#Y;3omR2tqQpzR2qFl3+i>E-U;CIkTRJzZJJD-I#u)rUtWFn zRg0--D{+XU-+lL8fj|g)OiT-jjcqMGHOJIVZ$WY95_v}Z0{{U3|0DMb*8l(j21!IgR09C-TiCif!tT@n0000 128 chars +dashboard_password = "${base64:96}" +dashboard_secret = "${base64:32}" +api_key = "${password:32}" + +[config] +mounts = [] + +# Web dashboard (HERMES_DASHBOARD=1). Exposed behind Traefik, so Hermes' +# auth-gated mode kicks in — protect it with the bundled basic-auth provider. +[[config.domains]] +serviceName = "hermes" +port = 9119 +host = "${dashboard_domain}" + +# OpenAI-compatible gateway API. Disabled and loopback-bound by default, +# so it must be enabled, bound to 0.0.0.0, and given a bearer token. +[[config.domains]] +serviceName = "hermes" +port = 8642 +host = "${gateway_domain}" + +[config.env] +HERMES_DASHBOARD = "1" +HERMES_DASHBOARD_BASIC_AUTH_USERNAME = "admin" +HERMES_DASHBOARD_BASIC_AUTH_PASSWORD = "${dashboard_password}" +HERMES_DASHBOARD_BASIC_AUTH_SECRET = "${dashboard_secret}" +API_SERVER_ENABLED = "true" +API_SERVER_HOST = "0.0.0.0" +API_SERVER_KEY = "${api_key}" diff --git a/meta.json b/meta.json index 06aa27b0..baac068c 100644 --- a/meta.json +++ b/meta.json @@ -2970,6 +2970,24 @@ "self-hosted" ] }, + { + "id": "hermes", + "name": "Hermes", + "version": "v2026.6.19", + "description": "Hermes is an open agent runtime from Nous Research, exposing an OpenAI-compatible gateway API and a supervised web dashboard for building and running AI agents.", + "logo": "logo.png", + "links": { + "github": "https://github.com/NousResearch/hermes-agent", + "website": "https://hermes-agent.nousresearch.com/", + "docs": "https://hermes-agent.nousresearch.com/docs/user-guide/docker" + }, + "tags": [ + "ai", + "agent", + "llm", + "self-hosted" + ] + }, { "id": "heyform", "name": "HeyForm", From 74fd2a960f2057b6095040324102940c198286b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20=C3=87elik?= Date: Tue, 7 Jul 2026 22:03:04 +0300 Subject: [PATCH 07/15] feat: add Inkvoice template (#958) --- blueprints/inkvoice/docker-compose.yml | 22 ++++++++++++++++++++++ blueprints/inkvoice/inkvoice.svg | 7 +++++++ blueprints/inkvoice/template.toml | 17 +++++++++++++++++ meta.json | 18 ++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 blueprints/inkvoice/docker-compose.yml create mode 100644 blueprints/inkvoice/inkvoice.svg create mode 100644 blueprints/inkvoice/template.toml diff --git a/blueprints/inkvoice/docker-compose.yml b/blueprints/inkvoice/docker-compose.yml new file mode 100644 index 00000000..bd275006 --- /dev/null +++ b/blueprints/inkvoice/docker-compose.yml @@ -0,0 +1,22 @@ +version: "3.8" +services: + inkvoice: + image: ghcr.io/pigontech/inkvoice:0.1.0 + restart: unless-stopped + environment: + - ADMIN_USER=${ADMIN_USER} + - ADMIN_PASS=${ADMIN_PASS} + - JWT_SECRET=${JWT_SECRET} + - DATABASE_PATH=/app/data/invoice.db + - PORT=3000 + - HOST=0.0.0.0 + # Dokploy's auto-generated domain is HTTP (sslip.io); keep false so login + # works out of the box. Set true once you attach an HTTPS custom domain. + - COOKIE_SECURE=false + volumes: + - inkvoice-data:/app/data + expose: + - 3000 + +volumes: + inkvoice-data: diff --git a/blueprints/inkvoice/inkvoice.svg b/blueprints/inkvoice/inkvoice.svg new file mode 100644 index 00000000..788f0558 --- /dev/null +++ b/blueprints/inkvoice/inkvoice.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/blueprints/inkvoice/template.toml b/blueprints/inkvoice/template.toml new file mode 100644 index 00000000..0ce2dafc --- /dev/null +++ b/blueprints/inkvoice/template.toml @@ -0,0 +1,17 @@ +[variables] +main_domain = "${domain}" +admin_user = "admin" +admin_pass = "${password:16}" +jwt_secret = "${password:48}" + +[config] +env = [ + "ADMIN_USER=${admin_user}", + "ADMIN_PASS=${admin_pass}", + "JWT_SECRET=${jwt_secret}", +] + +[[config.domains]] +serviceName = "inkvoice" +port = 3000 +host = "${main_domain}" diff --git a/meta.json b/meta.json index baac068c..b7600cb4 100644 --- a/meta.json +++ b/meta.json @@ -3261,6 +3261,24 @@ "database" ] }, + { + "id": "inkvoice", + "name": "Inkvoice", + "version": "0.1.0", + "description": "Open-source invoicing for freelancers and small teams: invoices, online payments (Stripe & PayPal), expenses, multi-currency and reports.", + "logo": "inkvoice.svg", + "links": { + "github": "https://github.com/pigontech/inkvoice", + "website": "https://inkvoice.app", + "docs": "https://docs.inkvoice.app" + }, + "tags": [ + "invoicing", + "billing", + "finance", + "self-hosted" + ] + }, { "id": "inngest", "name": "Inngest", From 942a43ec02eefa75ed06632f440ee05fa5a4fd2f Mon Sep 17 00:00:00 2001 From: Rohit Mulani Date: Tue, 7 Jul 2026 23:09:44 +0400 Subject: [PATCH 08/15] feat: add ArchiveBox template (#954) Co-authored-by: Rohit Mulani <289630555+rohitmulani63-ops@users.noreply.github.com> --- blueprints/archivebox/archivebox.svg | 5 +++++ blueprints/archivebox/docker-compose.yml | 16 ++++++++++++++++ blueprints/archivebox/template.toml | 15 +++++++++++++++ meta.json | 17 +++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 blueprints/archivebox/archivebox.svg create mode 100644 blueprints/archivebox/docker-compose.yml create mode 100644 blueprints/archivebox/template.toml diff --git a/blueprints/archivebox/archivebox.svg b/blueprints/archivebox/archivebox.svg new file mode 100644 index 00000000..be38ea52 --- /dev/null +++ b/blueprints/archivebox/archivebox.svg @@ -0,0 +1,5 @@ + + + + A + diff --git a/blueprints/archivebox/docker-compose.yml b/blueprints/archivebox/docker-compose.yml new file mode 100644 index 00000000..2f149345 --- /dev/null +++ b/blueprints/archivebox/docker-compose.yml @@ -0,0 +1,16 @@ +services: + archivebox: + image: archivebox/archivebox:latest + restart: unless-stopped + command: server --quick-init 0.0.0.0:8000 + environment: + ALLOWED_HOSTS: ${ALLOWED_HOSTS} + PUBLIC_INDEX: ${PUBLIC_INDEX} + PUBLIC_SNAPSHOTS: ${PUBLIC_SNAPSHOTS} + volumes: + - archivebox_data:/data + ports: + - "8000" + +volumes: + archivebox_data: diff --git a/blueprints/archivebox/template.toml b/blueprints/archivebox/template.toml new file mode 100644 index 00000000..edcc7fa8 --- /dev/null +++ b/blueprints/archivebox/template.toml @@ -0,0 +1,15 @@ +[variables] +main_domain = "${domain}" + +[config] +mounts = [] + +[[config.domains]] +serviceName = "archivebox" +port = 8000 +host = "${main_domain}" + +[config.env] +ALLOWED_HOSTS = "*" +PUBLIC_INDEX = "True" +PUBLIC_SNAPSHOTS = "True" diff --git a/meta.json b/meta.json index b7600cb4..23b8bb51 100644 --- a/meta.json +++ b/meta.json @@ -431,6 +431,23 @@ "nosql" ] }, + { + "id": "archivebox", + "name": "ArchiveBox", + "version": "latest", + "description": "ArchiveBox is a self-hosted internet archiving solution for saving websites, media, and documents.", + "logo": "archivebox.svg", + "links": { + "github": "https://github.com/ArchiveBox/ArchiveBox", + "website": "https://archivebox.io/", + "docs": "https://docs.archivebox.io/" + }, + "tags": [ + "archive", + "bookmarks", + "web" + ] + }, { "id": "argilla", "name": "Argilla", From 47f92da9a20832127d58584205211c2a13e4e277 Mon Sep 17 00:00:00 2001 From: Rohit Mulani Date: Tue, 7 Jul 2026 23:10:07 +0400 Subject: [PATCH 09/15] feat: add FileGator template (#953) * feat: add FileGator template * chore: pin filegator template version --------- Co-authored-by: Rohit Mulani <289630555+rohitmulani63-ops@users.noreply.github.com> --- blueprints/filegator/docker-compose.yml | 13 +++++++++++++ blueprints/filegator/filegator.svg | 5 +++++ blueprints/filegator/template.toml | 11 +++++++++++ meta.json | 17 +++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 blueprints/filegator/docker-compose.yml create mode 100644 blueprints/filegator/filegator.svg create mode 100644 blueprints/filegator/template.toml diff --git a/blueprints/filegator/docker-compose.yml b/blueprints/filegator/docker-compose.yml new file mode 100644 index 00000000..f2f73351 --- /dev/null +++ b/blueprints/filegator/docker-compose.yml @@ -0,0 +1,13 @@ +services: + filegator: + image: filegator/filegator:v7.14.3 + restart: unless-stopped + volumes: + - filegator_repository:/var/www/filegator/repository + - filegator_private:/var/www/filegator/private + ports: + - "8080" + +volumes: + filegator_repository: + filegator_private: diff --git a/blueprints/filegator/filegator.svg b/blueprints/filegator/filegator.svg new file mode 100644 index 00000000..7f09ba2d --- /dev/null +++ b/blueprints/filegator/filegator.svg @@ -0,0 +1,5 @@ + + + + F + diff --git a/blueprints/filegator/template.toml b/blueprints/filegator/template.toml new file mode 100644 index 00000000..8646a0c7 --- /dev/null +++ b/blueprints/filegator/template.toml @@ -0,0 +1,11 @@ +[variables] +main_domain = "${domain}" + +[config] +env = {} +mounts = [] + +[[config.domains]] +serviceName = "filegator" +port = 8080 +host = "${main_domain}" diff --git a/meta.json b/meta.json index 23b8bb51..c1ebf478 100644 --- a/meta.json +++ b/meta.json @@ -2344,6 +2344,23 @@ "storage" ] }, + { + "id": "filegator", + "name": "FileGator", + "version": "7.14.3", + "description": "FileGator is a simple self-hosted web file manager with multi-user support.", + "logo": "filegator.svg", + "links": { + "github": "https://github.com/filegator/filegator", + "website": "https://filegator.io/", + "docs": "https://docs.filegator.io/" + }, + "tags": [ + "files", + "file-manager", + "self-hosted" + ] + }, { "id": "filestash", "name": "Filestash", From 7faf814ec7e435917f284344b73061d9ffe77242 Mon Sep 17 00:00:00 2001 From: Rohit Mulani Date: Tue, 7 Jul 2026 23:12:35 +0400 Subject: [PATCH 10/15] feat: add SFTPGo template (#951) * feat: add SFTPGo template * fix: use Dokploy port syntax for SFTPGo * chore: pin sftpgo template version --------- Co-authored-by: Rohit Mulani <289630555+rohitmulani63-ops@users.noreply.github.com> --- blueprints/sftpgo/docker-compose.yml | 14 ++++++++++++++ blueprints/sftpgo/sftpgo.svg | 5 +++++ blueprints/sftpgo/template.toml | 11 +++++++++++ meta.json | 17 +++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 blueprints/sftpgo/docker-compose.yml create mode 100644 blueprints/sftpgo/sftpgo.svg create mode 100644 blueprints/sftpgo/template.toml diff --git a/blueprints/sftpgo/docker-compose.yml b/blueprints/sftpgo/docker-compose.yml new file mode 100644 index 00000000..2cd48773 --- /dev/null +++ b/blueprints/sftpgo/docker-compose.yml @@ -0,0 +1,14 @@ +services: + sftpgo: + image: drakkan/sftpgo:v2.7.3 + restart: unless-stopped + volumes: + - sftpgo_data:/srv/sftpgo + - sftpgo_home:/var/lib/sftpgo + ports: + - "8080" + - "2022" + +volumes: + sftpgo_data: + sftpgo_home: diff --git a/blueprints/sftpgo/sftpgo.svg b/blueprints/sftpgo/sftpgo.svg new file mode 100644 index 00000000..1928bbb7 --- /dev/null +++ b/blueprints/sftpgo/sftpgo.svg @@ -0,0 +1,5 @@ + + + + S + diff --git a/blueprints/sftpgo/template.toml b/blueprints/sftpgo/template.toml new file mode 100644 index 00000000..12437970 --- /dev/null +++ b/blueprints/sftpgo/template.toml @@ -0,0 +1,11 @@ +[variables] +main_domain = "${domain}" + +[config] +env = {} +mounts = [] + +[[config.domains]] +serviceName = "sftpgo" +port = 8080 +host = "${main_domain}" diff --git a/meta.json b/meta.json index c1ebf478..30727a3b 100644 --- a/meta.json +++ b/meta.json @@ -5864,6 +5864,23 @@ "file-system" ] }, + { + "id": "sftpgo", + "name": "SFTPGo", + "version": "2.7.3", + "description": "SFTPGo is a full-featured and highly configurable SFTP, HTTP/S, FTP/S, and WebDAV server.", + "logo": "sftpgo.svg", + "links": { + "github": "https://github.com/drakkan/sftpgo", + "website": "https://sftpgo.com/", + "docs": "https://docs.sftpgo.com/" + }, + "tags": [ + "sftp", + "files", + "webdav" + ] + }, { "id": "shlink", "name": "Shlink", From 5f037d3e6ba34d7f1a97148d184b10270dc8a578 Mon Sep 17 00:00:00 2001 From: Rohit Mulani Date: Tue, 7 Jul 2026 23:12:56 +0400 Subject: [PATCH 11/15] feat: add Jellyseerr template (#950) * feat: add Jellyseerr template * chore: pin jellyseerr template version --------- Co-authored-by: Rohit Mulani <289630555+rohitmulani63-ops@users.noreply.github.com> --- blueprints/jellyseerr/docker-compose.yml | 13 +++++++++++++ blueprints/jellyseerr/jellyseerr.svg | 5 +++++ blueprints/jellyseerr/template.toml | 11 +++++++++++ meta.json | 17 +++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 blueprints/jellyseerr/docker-compose.yml create mode 100644 blueprints/jellyseerr/jellyseerr.svg create mode 100644 blueprints/jellyseerr/template.toml diff --git a/blueprints/jellyseerr/docker-compose.yml b/blueprints/jellyseerr/docker-compose.yml new file mode 100644 index 00000000..e17f3ddb --- /dev/null +++ b/blueprints/jellyseerr/docker-compose.yml @@ -0,0 +1,13 @@ +services: + jellyseerr: + image: fallenbagel/jellyseerr:2.7.3 + restart: unless-stopped + volumes: + - jellyseerr_config:/app/config + environment: + LOG_LEVEL: info + ports: + - "5055" + +volumes: + jellyseerr_config: diff --git a/blueprints/jellyseerr/jellyseerr.svg b/blueprints/jellyseerr/jellyseerr.svg new file mode 100644 index 00000000..93840c4a --- /dev/null +++ b/blueprints/jellyseerr/jellyseerr.svg @@ -0,0 +1,5 @@ + + + + J + diff --git a/blueprints/jellyseerr/template.toml b/blueprints/jellyseerr/template.toml new file mode 100644 index 00000000..b41dae81 --- /dev/null +++ b/blueprints/jellyseerr/template.toml @@ -0,0 +1,11 @@ +[variables] +main_domain = "${domain}" + +[config] +env = {} +mounts = [] + +[[config.domains]] +serviceName = "jellyseerr" +port = 5055 +host = "${main_domain}" diff --git a/meta.json b/meta.json index 30727a3b..de280bb5 100644 --- a/meta.json +++ b/meta.json @@ -3433,6 +3433,23 @@ "media system" ] }, + { + "id": "jellyseerr", + "name": "Jellyseerr", + "version": "2.7.3", + "description": "Jellyseerr is a media request and discovery manager for Jellyfin, Plex, and Emby users.", + "logo": "jellyseerr.svg", + "links": { + "github": "https://github.com/Fallenbagel/jellyseerr", + "website": "https://docs.jellyseerr.dev/", + "docs": "https://docs.jellyseerr.dev/" + }, + "tags": [ + "media", + "requests", + "jellyfin" + ] + }, { "id": "jenkins", "name": "jenkins", From c3ed7d9296e6852eb2f3492ec80af619e9f3e465 Mon Sep 17 00:00:00 2001 From: Rohit Mulani Date: Tue, 7 Jul 2026 23:13:20 +0400 Subject: [PATCH 12/15] feat: add Dockge template (#949) Co-authored-by: Rohit Mulani <289630555+rohitmulani63-ops@users.noreply.github.com> --- blueprints/dockge/docker-compose.yml | 16 ++++++++++++++++ blueprints/dockge/dockge.svg | 5 +++++ blueprints/dockge/template.toml | 11 +++++++++++ meta.json | 17 +++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 blueprints/dockge/docker-compose.yml create mode 100644 blueprints/dockge/dockge.svg create mode 100644 blueprints/dockge/template.toml diff --git a/blueprints/dockge/docker-compose.yml b/blueprints/dockge/docker-compose.yml new file mode 100644 index 00000000..8736f2fd --- /dev/null +++ b/blueprints/dockge/docker-compose.yml @@ -0,0 +1,16 @@ +services: + dockge: + image: louislam/dockge:1 + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - dockge_data:/app/data + - dockge_stacks:/opt/stacks + environment: + DOCKGE_STACKS_DIR: /opt/stacks + ports: + - "5001" + +volumes: + dockge_data: + dockge_stacks: diff --git a/blueprints/dockge/dockge.svg b/blueprints/dockge/dockge.svg new file mode 100644 index 00000000..69ade613 --- /dev/null +++ b/blueprints/dockge/dockge.svg @@ -0,0 +1,5 @@ + + + + D + diff --git a/blueprints/dockge/template.toml b/blueprints/dockge/template.toml new file mode 100644 index 00000000..79d8a24f --- /dev/null +++ b/blueprints/dockge/template.toml @@ -0,0 +1,11 @@ +[variables] +main_domain = "${domain}" + +[config] +env = {} +mounts = [] + +[[config.domains]] +serviceName = "dockge" +port = 5001 +host = "${main_domain}" diff --git a/meta.json b/meta.json index de280bb5..f1dcccfa 100644 --- a/meta.json +++ b/meta.json @@ -1851,6 +1851,23 @@ "discussion" ] }, + { + "id": "dockge", + "name": "Dockge", + "version": "1", + "description": "Dockge is a reactive, self-hosted Docker Compose stack manager from the creator of Uptime Kuma.", + "logo": "dockge.svg", + "links": { + "github": "https://github.com/louislam/dockge", + "website": "https://dockge.kuma.pet/", + "docs": "https://github.com/louislam/dockge" + }, + "tags": [ + "docker", + "compose", + "management" + ] + }, { "id": "docling-serve", "name": "Docling Serve", From 6d0028bcfcdd2a26549cb3484ee11711ad46158c Mon Sep 17 00:00:00 2001 From: Rohit Mulani Date: Tue, 7 Jul 2026 23:16:27 +0400 Subject: [PATCH 13/15] feat: add Joplin Server template (#948) * feat: add Joplin Server template * chore: pin joplin-server template version * Update blueprints/joplin-server/template.toml --------- Co-authored-by: Rohit Mulani <289630555+rohitmulani63-ops@users.noreply.github.com> Co-authored-by: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> --- blueprints/joplin-server/docker-compose.yml | 30 +++++++++++++++++++++ blueprints/joplin-server/joplin-server.svg | 5 ++++ blueprints/joplin-server/template.toml | 18 +++++++++++++ meta.json | 17 ++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 blueprints/joplin-server/docker-compose.yml create mode 100644 blueprints/joplin-server/joplin-server.svg create mode 100644 blueprints/joplin-server/template.toml diff --git a/blueprints/joplin-server/docker-compose.yml b/blueprints/joplin-server/docker-compose.yml new file mode 100644 index 00000000..fefac15b --- /dev/null +++ b/blueprints/joplin-server/docker-compose.yml @@ -0,0 +1,30 @@ +services: + joplin-db: + image: postgres:16-alpine + restart: unless-stopped + environment: + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_DB: ${POSTGRES_DATABASE} + volumes: + - joplin_db_data:/var/lib/postgresql/data + + joplin-server: + image: joplin/server:3.7.1 + restart: unless-stopped + depends_on: + - joplin-db + environment: + APP_BASE_URL: ${APP_BASE_URL} + APP_PORT: ${APP_PORT} + DB_CLIENT: pg + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DATABASE: ${POSTGRES_DATABASE} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PORT: 5432 + POSTGRES_HOST: joplin-db + ports: + - "22300" + +volumes: + joplin_db_data: diff --git a/blueprints/joplin-server/joplin-server.svg b/blueprints/joplin-server/joplin-server.svg new file mode 100644 index 00000000..93840c4a --- /dev/null +++ b/blueprints/joplin-server/joplin-server.svg @@ -0,0 +1,5 @@ + + + + J + diff --git a/blueprints/joplin-server/template.toml b/blueprints/joplin-server/template.toml new file mode 100644 index 00000000..f8258bc6 --- /dev/null +++ b/blueprints/joplin-server/template.toml @@ -0,0 +1,18 @@ +[variables] +main_domain = "${domain}" +postgres_password = "${password:32}" + +[config] +mounts = [] + +[[config.domains]] +serviceName = "joplin-server" +port = 22300 +host = "${main_domain}" + +[config.env] +APP_BASE_URL = "http://${main_domain}" +APP_PORT = "22300" +POSTGRES_PASSWORD = "${postgres_password}" +POSTGRES_USER = "joplin" +POSTGRES_DATABASE = "joplin" diff --git a/meta.json b/meta.json index f1dcccfa..1a253a69 100644 --- a/meta.json +++ b/meta.json @@ -3486,6 +3486,23 @@ "open-source" ] }, + { + "id": "joplin-server", + "name": "Joplin Server", + "version": "3.7.1", + "description": "Joplin Server is the self-hosted sync backend for Joplin notes, notebooks, and attachments.", + "logo": "joplin-server.svg", + "links": { + "github": "https://github.com/laurent22/joplin", + "website": "https://joplinapp.org/", + "docs": "https://github.com/laurent22/joplin/tree/dev/packages/server" + }, + "tags": [ + "notes", + "sync", + "productivity" + ] + }, { "id": "kaneo", "name": "Kaneo", From 5a193c5fb27fe67254be7122f209f60b5413736d Mon Sep 17 00:00:00 2001 From: Rohit Mulani Date: Tue, 7 Jul 2026 23:16:48 +0400 Subject: [PATCH 14/15] feat: add Gotify template (#946) * feat: add Gotify template * chore: pin gotify template version --------- Co-authored-by: Rohit Mulani <289630555+rohitmulani63-ops@users.noreply.github.com> --- blueprints/gotify/docker-compose.yml | 11 +++++++++ blueprints/gotify/gotify.svg | 5 ++++ blueprints/gotify/template.toml | 11 +++++++++ meta.json | 35 +++++++++++++++++++++------- 4 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 blueprints/gotify/docker-compose.yml create mode 100644 blueprints/gotify/gotify.svg create mode 100644 blueprints/gotify/template.toml diff --git a/blueprints/gotify/docker-compose.yml b/blueprints/gotify/docker-compose.yml new file mode 100644 index 00000000..1d3d8265 --- /dev/null +++ b/blueprints/gotify/docker-compose.yml @@ -0,0 +1,11 @@ +services: + gotify: + image: gotify/server:2.9.1 + restart: unless-stopped + volumes: + - gotify_data:/app/data + ports: + - "80" + +volumes: + gotify_data: diff --git a/blueprints/gotify/gotify.svg b/blueprints/gotify/gotify.svg new file mode 100644 index 00000000..29502b8a --- /dev/null +++ b/blueprints/gotify/gotify.svg @@ -0,0 +1,5 @@ + + + + G + diff --git a/blueprints/gotify/template.toml b/blueprints/gotify/template.toml new file mode 100644 index 00000000..2308838a --- /dev/null +++ b/blueprints/gotify/template.toml @@ -0,0 +1,11 @@ +[variables] +main_domain = "${domain}" + +[config] +env = {} +mounts = [] + +[[config.domains]] +serviceName = "gotify" +port = 80 +host = "${main_domain}" diff --git a/meta.json b/meta.json index 1a253a69..83496f3b 100644 --- a/meta.json +++ b/meta.json @@ -182,7 +182,7 @@ "id": "alist", "name": "AList", "version": "v3.55.0", - "description": "🗂️A file list/WebDAV program that supports multiple storages, powered by Gin and Solidjs.", + "description": "🗂️A file list/WebDAV program that supports multiple storages, powered by Gin and Solidjs.", "logo": "alist.svg", "links": { "github": "https://github.com/AlistGo/alist", @@ -316,7 +316,7 @@ "id": "anytype", "name": "Anytype", "version": "latest", - "description": "Anytype is a personal knowledge base—your digital brain—that lets you gather, connect and remix all kinds of information. Create pages, tasks, wikis, journals—even entire apps—and define your own data model while your data stays offline-first, private and encrypted across devices.\n\nAfter installation, you can view the Anytype client configuration by running `cat /data/client-config.yml` inside the service container.", + "description": "Anytype is a personal knowledge base—your digital brain—that lets you gather, connect and remix all kinds of information. Create pages, tasks, wikis, journals—even entire apps—and define your own data model while your data stays offline-first, private and encrypted across devices.\n\nAfter installation, you can view the Anytype client configuration by running `cat /data/client-config.yml` inside the service container.", "logo": "logo.png", "links": { "github": "https://github.com/grishy/any-sync-bundle", @@ -545,7 +545,7 @@ "id": "autobase", "name": "Autobase", "version": "2.5.2", - "description": "Autobase for PostgreSQL® is an open-source alternative to cloud-managed databases (self-hosted DBaaS).", + "description": "Autobase for PostgreSQL® is an open-source alternative to cloud-managed databases (self-hosted DBaaS).", "links": { "github": "https://github.com/vitabaks/autobase", "website": "https://autobase.tech/", @@ -755,7 +755,7 @@ "id": "blender", "name": "Blender", "version": "latest", - "description": "Blender is a free and open-source 3D creation suite. It supports the entire 3D pipeline—modeling, rigging, animation, simulation, rendering, compositing and motion tracking, video editing and 2D animation pipeline.", + "description": "Blender is a free and open-source 3D creation suite. It supports the entire 3D pipeline—modeling, rigging, animation, simulation, rendering, compositing and motion tracking, video editing and 2D animation pipeline.", "logo": "blender.svg", "links": { "github": "https://github.com/linuxserver/docker-blender", @@ -2952,6 +2952,23 @@ "tools" ] }, + { + "id": "gotify", + "name": "Gotify", + "version": "2.9.1", + "description": "Gotify is a simple server for sending and receiving self-hosted push notifications.", + "logo": "gotify.svg", + "links": { + "github": "https://github.com/gotify/server", + "website": "https://gotify.net/", + "docs": "https://gotify.net/docs/" + }, + "tags": [ + "notifications", + "self-hosted", + "push" + ] + }, { "id": "grafana", "name": "Grafana", @@ -3189,7 +3206,7 @@ "id": "huly", "name": "Huly", "version": "0.6.377", - "description": "Huly — All-in-One Project Management Platform (alternative to Linear, Jira, Slack, Notion, Motion)", + "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", @@ -3747,7 +3764,7 @@ "id": "librechat", "name": "LibreChat", "version": "latest", - "description": "LibreChat is the ultimate open-source app for all your AI conversations, fully customizable and compatible with any AI provider (Openai, Ollama, Google etc.) — all in one sleek interface.", + "description": "LibreChat is the ultimate open-source app for all your AI conversations, fully customizable and compatible with any AI provider (Openai, Ollama, Google etc.) — all in one sleek interface.", "logo": "librechat.png", "links": { "github": "https://github.com/danny-avila/librechat", @@ -5174,7 +5191,7 @@ "id": "photoprism", "name": "Photoprism", "version": "latest", - "description": "PhotoPrism® is an AI-Powered Photos App for the Decentralized Web. It makes use of the latest technologies to tag and find pictures automatically without getting in your way.", + "description": "PhotoPrism® is an AI-Powered Photos App for the Decentralized Web. It makes use of the latest technologies to tag and find pictures automatically without getting in your way.", "logo": "photoprism.svg", "links": { "github": "https://github.com/photoprism/photoprism", @@ -6239,7 +6256,7 @@ "id": "surrealdb", "name": "SurrealDB", "version": "2.3.10", - "description": "SurrealDB is a native, open-source, multi-model database that lets you store and manage data across relational, document, graph, time-series, vector & search, and geospatial models—all in one place.", + "description": "SurrealDB is a native, open-source, multi-model database that lets you store and manage data across relational, document, graph, time-series, vector & search, and geospatial models—all in one place.", "logo": "surrealdb.svg", "links": { "github": "https://github.com/surrealdb/surrealdb", @@ -6511,7 +6528,7 @@ "id": "typecho", "name": "Typecho", "version": "stable", - "description": "Typecho 是一个轻量级的开源博客程序,基于 PHP 开发,支持多种数据库,简洁而强大。", + "description": "Typecho 是一个轻量级的开源博客程序,基于 PHP 开发,支持多种数据库,简洁而强大。", "logo": "typecho.png", "links": { "github": "https://github.com/typecho/typecho", From 7f722cdeab6c87871e67d54cc59190557635b879 Mon Sep 17 00:00:00 2001 From: Rohit Mulani Date: Tue, 7 Jul 2026 23:19:17 +0400 Subject: [PATCH 15/15] feat: add Firefly III template (#941) Co-authored-by: Rohit Mulani <289630555+rohitmulani63-ops@users.noreply.github.com> --- blueprints/firefly-iii/README.md | 13 +++++ blueprints/firefly-iii/docker-compose.yml | 65 +++++++++++++++++++++++ blueprints/firefly-iii/logo.svg | 14 +++++ blueprints/firefly-iii/template.toml | 36 +++++++++++++ meta.json | 17 ++++++ 5 files changed, 145 insertions(+) create mode 100644 blueprints/firefly-iii/README.md create mode 100644 blueprints/firefly-iii/docker-compose.yml create mode 100644 blueprints/firefly-iii/logo.svg create mode 100644 blueprints/firefly-iii/template.toml diff --git a/blueprints/firefly-iii/README.md b/blueprints/firefly-iii/README.md new file mode 100644 index 00000000..1687baf8 --- /dev/null +++ b/blueprints/firefly-iii/README.md @@ -0,0 +1,13 @@ +# Firefly III + +Firefly III is a self-hosted personal finance manager for budgets, accounts, transactions, categories, and reports. + +This Dokploy template includes: + +- Firefly III core web application +- MariaDB database with generated credentials +- Persistent upload and database volumes +- Daily cron runner using Firefly III's static cron token +- Dokploy domain routing on the application service + +After deployment, open the generated domain and complete the first-user setup flow. diff --git a/blueprints/firefly-iii/docker-compose.yml b/blueprints/firefly-iii/docker-compose.yml new file mode 100644 index 00000000..b9823407 --- /dev/null +++ b/blueprints/firefly-iii/docker-compose.yml @@ -0,0 +1,65 @@ +version: "3.8" + +services: + firefly-iii: + image: fireflyiii/core:version-6.6.3 + restart: unless-stopped + depends_on: + firefly-iii-db: + condition: service_healthy + environment: + APP_KEY: ${APP_KEY} + APP_URL: ${APP_URL} + TRUSTED_PROXIES: "**" + TZ: ${TZ} + SITE_OWNER: ${SITE_OWNER} + DEFAULT_LANGUAGE: ${DEFAULT_LANGUAGE} + DEFAULT_LOCALE: ${DEFAULT_LOCALE} + DB_CONNECTION: mysql + DB_HOST: firefly-iii-db + DB_PORT: 3306 + DB_DATABASE: ${DB_DATABASE} + DB_USERNAME: ${DB_USERNAME} + DB_PASSWORD: ${DB_PASSWORD} + STATIC_CRON_TOKEN: ${STATIC_CRON_TOKEN} + expose: + - "8080" + volumes: + - firefly-iii-upload:/var/www/html/storage/upload + + firefly-iii-db: + image: mariadb:11.8 + restart: unless-stopped + environment: + MYSQL_DATABASE: ${DB_DATABASE} + MYSQL_USER: ${DB_USERNAME} + MYSQL_PASSWORD: ${DB_PASSWORD} + MYSQL_RANDOM_ROOT_PASSWORD: "yes" + volumes: + - firefly-iii-db:/var/lib/mysql + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + interval: 10s + timeout: 5s + retries: 5 + + firefly-iii-cron: + image: alpine:3.22 + restart: unless-stopped + depends_on: + - firefly-iii + environment: + TZ: ${TZ} + STATIC_CRON_TOKEN: ${STATIC_CRON_TOKEN} + command: + - sh + - -c + - | + apk add --no-cache tzdata wget && \ + (ln -snf /usr/share/zoneinfo/$$TZ /etc/localtime || true) && \ + echo "0 3 * * * wget -qO- http://firefly-iii:8080/api/v1/cron/$$STATIC_CRON_TOKEN; echo" | crontab - && \ + crond -f -L /dev/stdout + +volumes: + firefly-iii-upload: {} + firefly-iii-db: {} diff --git a/blueprints/firefly-iii/logo.svg b/blueprints/firefly-iii/logo.svg new file mode 100644 index 00000000..8b4b7d2c --- /dev/null +++ b/blueprints/firefly-iii/logo.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/blueprints/firefly-iii/template.toml b/blueprints/firefly-iii/template.toml new file mode 100644 index 00000000..3f02a8ae --- /dev/null +++ b/blueprints/firefly-iii/template.toml @@ -0,0 +1,36 @@ +[variables] +main_domain = "${domain}" +app_key = "${base64:32}" +db_name = "firefly" +db_user = "firefly" +db_password = "${password:32}" +cron_token = "${hash:32}" +site_owner = "${email}" +timezone = "UTC" +default_language = "en_US" +default_locale = "equal" + +[config] +env = [ + "APP_KEY=base64:${app_key}", + "APP_URL=https://${main_domain}", + "TRUSTED_PROXIES=**", + "TZ=${timezone}", + "SITE_OWNER=${site_owner}", + "DEFAULT_LANGUAGE=${default_language}", + "DEFAULT_LOCALE=${default_locale}", + "DB_DATABASE=${db_name}", + "DB_USERNAME=${db_user}", + "DB_PASSWORD=${db_password}", + "STATIC_CRON_TOKEN=${cron_token}", + "MYSQL_DATABASE=${db_name}", + "MYSQL_USER=${db_user}", + "MYSQL_PASSWORD=${db_password}", + "MYSQL_RANDOM_ROOT_PASSWORD=yes" +] +mounts = [] + +[[config.domains]] +serviceName = "firefly-iii" +port = 8080 +host = "${main_domain}" diff --git a/meta.json b/meta.json index 83496f3b..f1dbb9fe 100644 --- a/meta.json +++ b/meta.json @@ -2414,6 +2414,23 @@ "llm" ] }, + { + "id": "firefly-iii", + "name": "Firefly III", + "version": "6.6.3", + "description": "Firefly III is a self-hosted personal finance manager for tracking expenses, budgets, accounts, and financial reports.", + "logo": "logo.svg", + "links": { + "github": "https://github.com/firefly-iii/firefly-iii", + "website": "https://www.firefly-iii.org/", + "docs": "https://docs.firefly-iii.org/" + }, + "tags": [ + "finance", + "budgeting", + "self-hosted" + ] + }, { "id": "fivem", "name": "FiveM Server",