diff --git a/AGENTS.md b/AGENTS.md
index c34d6beb..753da746 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -170,6 +170,16 @@ This document provides essential context for AI models interacting with this pro
- **Env:** Array of strings: `env = ["KEY=VALUE", "DB_PASSWORD=${db_pass}"]`
- **Available helpers:** `${domain}`, `${password:length}`, `${base64:length}`, `${hash:length}`, `${uuid}`, `${randomPort}`, `${email}`, `${username}`, `${timestamp}`, `${timestamps:datetime}`, `${timestampms:datetime}`, `${jwt:secret_var:payload_var}`
- **JWT helper example:** `${jwt:mysecret:mypayload}` with payload containing `exp: ${timestamps:2030-01-01T00:00:00Z}`
+ - **Volume bind mounts (in docker-compose.yml):** When mounting host paths, do NOT use absolute paths like `"/folder:/path/in/container"`. Use relative paths instead:
+ ```yaml
+ # Invalid
+ volumes:
+ - "/folder:/path/in/container" ❌
+ # Valid
+ volumes:
+ - "../files/my-database:/var/lib/mysql" ✅
+ - "../files/my-configs:/etc/my-app/config" ✅
+ ```
- **meta.json Requirements:**
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2671d5af..967ef6f2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -20,6 +20,11 @@ This project adheres to the [Contributor Covenant Code of Conduct](https://www.c
For larger changes or questions, open an issue first to discuss your ideas.
+### Pull Request Guidelines
+
+- **Keep PRs small and focused.** Avoid very large PRs; prefer several smaller PRs (e.g., one template or one logical change per PR). This speeds up review and keeps the history clear.
+- **Test before submitting.** Any PR that has not been tested by the contributor will be closed. This keeps the PR queue tidy and ensures that only contributions that have been verified by their authors are considered.
+
## Adding a New Template
To add a new template, follow these steps:
diff --git a/blueprints/alist/docker-compose.yml b/blueprints/alist/docker-compose.yml
index 9ff67c94..1577387f 100644
--- a/blueprints/alist/docker-compose.yml
+++ b/blueprints/alist/docker-compose.yml
@@ -1,7 +1,7 @@
version: '3.3'
services:
alist:
- image: xhofe/alist:v3.41.0
+ image: xhofe/alist:v3.55.0
volumes:
- alist-data:/opt/alist/data
environment:
diff --git a/blueprints/appsmith/docker-compose.yml b/blueprints/appsmith/docker-compose.yml
index f520ee36..e22be557 100644
--- a/blueprints/appsmith/docker-compose.yml
+++ b/blueprints/appsmith/docker-compose.yml
@@ -1,6 +1,10 @@
version: "3.8"
services:
appsmith:
- image: index.docker.io/appsmith/appsmith-ee:v1.29
+ image: appsmith/appsmith-ee:v1.94
volumes:
- - ../files/stacks:/appsmith-stacks
+ - appsmith-data:/appsmith-stacks
+ restart: unless-stopped
+
+volumes:
+ appsmith-data:
\ No newline at end of file
diff --git a/blueprints/budibase/docker-compose.yml b/blueprints/budibase/docker-compose.yml
index 92ad3288..17d08eef 100644
--- a/blueprints/budibase/docker-compose.yml
+++ b/blueprints/budibase/docker-compose.yml
@@ -1,8 +1,8 @@
services:
- apps:
- image: budibase.docker.scarf.sh/budibase/apps:3.5.3
- restart: unless-stopped
+ apps:
+ image: budibase/apps:3.23.47
+ restart: unless-stopped
environment:
SELF_HOSTED: 1
LOG_LEVEL: info
@@ -39,10 +39,10 @@ services:
timeout: 15s
retries: 5
start_period: 10s
- worker:
- image: budibase.docker.scarf.sh/budibase/worker:3.2.25
- restart: unless-stopped
+ worker:
+ image: budibase/worker:3.23.47
+ restart: unless-stopped
environment:
SELF_HOSTED: 1
LOG_LEVEL: info
@@ -78,10 +78,10 @@ services:
timeout: 15s
retries: 5
start_period: 10s
- minio:
- image: minio/minio:RELEASE.2024-11-07T00-52-20Z
- restart: unless-stopped
+ minio:
+ image: minio/minio:RELEASE.2025-09-07T16-13-09Z
+ restart: unless-stopped
volumes:
- 'minio_data:/data'
environment:
@@ -98,10 +98,10 @@ services:
interval: 30s
timeout: 20s
retries: 3
- proxy:
- image: budibase/proxy:3.2.25
- restart: unless-stopped
+ proxy:
+ image: budibase/proxy:3.23.47
+ restart: unless-stopped
environment:
PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND: 10
PROXY_RATE_LIMIT_API_PER_SECOND: 20
@@ -130,10 +130,10 @@ services:
timeout: 15s
retries: 5
start_period: 10s
+
couchdb:
image: budibase/couchdb:v3.3.3
restart: unless-stopped
-
environment:
COUCHDB_USER: budibase
COUCHDB_PASSWORD: ${BB_COUCHDB_PASSWORD}
@@ -150,9 +150,9 @@ services:
start_period: 10s
volumes:
- 'couchdb3_data:/opt/couchdb/data'
- redis:
- image: redis:7.2-alpine
+ redis:
+ image: redis:8.4-alpine
restart: unless-stopped
command: 'redis-server --requirepass "${BB_REDIS_PASSWORD}"'
volumes:
@@ -168,22 +168,9 @@ services:
timeout: 15s
retries: 5
start_period: 10s
- watchtower:
- restart: unless-stopped
-
- image: containrrr/watchtower:1.7.1
- volumes:
- - '/var/run/docker.sock:/var/run/docker.sock'
- command: '--debug --http-api-update bbapps bbworker bbproxy'
- environment:
- WATCHTOWER_HTTP_API: true
- WATCHTOWER_HTTP_API_TOKEN: ${BB_WATCHTOWER_PASSWORD}
- WATCHTOWER_CLEANUP: true
- labels:
- - com.centurylinklabs.watchtower.enable=false
volumes:
minio_data:
couchdb3_data:
- redis_data:
\ No newline at end of file
+ redis_data:
diff --git a/blueprints/habitica/docker-compose.yml b/blueprints/habitica/docker-compose.yml
index af226516..3990e571 100644
--- a/blueprints/habitica/docker-compose.yml
+++ b/blueprints/habitica/docker-compose.yml
@@ -1,13 +1,18 @@
-version: "3.8"
-
services:
server:
image: docker.io/awinterstein/habitica-server:latest
restart: unless-stopped
depends_on:
- - mongo
+ mongo:
+ condition: service_healthy
environment:
- - NODE_DB_URI=mongodb://mongo/habitica
+ NODE_DB_URI: "mongodb://${MONGO_HABITICA_USER}:${MONGO_HABITICA_PASSWORD}@mongo/habitica?authSource=habitica"
+ INVITE_ONLY: "${INVITE_ONLY}"
+ EMAIL_SERVER_URL: "${EMAIL_SERVER_URL}"
+ EMAIL_SERVER_PORT: "${EMAIL_SERVER_PORT}"
+ EMAIL_SERVER_AUTH_USER: "${EMAIL_SERVER_AUTH_USER}"
+ EMAIL_SERVER_AUTH_PASSWORD: "${EMAIL_SERVER_AUTH_PASSWORD}"
+ ADMIN_EMAIL: "${ADMIN_EMAIL}"
client:
image: docker.io/awinterstein/habitica-client:latest
@@ -20,12 +25,64 @@ services:
mongo:
image: docker.io/mongo:latest
restart: unless-stopped
- command: ["--replSet", "rs", "--bind_ip_all", "--port", "27017"]
+ command: >
+ bash -c "
+ echo \"${MONGO_KEYFILE_CONTENT}\" > /etc/mongo-keyfile &&
+ chown 999:999 /etc/mongo-keyfile &&
+ chmod 400 /etc/mongo-keyfile &&
+ exec docker-entrypoint.sh mongod --replSet rs --bind_ip_all --port 27017 --keyFile /etc/mongo-keyfile
+ "
+ environment:
+ MONGO_INITDB_ROOT_USERNAME: ${MONGO_ADMIN_USER}
+ MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ADMIN_PASSWORD}
+ MONGO_KEYFILE_CONTENT: ${MONGO_KEYFILE_CONTENT}
+ MONGO_HABITICA_USER: ${MONGO_HABITICA_USER}
+ MONGO_HABITICA_PASSWORD: ${MONGO_HABITICA_PASSWORD}
+ # ---------------------------------------------------------
+ # SMART HEALTHCHECK: Auto-fixes Hostname Mismatches for replicaSet
+ # ---------------------------------------------------------
healthcheck:
- test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27017 --quiet
- interval: 10s
- timeout: 30s
- retries: 30
+ test: |
+ mongosh --port 27017 --quiet -u "${MONGO_ADMIN_USER}" -p "${MONGO_ADMIN_PASSWORD}" --authenticationDatabase admin --eval "
+ try {
+ // 1. Hostname Fix
+ const config = rs.conf();
+ const currentHost = require('os').hostname() + ':27017';
+ if (config.members[0].host !== currentHost) {
+ config.members[0].host = currentHost;
+ rs.reconfig(config, { force: true });
+ }
+
+ // 2. User Creation Logic
+ const targetDb = db.getSiblingDB('habitica');
+ const hUser = process.env.MONGO_HABITICA_USER;
+ const hPass = process.env.MONGO_HABITICA_PASSWORD;
+
+ // We can only check/create users if we are Primary
+ if (rs.isMaster().ismaster) {
+ if (!targetDb.getUser(hUser)) {
+ print('Creating missing user ' + hUser + '...');
+ targetDb.createUser({ user: hUser, pwd: hPass, roles: ['readWrite'] });
+ }
+ // SUCCESS: User exists and we are Primary
+ quit(0);
+ } else {
+ // We are not Primary yet (still electing), so we cannot confirm user exists.
+ // Fail the check so the dependent app waits.
+ print('Waiting for Primary state...');
+ quit(1);
+ }
+ } catch (err) {
+ // If not initialized, initiate and FAIL this check so we wait for the next cycle
+ try {
+ rs.initiate({ _id: 'rs', members: [{ _id: 0, host: require('os').hostname() + ':27017' }] });
+ } catch (e) {}
+ quit(1);
+ }
+ "
+ interval: 5s
+ timeout: 10s
+ retries: 20
volumes:
- habitica-mongo-data:/data/db
diff --git a/blueprints/habitica/template.toml b/blueprints/habitica/template.toml
index 3888ae24..a8cb5fc6 100644
--- a/blueprints/habitica/template.toml
+++ b/blueprints/habitica/template.toml
@@ -1,6 +1,9 @@
[variables]
main_domain = "${domain}"
mail_password = "${password:32}"
+mongo_key = "${base64:756}"
+mongo_admin_password = "${password}"
+mongo_habitica_password = "${password}"
[config]
[[config.domains]]
@@ -9,16 +12,21 @@ port = 80
host = "habitica.${main_domain}"
[config.env]
-
-BASE_URL="https://habitica.${main_domain}"
-INVITE_ONLY="false"
-EMAIL_SERVER_URL="mail.example.com"
-EMAIL_SERVER_PORT="587"
-EMAIL_SERVER_AUTH_USER="mail_user"
-EMAIL_SERVER_AUTH_PASSWORD="${mail_password}"
+BASE_URL = "https://habitica.${main_domain}"
+INVITE_ONLY = "false"
+EMAIL_SERVER_URL = "mail.example.com"
+EMAIL_SERVER_PORT = "587"
+EMAIL_SERVER_AUTH_USER = "mail_user"
+EMAIL_SERVER_AUTH_PASSWORD = "${mail_password}"
+MONGO_KEYFILE_CONTENT = "${mongo_key}"
+MONGO_ADMIN_USER = "admin"
+MONGO_ADMIN_PASSWORD = "${mongo_admin_password}"
+MONGO_HABITICA_USER = "habitica"
+MONGO_HABITICA_PASSWORD = "${mongo_habitica_password}"
+ADMIN_EMAIL = "no-reply@${main_domain}"
[[config.mounts]]
serviceName = "mongo"
type = "volume"
source = "habitica-mongo-data"
-target = "/data/db"
\ No newline at end of file
+target = "/data/db"
diff --git a/blueprints/invoiceshelf/docker-compose.yml b/blueprints/invoiceshelf/docker-compose.yml
index 8d2c8265..bc4e8ff0 100644
--- a/blueprints/invoiceshelf/docker-compose.yml
+++ b/blueprints/invoiceshelf/docker-compose.yml
@@ -20,8 +20,7 @@ services:
image: invoiceshelf/invoiceshelf:nightly
volumes:
- - invoiceshelf-app-data:/data
- - invoiceshelf-app-conf:/conf
+ - invoiceshelf-storage:/var/www/html/storage
environment:
- PHP_TZ=UTC
- TIMEZONE=UTC
@@ -49,5 +48,4 @@ services:
volumes:
invoiceshelf-postgres-data:
- invoiceshelf-app-data:
- invoiceshelf-app-conf:
\ No newline at end of file
+ invoiceshelf-storage:
diff --git a/blueprints/ipfs/docker-compose.yml b/blueprints/ipfs/docker-compose.yml
new file mode 100644
index 00000000..4275f553
--- /dev/null
+++ b/blueprints/ipfs/docker-compose.yml
@@ -0,0 +1,17 @@
+version: "3.8"
+services:
+ ipfs:
+ image: ipfs/kubo:latest
+ restart: unless-stopped
+ environment:
+ - IPFS_PROFILE=server
+ volumes:
+ - ipfs_data:/data/ipfs
+ - ipfs_staging:/export
+ ports:
+ - 4001
+ - 8080
+ - 5001
+volumes:
+ ipfs_data: {}
+ ipfs_staging: {}
diff --git a/blueprints/ipfs/ipfs.svg b/blueprints/ipfs/ipfs.svg
new file mode 100644
index 00000000..1b90c313
--- /dev/null
+++ b/blueprints/ipfs/ipfs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/blueprints/ipfs/template.toml b/blueprints/ipfs/template.toml
new file mode 100644
index 00000000..89d4677e
--- /dev/null
+++ b/blueprints/ipfs/template.toml
@@ -0,0 +1,25 @@
+[variables]
+gateway_domain = "${domain}"
+api_domain = "${domain}"
+
+[config]
+env = []
+
+[[config.domains]]
+serviceName = "ipfs"
+port = 8080
+host = "${gateway_domain}"
+
+[[config.domains]]
+serviceName = "ipfs"
+port = 5001
+host = "${api_domain}"
+
+[[config.mounts]]
+filePath = "/container-init.d/001-configure-api.sh"
+content = """
+#!/bin/sh
+ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001
+ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
+ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "POST", "GET"]'
+"""
diff --git a/blueprints/nextcloud-aio/docker-compose.yml b/blueprints/nextcloud-aio/docker-compose.yml
index 1f4e43e6..f262b157 100644
--- a/blueprints/nextcloud-aio/docker-compose.yml
+++ b/blueprints/nextcloud-aio/docker-compose.yml
@@ -1,6 +1,6 @@
services:
nextcloud:
- image: nextcloud:30.0.2
+ image: nextcloud:32.0.5
restart: always
ports:
diff --git a/blueprints/postgres-pgdog/docker-compose.yml b/blueprints/postgres-pgdog/docker-compose.yml
new file mode 100644
index 00000000..f5164d9c
--- /dev/null
+++ b/blueprints/postgres-pgdog/docker-compose.yml
@@ -0,0 +1,33 @@
+services:
+ postgres-pgdog:
+ image: ${PGDOG_IMAGE}
+ restart: unless-stopped
+ # Uncomment 'ports' settings below to enable external access
+ # ports:
+ # - "6432:6432"
+ volumes:
+ - ../files/pgdog.toml:/pgdog/pgdog.toml
+ - ../files/users.toml:/pgdog/users.toml
+ environment:
+ - RUST_LOG=${RUST_LOG}
+ depends_on:
+ postgres:
+ condition: service_healthy
+
+ postgres:
+ image: ${POSTGRES_IMAGE}
+ restart: unless-stopped
+ environment:
+ - POSTGRES_USER=${POSTGRES_USER}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+ - POSTGRES_DB=${POSTGRES_DB}
+ volumes:
+ - postgres-data:/var/lib/postgresql
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+volumes:
+ postgres-data:
diff --git a/blueprints/postgres-pgdog/postgres-pgdog.png b/blueprints/postgres-pgdog/postgres-pgdog.png
new file mode 100644
index 00000000..bbc4aae7
Binary files /dev/null and b/blueprints/postgres-pgdog/postgres-pgdog.png differ
diff --git a/blueprints/postgres-pgdog/template.toml b/blueprints/postgres-pgdog/template.toml
new file mode 100644
index 00000000..2ffc4ec0
--- /dev/null
+++ b/blueprints/postgres-pgdog/template.toml
@@ -0,0 +1,36 @@
+[variables]
+postgres_user = "${username}"
+postgres_password = "${password:32}"
+postgres_db = "postgres"
+pgdog_image = "ghcr.io/pgdogdev/pgdog:v0.1.26"
+postgres_image = "postgres:18-alpine"
+
+[[config.mounts]]
+filePath = "pgdog.toml"
+content = """
+[general]
+host = "0.0.0.0"
+port = 6432
+
+[[databases]]
+name = "${postgres_db}"
+host = "postgres"
+port = 5432
+"""
+
+[[config.mounts]]
+filePath = "users.toml"
+content = """
+[[users]]
+name = "${postgres_user}"
+database = "${postgres_db}"
+password = "${postgres_password}"
+"""
+
+[config.env]
+POSTGRES_USER = "${postgres_user}"
+POSTGRES_PASSWORD = "${postgres_password}"
+POSTGRES_DB = "${postgres_db}"
+PGDOG_IMAGE = "${pgdog_image}"
+POSTGRES_IMAGE = "${postgres_image}"
+RUST_LOG = "info"
diff --git a/blueprints/pulse/docker-compose.yml b/blueprints/pulse/docker-compose.yml
new file mode 100644
index 00000000..074aec07
--- /dev/null
+++ b/blueprints/pulse/docker-compose.yml
@@ -0,0 +1,22 @@
+version: "3.8"
+services:
+ pulse:
+ image: rcourtman/pulse:5.1
+ restart: always
+ expose:
+ - 7655
+ volumes:
+ - pulse_data:/data
+ - /var/run/docker.sock:/var/run/docker.sock
+ environment:
+ - PULSE_AUTH_USER=${PULSE_AUTH_USER}
+ - PULSE_AUTH_PASS=${PULSE_AUTH_PASS}
+ healthcheck:
+ test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:7655/api/health"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 40s
+
+volumes:
+ pulse_data:
\ No newline at end of file
diff --git a/blueprints/pulse/pulse.svg b/blueprints/pulse/pulse.svg
new file mode 100644
index 00000000..428a6e54
--- /dev/null
+++ b/blueprints/pulse/pulse.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/blueprints/pulse/template.toml b/blueprints/pulse/template.toml
new file mode 100644
index 00000000..865990c4
--- /dev/null
+++ b/blueprints/pulse/template.toml
@@ -0,0 +1,13 @@
+[variables]
+main_domain = "${domain}"
+pulse_auth_user = "${username}"
+pulse_auth_pass = "${password:32}"
+
+[config]
+env = ["PULSE_AUTH_USER=${pulse_auth_user}", "PULSE_AUTH_PASS=${pulse_auth_pass}"]
+mounts = []
+
+[[config.domains]]
+serviceName = "pulse"
+port = 7_655
+host = "${main_domain}"
\ No newline at end of file
diff --git a/blueprints/seaweedfs/docker-compose.yml b/blueprints/seaweedfs/docker-compose.yml
new file mode 100644
index 00000000..ca4a0968
--- /dev/null
+++ b/blueprints/seaweedfs/docker-compose.yml
@@ -0,0 +1,114 @@
+services:
+ master:
+ image: chrislusf/seaweedfs:4.02
+ command: >
+ -v=0
+ master
+ -volumeSizeLimitMB=10240
+ -ip=master
+ -ip.bind=0.0.0.0
+ -port=9333
+ -mdir=/data/master
+ volumes:
+ - seaweedfs-master:/data/master
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD", "wget", "-q", "--spider", "http://localhost:9333"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ expose:
+ - 9333
+ deploy:
+ resources:
+ limits:
+ memory: 512M
+ reservations:
+ memory: 256M
+
+ volume:
+ image: chrislusf/seaweedfs:4.02
+ command: >
+ -v=0
+ volume
+ -mserver="master:9333"
+ -port=8080
+ -dir=/data/volume
+ -max=100
+ volumes:
+ - seaweedfs-volume:/data/volume
+ depends_on:
+ master:
+ condition: service_healthy
+ restart: unless-stopped
+ expose:
+ - 8080
+ deploy:
+ resources:
+ limits:
+ memory: 1G
+ reservations:
+ memory: 512M
+
+ filer:
+ image: chrislusf/seaweedfs:4.02
+ command: >
+ -v=0
+ filer
+ -defaultReplicaPlacement=000
+ -master="master:9333"
+ -ip=filer
+ -ip.bind=0.0.0.0
+ -port=8888
+ environment:
+ - WEED_MASTER=master:9333
+ volumes:
+ - seaweedfs-filer:/data
+ depends_on:
+ - master
+ - volume
+ restart: unless-stopped
+ # # Secure the GUI with username/password
+ # labels:
+ # # htpasswd -nb admin admin
+ # - "traefik.http.middlewares.basic-auth.basicauth.users=admin:$$apr1$$aLLYxhdC$$ZAW26eJfBRC8qWjCkcZns."
+ # - "traefik.http.routers.service-name.middlewares=basic-auth"
+ healthcheck:
+ test: ["CMD", "wget", "-q", "--spider", "http://localhost:8888"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ deploy:
+ resources:
+ limits:
+ memory: 1G
+ reservations:
+ memory: 512M
+ expose:
+ - 8888
+
+ s3:
+ image: chrislusf/seaweedfs:4.02
+ command: >
+ -v=0
+ s3
+ -filer="filer:8888"
+ -ip.bind=0.0.0.0
+ -port=8333
+ environment:
+ - AWS_ACCESS_KEY_ID=${S3_ACCESS_KEY}
+ - AWS_SECRET_ACCESS_KEY=${S3_SECRET_KEY}
+ restart: unless-stopped
+ deploy:
+ resources:
+ limits:
+ memory: 512M
+ reservations:
+ memory: 256M
+ expose:
+ - 8333
+
+volumes:
+ seaweedfs-master:
+ seaweedfs-volume:
+ seaweedfs-filer:
diff --git a/blueprints/seaweedfs/seaweedfs.svg b/blueprints/seaweedfs/seaweedfs.svg
new file mode 100644
index 00000000..61fce568
--- /dev/null
+++ b/blueprints/seaweedfs/seaweedfs.svg
@@ -0,0 +1,317 @@
+
+
+
+
diff --git a/blueprints/seaweedfs/template.toml b/blueprints/seaweedfs/template.toml
new file mode 100644
index 00000000..a72ae280
--- /dev/null
+++ b/blueprints/seaweedfs/template.toml
@@ -0,0 +1,27 @@
+[variables]
+main_domain = "${domain}"
+filer_domain = "filer.${domain}"
+master_domain = "master.${domain}"
+s3_domain = "s3.${domain}"
+
+[config]
+mounts = []
+
+[[config.domains]]
+serviceName = "filer"
+port = 8888
+host = "${filer_domain}"
+
+[[config.domains]]
+serviceName = "master"
+port = 9333
+host = "${master_domain}"
+
+[[config.domains]]
+serviceName = "s3"
+port = 8333
+host = "${s3_domain}"
+
+[config.env]
+S3_ACCESS_KEY = "admin"
+S3_SECRET_KEY = "${password:16}"
diff --git a/blueprints/strapi/docker-compose.yml b/blueprints/strapi/docker-compose.yml
new file mode 100644
index 00000000..6ac724fc
--- /dev/null
+++ b/blueprints/strapi/docker-compose.yml
@@ -0,0 +1,58 @@
+# Self-host guide:
+# - https://strapi.io/blog/how-to-self-host-your-headless-cms-using-docker-compose
+
+services:
+ strapi:
+ image: elestio/strapi-production:v5.33.0
+ environment:
+ # https://docs.strapi.io/cms/configurations/environment
+ NODE_ENV: production
+ STRAPI_TELEMETRY_DISABLED: true
+ STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE: en
+ FAST_REFRESH: true
+ JWT_SECRET: ${JWT_SECRET}
+ ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET}
+ DATABASE_CLIENT: postgres
+ DATABASE_HOST: strapi_postgres
+ DATABASE_PORT: 5432
+ DATABASE_NAME: strapi
+ DATABASE_USERNAME: strapi
+ DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
+ volumes:
+ - strapi_data:/srv/app
+ expose:
+ - 1337
+ depends_on:
+ - strapi_postgres
+ healthcheck:
+ test:
+ - CMD
+ - wget
+ - "-q"
+ - "--spider"
+ - "http://127.0.0.1:1337"
+ start_period: 3s
+ interval: 30s
+ timeout: 10s
+ retries: 5
+
+ strapi_postgres:
+ image: postgres:18
+ environment:
+ POSTGRES_DB: strapi
+ POSTGRES_USER: strapi
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+ volumes:
+ - strapi_postgres_data:/var/lib/postgresql
+ healthcheck:
+ test:
+ - CMD-SHELL
+ - "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
+ start_period: 3s
+ interval: 30s
+ timeout: 10s
+ retries: 5
+
+volumes:
+ strapi_data:
+ strapi_postgres_data:
diff --git a/blueprints/strapi/strapi.svg b/blueprints/strapi/strapi.svg
new file mode 100644
index 00000000..1e4ed993
--- /dev/null
+++ b/blueprints/strapi/strapi.svg
@@ -0,0 +1,23 @@
+
diff --git a/blueprints/strapi/template.toml b/blueprints/strapi/template.toml
new file mode 100644
index 00000000..0acddaf5
--- /dev/null
+++ b/blueprints/strapi/template.toml
@@ -0,0 +1,15 @@
+[variables]
+main_domain = "${domain}"
+postgres_password = "${password:32}"
+jwt_secret = "${password:32}"
+admin_jwt_secret = "${password:32}"
+
+[[config.domains]]
+serviceName = "strapi"
+port = 1337
+host = "${main_domain}"
+
+[config.env]
+POSTGRES_PASSWORD = "${postgres_password}"
+JWT_SECRET = "${jwt_secret}"
+ADMIN_JWT_SECRET = "${admin_jwt_secret}"
diff --git a/blueprints/supabase/docker-compose.yml b/blueprints/supabase/docker-compose.yml
index 7d4dae81..506ddc90 100644
--- a/blueprints/supabase/docker-compose.yml
+++ b/blueprints/supabase/docker-compose.yml
@@ -77,6 +77,7 @@ services:
SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
DASHBOARD_USERNAME: ${DASHBOARD_USERNAME}
DASHBOARD_PASSWORD: ${DASHBOARD_PASSWORD}
+ CONTAINER_PREFIX: ${CONTAINER_PREFIX}
# https://unix.stackexchange.com/a/294837
entrypoint: bash -c 'eval "echo \"$$(cat ~/temp.yml)\"" > ~/kong.yml && /docker-entrypoint.sh kong docker-start'
diff --git a/blueprints/supabase/template.toml b/blueprints/supabase/template.toml
index 9f35f79c..f70c93cc 100644
--- a/blueprints/supabase/template.toml
+++ b/blueprints/supabase/template.toml
@@ -309,7 +309,7 @@ services:
## Secure Realtime routes
- name: realtime-v1-ws
_comment: 'Realtime: /realtime/v1/* -> ws://realtime:4000/socket/*'
- url: http://realtime-dev.supabase-realtime:4000/socket
+ url: http://realtime-dev.${CONTAINER_PREFIX}-realtime:4000/socket
protocol: ws
routes:
- name: realtime-v1-ws
@@ -329,7 +329,7 @@ services:
- anon
- name: realtime-v1-rest
_comment: 'Realtime: /realtime/v1/* -> ws://realtime:4000/socket/*'
- url: http://realtime-dev.supabase-realtime:4000/api
+ url: http://realtime-dev.${CONTAINER_PREFIX}-realtime:4000/api
protocol: http
routes:
- name: realtime-v1-rest
@@ -850,7 +850,7 @@ transforms:
kong: '.appname == "supabase-kong"'
auth: '.appname == "supabase-auth"'
rest: '.appname == "supabase-rest"'
- realtime: '.appname == "realtime-dev.supabase-realtime"'
+ realtime: '.appname == "realtime-dev.${CONTAINER_PREFIX}-realtime"'
storage: '.appname == "supabase-storage"'
functions: '.appname == "supabase-edge-functions"'
db: '.appname == "supabase-db"'
diff --git a/blueprints/superset/docker-compose.yml b/blueprints/superset/docker-compose.yml
index 076fe0a8..3a20fd04 100644
--- a/blueprints/superset/docker-compose.yml
+++ b/blueprints/superset/docker-compose.yml
@@ -15,23 +15,14 @@
# ## NETWORK INSTRUCTIONS
#
# If you want to connect superset with other internal databases managed by
-# Dokploy (on dokploy-network) using internal hostnames, you will need to
-# uncomment the `networks` section, both for the superset container and
-# at the very bottom of this docker-compose template.
+# Dokploy using internal hostnames, you will need to connect the `superset`
+# container to those networks.
#
-# Note that the `superset` service name/hostname will not be unique on the
-# global `dokploy-network`. If you plan to:
-#
-# 1. deploy a second instance of superset on dokploy-network, and
-# 2. have other containers on dokploy-network utilise the second instance's
-# Superset API (https://superset.apache.org/docs/api)
-#
-# Please change the service name of the second instance.
services:
superset:
- image: amancevice/superset
- restart: always
+ image: amancevice/superset:6.0.0
+ restart: unless-stopped
#networks:
# - dokploy-network
depends_on:
@@ -52,14 +43,14 @@ services:
REDIS_HOST: superset_redis
superset_postgres:
- image: postgres
- restart: always
+ image: postgres:18
+ restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- - superset_postgres_data:/var/lib/postgresql/data
+ - superset_postgres_data:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 30s
@@ -67,8 +58,8 @@ services:
retries: 3
superset_redis:
- image: redis
- restart: always
+ image: redis:8
+ restart: unless-stopped
volumes:
- superset_redis_data:/data
command: redis-server --requirepass ${REDIS_PASSWORD}
@@ -78,10 +69,6 @@ services:
timeout: 10s
retries: 3
-#networks:
-# dokploy-network:
-# external: true
-
volumes:
superset_postgres_data:
superset_redis_data:
diff --git a/blueprints/superset/template.toml b/blueprints/superset/template.toml
index ec4535fd..7cee12fc 100644
--- a/blueprints/superset/template.toml
+++ b/blueprints/superset/template.toml
@@ -3,7 +3,6 @@ main_domain = "${domain}"
secret_key = "${password:30}"
postgres_password = "${password:30}"
redis_password = "${password:30}"
-mapbox_api_key = ""
[[config.domains]]
serviceName = "superset"
@@ -12,7 +11,7 @@ host = "${main_domain}"
[config.env]
SECRET_KEY = "${secret_key}"
-MAPBOX_API_KEY = "${mapbox_api_key}"
+MAPBOX_API_KEY = ""
POSTGRES_DB = "superset"
POSTGRES_USER = "superset"
POSTGRES_PASSWORD = "${postgres_password}"
diff --git a/blueprints/trilium-next/docker-compose.yml b/blueprints/trilium-next/docker-compose.yml
new file mode 100755
index 00000000..6ffc82a5
--- /dev/null
+++ b/blueprints/trilium-next/docker-compose.yml
@@ -0,0 +1,23 @@
+# Running `docker-compose up` will create/use the "trilium-data" directory in the user home
+services:
+ trilium_next:
+ # Optionally, replace `latest` with a version tag like `v0.110.3`
+ # Using `latest` may cause unintended updates to the container
+ image: triliumnext/trilium:v0.101.3
+ # Restart the container unless it was stopped by the user
+ restart: unless-stopped
+ environment:
+ - TRILIUM_DATA_DIR=/home/node/trilium-data
+ ports:
+ # By default, Trilium will be available at http://localhost:8080
+ # It will also be accessible at http://:8080
+ # You might want to limit this with something like Docker Networks, reverse proxies, or firewall rules,
+ # however be aware that using UFW is known to not work with default Docker installations, see:
+ # https://docs.docker.com/engine/network/packet-filtering-firewalls/#docker-and-ufw
+ - "8080"
+ volumes:
+ # Unless TRILIUM_DATA_DIR is set, the data will be stored in the "trilium-data" directory in the home directory.
+ # This can also be changed with by replacing the line below with `- /path/of/your/choice:/home/node/trilium-data
+ - ${TRILIUM_DATA_DIR:-~/trilium-data}:/home/node/trilium-data
+ - /etc/timezone:/etc/timezone:ro
+ - /etc/localtime:/etc/localtime:ro
diff --git a/blueprints/trilium-next/template.toml b/blueprints/trilium-next/template.toml
new file mode 100755
index 00000000..0292bb68
--- /dev/null
+++ b/blueprints/trilium-next/template.toml
@@ -0,0 +1,13 @@
+[variables]
+main_domain = "${domain}"
+
+[config]
+env = [
+"TRILIUM_DATA_DIR=/root"
+]
+mount = []
+
+[[config.domains]]
+serviceName = "trilium_next"
+port = 8080
+host = "${main_domain}"
diff --git a/blueprints/trilium-next/trilium-next-logo.svg b/blueprints/trilium-next/trilium-next-logo.svg
new file mode 100644
index 00000000..79f47a82
--- /dev/null
+++ b/blueprints/trilium-next/trilium-next-logo.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/blueprints/trmnl-byos-laravel/docker-compose.yml b/blueprints/trmnl-byos-laravel/docker-compose.yml
index f571719d..61674d23 100644
--- a/blueprints/trmnl-byos-laravel/docker-compose.yml
+++ b/blueprints/trmnl-byos-laravel/docker-compose.yml
@@ -1,6 +1,6 @@
services:
trmnl-byos-laravel:
- image: ghcr.io/usetrmnl/byos_laravel:0.21.0
+ image: ghcr.io/usetrmnl/byos_laravel:0.27.0
environment:
- APP_URL=${APP_URL}
- PHP_OPCACHE_ENABLE=${PHP_OPCACHE_ENABLE}
diff --git a/blueprints/uptime-kuma/docker-compose.yml b/blueprints/uptime-kuma/docker-compose.yml
index ca80a8a3..f50c2013 100644
--- a/blueprints/uptime-kuma/docker-compose.yml
+++ b/blueprints/uptime-kuma/docker-compose.yml
@@ -1,7 +1,7 @@
version: "3.8"
services:
uptime-kuma:
- image: louislam/uptime-kuma:1.23.15
+ image: louislam/uptime-kuma:2.1.0
restart: always
volumes:
- uptime-kuma-data:/app/data
diff --git a/blueprints/vikunja/docker-compose.yml b/blueprints/vikunja/docker-compose.yml
index 11b744b0..0d1c7fbe 100644
--- a/blueprints/vikunja/docker-compose.yml
+++ b/blueprints/vikunja/docker-compose.yml
@@ -1,17 +1,17 @@
-version: "3.8"
-
services:
vikunja:
image: vikunja/vikunja
+ user: "0:0"
environment:
- VIKUNJA_SERVICE_PUBLICURL: http://vikunja.local
- VIKUNJA_DATABASE_HOST: db
+ VIKUNJA_SERVICE_PUBLICURL: ${VIKUNJA_SERVICE_PUBLICURL}
+ VIKUNJA_PUBLIC_PORT: ${VIKUNJA_PUBLIC_PORT}
+ VIKUNJA_DATABASE_HOST: ${VIKUNJA_DATABASE_HOST}
VIKUNJA_DATABASE_PASSWORD: ${VIKUNJA_DATABASE_PASSWORD}
- VIKUNJA_DATABASE_TYPE: postgres
- VIKUNJA_DATABASE_USER: vikunja
- VIKUNJA_DATABASE_DATABASE: vikunja
+ VIKUNJA_DATABASE_TYPE: ${VIKUNJA_DATABASE_TYPE}
+ VIKUNJA_DATABASE_USER: ${VIKUNJA_DATABASE_USER}
+ VIKUNJA_DATABASE_DATABASE: ${VIKUNJA_DATABASE_DATABASE}
VIKUNJA_SERVICE_JWTSECRET: ${VIKUNJA_SERVICE_JWTSECRET}
- expose:
+ ports:
- 3456
volumes:
- vikunja-files:/app/vikunja/files
@@ -24,15 +24,16 @@ services:
image: postgres:17
environment:
POSTGRES_PASSWORD: ${VIKUNJA_DATABASE_PASSWORD}
- POSTGRES_USER: vikunja
- POSTGRES_DB: vikunja
+ POSTGRES_USER: ${VIKUNJA_DATABASE_USER}
+ POSTGRES_DB: ${VIKUNJA_DATABASE_DATABASE}
volumes:
- vikunja-db:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
- test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER"]
- interval: 2s
- start_period: 30s
+ test: ["CMD-SHELL", "pg_isready", "-U", "${VIKUNJA_DATABASE_USER}", "-d", "${VIKUNJA_DATABASE_DATABASE}"]
+ interval: 10s
+ timeout: 5s
+ retries: 3
volumes:
vikunja-files: {}
diff --git a/blueprints/vikunja/template.toml b/blueprints/vikunja/template.toml
index 0a4e88f9..1740d3e6 100644
--- a/blueprints/vikunja/template.toml
+++ b/blueprints/vikunja/template.toml
@@ -18,10 +18,6 @@ VIKUNJA_DATABASE_USER = "vikunja"
VIKUNJA_DATABASE_DATABASE = "vikunja"
VIKUNJA_SERVICE_JWTSECRET = "${jwt_secret}"
-POSTGRES_PASSWORD = "${db_password}"
-POSTGRES_USER = "vikunja"
-POSTGRES_DB = "vikunja"
-
[[config.mounts]]
serviceName = "vikunja"
volumeName = "vikunja-files"
diff --git a/blueprints/wg-easy/docker-compose.yml b/blueprints/wg-easy/docker-compose.yml
index 1161bb12..0a98f6d9 100644
--- a/blueprints/wg-easy/docker-compose.yml
+++ b/blueprints/wg-easy/docker-compose.yml
@@ -3,24 +3,23 @@ volumes:
services:
wg-easy:
- image: ghcr.io/wg-easy/wg-easy:15
- restart: unless-stopped
environment:
- - WG_HOST=${WIREGUARD_HOST}
- - PASSWORD=${WIREGUARD_PASSWORD}
- - WG_PORT=51820
+ - INIT_ENABLED=1
+ - INIT_HOST=${WIREGUARD_HOST}
+ - INIT_PORT=51820
+ - INIT_USERNAME=admin
+ - INIT_PASSWORD=${WIREGUARD_PASSWORD}
+ - INIT_DNS=1.1.1.1,8.8.8.8
- PORT=51821
- - WG_MTU=1280
- - WG_DEFAULT_DNS=1.1.1.1,8.8.8.8
- - WG_ALLOWED_IPS=0.0.0.0/0
- - WG_POST_UP=iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT;
- - WG_POST_DOWN=iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT;
+ image: ghcr.io/wg-easy/wg-easy:15
+ container_name: wg-easy
volumes:
- etc_wireguard:/etc/wireguard
- /lib/modules:/lib/modules:ro
ports:
- "51820:51820/udp"
- "51821:51821/tcp"
+ restart: unless-stopped
cap_add:
- NET_ADMIN
- SYS_MODULE
diff --git a/blueprints/wuzapi/docker-compose.yml b/blueprints/wuzapi/docker-compose.yml
new file mode 100644
index 00000000..87b5b8b8
--- /dev/null
+++ b/blueprints/wuzapi/docker-compose.yml
@@ -0,0 +1,36 @@
+version: "3.8"
+services:
+ wuzapi-server:
+ image: asternic/wuzapi:sha-30c1805
+ restart: unless-stopped
+ expose:
+ - 8080
+ environment:
+ - WUZAPI_ADMIN_TOKEN=${WUZAPI_ADMIN_TOKEN}
+ - WUZAPI_GLOBAL_ENCRYPTION_KEY=${WUZAPI_GLOBAL_ENCRYPTION_KEY}
+ - DB_USER=${DB_USER:-wuzapi}
+ - DB_PASSWORD=${DB_PASSWORD:-wuzapi}
+ - DB_NAME=${DB_NAME:-wuzapi}
+ - DB_HOST=db
+ - DB_PORT=5432
+ - TZ=${TZ:-UTC}
+ depends_on:
+ - db
+
+ db:
+ image: postgres:16-alpine
+ restart: always
+ environment:
+ POSTGRES_USER: ${DB_USER:-wuzapi}
+ POSTGRES_PASSWORD: ${DB_PASSWORD:-wuzapi}
+ POSTGRES_DB: ${DB_NAME:-wuzapi}
+ volumes:
+ - db_data:/var/lib/postgresql/data
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U $${DB_USER:-wuzapi}"]
+ interval: 5s
+ timeout: 5s
+ retries: 5
+
+volumes:
+ db_data:
diff --git a/blueprints/wuzapi/template.toml b/blueprints/wuzapi/template.toml
new file mode 100644
index 00000000..71d95c49
--- /dev/null
+++ b/blueprints/wuzapi/template.toml
@@ -0,0 +1,20 @@
+[variables]
+main_domain = "${domain}"
+admin_token = "${password:32}"
+encryption_key = "${password:32}"
+db_user = "wuzapi"
+db_password = "${password:32}"
+db_name = "wuzapi"
+
+[config]
+[[config.domains]]
+serviceName = "wuzapi-server"
+port = 8080
+host = "${main_domain}"
+
+[config.env]
+WUZAPI_ADMIN_TOKEN = "${admin_token}"
+WUZAPI_GLOBAL_ENCRYPTION_KEY = "${encryption_key}"
+DB_USER = "${db_user}"
+DB_PASSWORD = "${db_password}"
+DB_NAME = "${db_name}"
diff --git a/blueprints/wuzapi/wuzapi.png b/blueprints/wuzapi/wuzapi.png
new file mode 100644
index 00000000..f48f5d33
Binary files /dev/null and b/blueprints/wuzapi/wuzapi.png differ
diff --git a/meta.json b/meta.json
index f7dca105..42cdf342 100644
--- a/meta.json
+++ b/meta.json
@@ -164,13 +164,13 @@
{
"id": "alist",
"name": "AList",
- "version": "v3.41.0",
+ "version": "v3.55.0",
"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",
- "website": "https://alist.nn.ci",
- "docs": "https://alist.nn.ci/guide/install/docker.html"
+ "website": "https://alistgo.com/",
+ "docs": "https://alistgo.com/guide/install/docker.html"
},
"tags": [
"file",
@@ -350,7 +350,7 @@
{
"id": "appsmith",
"name": "Appsmith",
- "version": "v1.29",
+ "version": "v1.94",
"description": "Appsmith is a free and open source platform for building internal tools and applications.",
"logo": "appsmith.png",
"links": {
@@ -896,7 +896,7 @@
{
"id": "budibase",
"name": "Budibase",
- "version": "3.5.3",
+ "version": "3.23.47",
"description": "Budibase is an open-source low-code platform that saves engineers 100s of hours building forms, portals, and approval apps, securely.",
"logo": "budibase.svg",
"links": {
@@ -3204,6 +3204,24 @@
"finance"
]
},
+ {
+ "id": "ipfs",
+ "name": "IPFS (Kubo)",
+ "version": "latest",
+ "description": "IPFS (Kubo) is a decentralized peer-to-peer file sharing and storage network node. Host your own IPFS gateway and API.",
+ "logo": "ipfs.svg",
+ "links": {
+ "github": "https://github.com/ipfs/kubo",
+ "website": "https://ipfs.tech/",
+ "docs": "https://docs.ipfs.tech/"
+ },
+ "tags": [
+ "storage",
+ "decentralized",
+ "p2p",
+ "self-hosted"
+ ]
+ },
{
"id": "it-tools",
"name": "IT Tools",
@@ -4367,8 +4385,8 @@
"description": "Obsidian LiveSync with CouchDB for real-time note synchronization.",
"logo": "obsidian.png",
"links": {
- "github": "https://github.com/apache/couchdb",
- "website": "https://couchdb.apache.org/",
+ "github": "https://github.com/vrtmrz/obsidian-livesync",
+ "website": "https://obsidian.md/sync",
"docs": "https://docs.couchdb.apache.org/"
},
"tags": [
@@ -5127,6 +5145,25 @@
"webmail"
]
},
+ {
+ "id": "postgres-pgdog",
+ "name": "PostgreSQL with PgDog",
+ "version": "0.1.26",
+ "description": "PostgreSQL database with PgDog connection pooler, load balancer, and horizontal scaling proxy. A modern alternative to PgBouncer with multi-threading support.",
+ "logo": "postgres-pgdog.png",
+ "links": {
+ "github": "https://github.com/pgdogdev/pgdog",
+ "website": "https://pgdog.dev",
+ "docs": "https://docs.pgdog.dev"
+ },
+ "tags": [
+ "database",
+ "postgresql",
+ "pooler",
+ "proxy",
+ "load-balancer"
+ ]
+ },
{
"id": "postgresus",
"name": "Postgresus",
@@ -5213,6 +5250,24 @@
"management"
]
},
+ {
+ "id": "pulse",
+ "name": "Pulse",
+ "version": "latest",
+ "description": "A responsive monitoring platform for Proxmox VE, PBS, and Docker with real-time metrics across nodes and containers.",
+ "logo": "pulse.svg",
+ "links": {
+ "github": "https://github.com/rcourtman/Pulse",
+ "website": "https://pulserelay.pro/",
+ "docs": "https://github.com/rcourtman/Pulse/blob/main/docs/README.md"
+ },
+ "tags": [
+ "monitoring",
+ "proxmox",
+ "docker",
+ "metrics"
+ ]
+ },
{
"id": "pyrodactyl",
"name": "Pyrodactyl",
@@ -5593,6 +5648,25 @@
"aggregator"
]
},
+ {
+ "id": "seaweedfs",
+ "name": "SeaweedFS",
+ "version": "latest",
+ "description": "SeaweedFS is a fast distributed storage system for blobs, objects, and files. Features S3-compatible API, POSIX FUSE mount, and WebDAV support.",
+ "logo": "seaweedfs.svg",
+ "links": {
+ "github": "https://github.com/seaweedfs/seaweedfs",
+ "website": "https://seaweedfs.com/",
+ "docs": "https://github.com/seaweedfs/seaweedfs/wiki"
+ },
+ "tags": [
+ "storage",
+ "s3",
+ "distributed",
+ "object-storage",
+ "file-system"
+ ]
+ },
{
"id": "shlink",
"name": "Shlink",
@@ -5824,6 +5898,24 @@
"media"
]
},
+ {
+ "id": "strapi",
+ "name": "Strapi",
+ "version": "v5.33.0",
+ "description": "Open-source headless CMS to build powerful APIs with built-in content management.",
+ "logo": "strapi.svg",
+ "links": {
+ "github": "https://github.com/strapi/strapi",
+ "discord": "https://discord.com/invite/strapi",
+ "docs": "https://docs.strapi.io",
+ "website": "https://strapi.io"
+ },
+ "tags": [
+ "headless",
+ "cms",
+ "content-management"
+ ]
+ },
{
"id": "supabase",
"name": "SupaBase",
@@ -5845,7 +5937,7 @@
{
"id": "superset",
"name": "Superset (Unofficial)",
- "version": "latest",
+ "version": "6.0.0",
"description": "Data visualization and data exploration platform.",
"logo": "superset.svg",
"links": {
@@ -6049,10 +6141,27 @@
"personal-use"
]
},
+ {
+ "id": "trilium-next",
+ "name": "TriliumNext",
+ "version": "latest",
+ "description": "Is a free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.",
+ "logo": "trilium-next-logo.svg",
+ "links": {
+ "github": "https://github.com/TriliumNext/Trilium",
+ "website": "https://triliumnotes.org/",
+ "docs": "https://docs.triliumnotes.org/"
+ },
+ "tags": [
+ "self-hosted",
+ "productivity",
+ "personal-use"
+ ]
+ },
{
"id": "trmnl-byos-laravel",
"name": "TRMNL BYOS Laravel",
- "version": "0.21.0",
+ "version": "0.27.0",
"description": "TRMNL BYOS Laravel is a self-hosted application to manage TRMNL e-ink devices.",
"logo": "byos-laravel.svg",
"links": {
@@ -6182,7 +6291,7 @@
{
"id": "uptime-kuma",
"name": "Uptime Kuma",
- "version": "1.23.15",
+ "version": "2.1.0",
"description": "Uptime Kuma is a free and open source monitoring tool that allows you to monitor your websites and applications.",
"logo": "uptime-kuma.png",
"links": {
@@ -6270,7 +6379,7 @@
"description": "Vikunja is a self-hosted, open-source to-do list application to organize tasks, projects, and notes.",
"logo": "image.png",
"links": {
- "github": "https://kolaente.dev/vikunja/",
+ "github": "https://github.com/go-vikunja/vikunja",
"website": "https://vikunja.io/",
"docs": "https://vikunja.io/docs/"
},
@@ -6419,6 +6528,24 @@
"cms"
]
},
+ {
+ "id": "wuzapi",
+ "name": "WuzAPI",
+ "version": "v1.0.0",
+ "description": "A RESTful API service for WhatsApp with multiple device support and concurrent sessions.",
+ "logo": "wuzapi.png",
+ "links": {
+ "github": "https://github.com/asternic/wuzapi",
+ "website": "https://www.wuzapi.app/",
+ "docs": "https://github.com/asternic/wuzapi/blob/main/README.md"
+ },
+ "tags": [
+ "api",
+ "whatsapp",
+ "messaging",
+ "automation"
+ ]
+ },
{
"id": "xsshunter",
"name": "XSSHunter",