From 1ff926b18402c040aa2eed6331d4d826cd437116 Mon Sep 17 00:00:00 2001 From: Tony Hart <154579112+thaarrtt@users.noreply.github.com> Date: Thu, 7 Aug 2025 13:48:53 +0700 Subject: [PATCH] add authelia (#270) * add authelia * update config * update config env * update hash * admin first login fix --- blueprints/authelia/authelia.png | Bin 0 -> 49603 bytes blueprints/authelia/docker-compose.yml | 55 + blueprints/authelia/template.toml | 195 ++++ meta.json | 1277 ++++++++++++++++++++---- 4 files changed, 1308 insertions(+), 219 deletions(-) create mode 100644 blueprints/authelia/authelia.png create mode 100644 blueprints/authelia/docker-compose.yml create mode 100644 blueprints/authelia/template.toml diff --git a/blueprints/authelia/authelia.png b/blueprints/authelia/authelia.png new file mode 100644 index 0000000000000000000000000000000000000000..8555e3525a07deddc316edc9c30ca6488b50ceb7 GIT binary patch literal 49603 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 Pz(Z~u+$y=@@a+EqUr-&k literal 0 HcmV?d00001 diff --git a/blueprints/authelia/docker-compose.yml b/blueprints/authelia/docker-compose.yml new file mode 100644 index 00000000..fa65571b --- /dev/null +++ b/blueprints/authelia/docker-compose.yml @@ -0,0 +1,55 @@ +services: + authelia: + image: authelia/authelia:latest + restart: unless-stopped + volumes: + - authelia_config:/config + - ../files/configuration.yml:/config/configuration.yml:ro + - ../files/users_database.yml:/config/users_database.yml + environment: + AUTHELIA_JWT_SECRET: $JWT_SECRET + AUTHELIA_SESSION_SECRET: $SESSION_SECRET + AUTHELIA_STORAGE_ENCRYPTION_KEY: $STORAGE_ENCRYPTION_KEY + AUTHELIA_STORAGE_POSTGRES_PASSWORD: $POSTGRES_PASSWORD + depends_on: + redis: + condition: service_healthy + postgres: + condition: service_healthy + ports: + - 9091 + + redis: + image: redis:7-alpine + restart: unless-stopped + volumes: + - redis_data:/data + command: redis-server --save 60 1 --loglevel warning --requirepass $REDIS_PASSWORD + environment: + REDIS_PASSWORD: $REDIS_PASSWORD + healthcheck: + test: ["CMD", "redis-cli", "--raw", "incr", "ping"] + interval: 10s + timeout: 3s + retries: 5 + + postgres: + image: postgres:16-alpine + restart: unless-stopped + volumes: + - postgres_data:/var/lib/postgresql/data + environment: + POSTGRES_DB: authelia + POSTGRES_USER: authelia + POSTGRES_PASSWORD: $POSTGRES_PASSWORD + healthcheck: + test: ["CMD-SHELL", "pg_isready -U authelia -d authelia"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + +volumes: + authelia_config: + redis_data: + postgres_data: \ No newline at end of file diff --git a/blueprints/authelia/template.toml b/blueprints/authelia/template.toml new file mode 100644 index 00000000..9dfdd912 --- /dev/null +++ b/blueprints/authelia/template.toml @@ -0,0 +1,195 @@ +[variables] +main_domain = "${domain}" +jwt_secret = "${password:64}" +session_secret = "${password:64}" +storage_encryption_key = "${password:64}" +redis_password = "${password:32}" +postgres_password = "${password:32}" +admin_username = "${username}" +admin_email = "${email}" +admin_password = "AdminPass123!" +admin_password_hash = "$argon2id$v=19$m=65536,t=3,p=4$170PGJ1MskQyxfFknfBPFQ$VqD1/pqC3fBHo+Zk58bC2xQm1ltOFTr0w2wx93vJgC4" + +[config] +[[config.domains]] +serviceName = "authelia" +port = 9091 +host = "${main_domain}" +path = "/" + +[config.env] +JWT_SECRET = "${jwt_secret}" +SESSION_SECRET = "${session_secret}" +STORAGE_ENCRYPTION_KEY = "${storage_encryption_key}" +REDIS_PASSWORD = "${redis_password}" +POSTGRES_PASSWORD = "${postgres_password}" +admin_username = "${admin_username}" +admin_email = "${admin_email}" + +[[config.mounts]] +filePath = "configuration.yml" +content = """ +############################################################### +# Authelia configuration # +############################################################### + +# DEFAULT ADMIN CREDENTIALS: +# Username: (auto-generated, check users_database.yml) +# Password: AdminPass123! +# Email: (auto-generated) +# +# IMPORTANT: Change the password after first login! +# SECURITY NOTE: This template starts with one-factor auth for easier setup. +# After configuring SMTP/notifications, change the policy to 'two_factor' + +# Server Configuration +server: + address: 'tcp://0.0.0.0:9091' + headers: + csp_template: '' + +# Log Configuration +log: + level: info + format: text + +# Theme +theme: auto + +# TOTP Configuration +totp: + disable: false + issuer: authelia.com + algorithm: sha1 + digits: 6 + period: 30 + skew: 1 + secret_size: 32 + +# WebAuthn/FIDO2 Configuration +webauthn: + disable: false + timeout: 60s + display_name: Authelia + attestation_conveyance_preference: indirect + user_verification: preferred + +# NTP Configuration +ntp: + address: 'time.cloudflare.com:123' + version: 4 + max_desync: 3s + disable_startup_check: false + disable_failure: false + +# Authentication Backend Configuration +authentication_backend: + password_reset: + disable: false + custom_url: '' + refresh_interval: 5m + file: + path: /config/users_database.yml + watch: false + search: + email: false + case_insensitive: false + password: + algorithm: argon2 + argon2: + variant: argon2id + iterations: 3 + memory: 65536 + parallelism: 4 + key_length: 32 + salt_length: 16 + +# Password Policy +password_policy: + standard: + enabled: false + min_length: 8 + max_length: 0 + require_uppercase: true + require_lowercase: true + require_number: true + require_special: true + zxcvbn: + enabled: false + min_score: 3 + +# Session Configuration +session: + name: authelia_session + domain: ${main_domain} + same_site: lax + secret: ${session_secret} + expiration: 1h + inactivity: 5m + remember_me_duration: 1M + redis: + host: redis + port: 6379 + password: ${redis_password} + database_index: 0 + maximum_active_connections: 8 + minimum_idle_connections: 0 + +# Storage Configuration +storage: + encryption_key: ${storage_encryption_key} + postgres: + host: postgres + port: 5432 + database: authelia + schema: public + username: authelia + password: ${postgres_password} + timeout: 5s + +# Notifier Configuration +notifier: + disable_startup_check: true + filesystem: + filename: /config/notification.txt + +# Regulation Configuration +regulation: + max_retries: 3 + find_time: 10m + ban_time: 12h + +# Access Control Configuration - MODIFIED FOR EASIER INITIAL SETUP +access_control: + default_policy: deny + rules: + - domain: ${main_domain} + policy: one_factor # Changed from one_factor to two_factor for production +""" + +[[config.mounts]] +filePath = "users_database.yml" +content = """ +############################################################### +# Users Database # +############################################################### + +# DEFAULT LOGIN CREDENTIALS: +# Username: (generated from username helper) +# Password: AdminPass123! +# Email: (generated from email helper) +# +# IMPORTANT: Change the default password after first login! +# To generate a new password hash, run: +# docker run authelia/authelia:latest authelia hash-password 'your-new-password' + +users: + ${admin_username}: + disabled: false + displayname: "Authelia Admin" + password: "${admin_password_hash}" + email: ${admin_email} + groups: + - admins + - dev +""" diff --git a/meta.json b/meta.json index 85dd94ec..381edc6b 100644 --- a/meta.json +++ b/meta.json @@ -10,7 +10,34 @@ "docs": "https://autobase.tech/docs" }, "logo": "autobase.svg", - "tags": ["database", "postgres", "automation", "self-hosted", "dbaas"] + "tags": [ + "database", + "postgres", + "automation", + "self-hosted", + "dbaas" + ] + }, + { + "id": "authelia", + "name": "Authelia", + "version": "latest", + "description": "The Single Sign-On Multi-Factor portal for web apps. An open-source authentication and authorization server providing 2FA and SSO via web portal.", + "logo": "authelia.png", + "links": { + "github": "https://github.com/authelia/authelia", + "website": "https://www.authelia.com/", + "docs": "https://www.authelia.com/overview/prologue/introduction/" + }, + "tags": [ + "authentication", + "authorization", + "2fa", + "sso", + "security", + "reverse-proxy", + "ldap" + ] }, { "id": "capso", @@ -23,7 +50,13 @@ "docs": "https://cap.so/docs/" }, "logo": "capso.png", - "tags": ["web", "s3", "mysql", "development", "self-hosted"] + "tags": [ + "web", + "s3", + "mysql", + "development", + "self-hosted" + ] }, { "id": "authentik", @@ -57,7 +90,13 @@ "docs": "https://github.com/freescout-helpdesk/freescout/wiki/Installation-Guide" }, "logo": "freescout.svg", - "tags": ["helpdesk", "support", "email", "customer-service", "self-hosted"] + "tags": [ + "helpdesk", + "support", + "email", + "customer-service", + "self-hosted" + ] }, { "id": "openresty-manager", @@ -70,7 +109,14 @@ "docs": "https://github.com/Safe3/openresty-manager" }, "logo": "logo.svg", - "tags": ["web", "proxy", "security", "self-hosted", "openresty", "nginx"] + "tags": [ + "web", + "proxy", + "security", + "self-hosted", + "openresty", + "nginx" + ] }, { "id": "appwrite", @@ -83,7 +129,11 @@ "docs": "https://appwrite.io/docs" }, "logo": "appwrite.svg", - "tags": ["database", "firebase", "postgres"] + "tags": [ + "database", + "firebase", + "postgres" + ] }, { "id": "outline", @@ -96,7 +146,11 @@ "docs": "https://docs.getoutline.com/s/guide" }, "logo": "outline.png", - "tags": ["documentation", "knowledge-base", "self-hosted"] + "tags": [ + "documentation", + "knowledge-base", + "self-hosted" + ] }, { "id": "supabase", @@ -109,7 +163,11 @@ "docs": "https://supabase.com/docs/guides/self-hosting" }, "logo": "supabase.svg", - "tags": ["database", "firebase", "postgres"], + "tags": [ + "database", + "firebase", + "postgres" + ], "dokploy_version": ">=0.22.5" }, { @@ -123,7 +181,11 @@ "docs": "https://supabase.com/docs/guides/self-hosting" }, "logo": "supabase.svg", - "tags": ["database", "firebase", "postgres"], + "tags": [ + "database", + "firebase", + "postgres" + ], "dokploy_version": "<0.22.5" }, { @@ -137,7 +199,11 @@ "website": "https://pocketbase.io/", "docs": "https://pocketbase.io/docs/" }, - "tags": ["backend", "database", "api"] + "tags": [ + "backend", + "database", + "api" + ] }, { "id": "plausible", @@ -150,7 +216,9 @@ "website": "https://plausible.io/", "docs": "https://plausible.io/docs" }, - "tags": ["analytics"] + "tags": [ + "analytics" + ] }, { "id": "calcom", @@ -163,7 +231,10 @@ "docs": "https://cal.com/docs" }, "logo": "calcom.jpg", - "tags": ["scheduling", "booking"] + "tags": [ + "scheduling", + "booking" + ] }, { "id": "grafana", @@ -176,7 +247,9 @@ "website": "https://grafana.com/", "docs": "https://grafana.com/docs/" }, - "tags": ["monitoring"] + "tags": [ + "monitoring" + ] }, { "id": "stalwart", @@ -210,7 +283,12 @@ "website": "https://datalens.tech/", "docs": "https://datalens.tech/docs/" }, - "tags": ["analytics", "self-hosted", "bi", "monitoring"] + "tags": [ + "analytics", + "self-hosted", + "bi", + "monitoring" + ] }, { "id": "directus", @@ -223,7 +301,9 @@ "website": "https://directus.io/", "docs": "https://docs.directus.io/" }, - "tags": ["cms"] + "tags": [ + "cms" + ] }, { "id": "baserow", @@ -236,7 +316,9 @@ "website": "https://baserow.io/", "docs": "https://baserow.io/docs/index" }, - "tags": ["database"] + "tags": [ + "database" + ] }, { "id": "budibase", @@ -249,7 +331,12 @@ "website": "https://budibase.com/", "docs": "https://docs.budibase.com/docs/" }, - "tags": ["database", "low-code", "nocode", "applications"] + "tags": [ + "database", + "low-code", + "nocode", + "applications" + ] }, { "id": "forgejo", @@ -262,7 +349,10 @@ "website": "https://forgejo.org/", "docs": "https://forgejo.org/docs/latest/" }, - "tags": ["self-hosted", "storage"] + "tags": [ + "self-hosted", + "storage" + ] }, { "id": "gitlab-ce", @@ -275,7 +365,12 @@ "website": "https://gitlab.com/", "docs": "https://docs.gitlab.com/ee/" }, - "tags": ["git", "ci-cd", "version-control", "project-management"] + "tags": [ + "git", + "ci-cd", + "version-control", + "project-management" + ] }, { "id": "ghost", @@ -288,7 +383,9 @@ "website": "https://ghost.org/", "docs": "https://ghost.org/docs/" }, - "tags": ["cms"] + "tags": [ + "cms" + ] }, { "id": "lodestone", @@ -301,7 +398,11 @@ "website": "https://lodestone.cc", "docs": "https://github.com/Lodestone-Team/lodestone/wiki" }, - "tags": ["minecraft", "hosting", "server"] + "tags": [ + "minecraft", + "hosting", + "server" + ] }, { "id": "dragonfly-db", @@ -314,7 +415,10 @@ "website": "https://www.dragonflydb.io/", "docs": "https://www.dragonflydb.io/docs" }, - "tags": ["database", "redis"] + "tags": [ + "database", + "redis" + ] }, { "id": "stack-auth", @@ -327,7 +431,11 @@ "website": "https://stack-auth.com/", "docs": "https://docs.stack-auth.com/next/overview" }, - "tags": ["authentication", "auth", "authorization"] + "tags": [ + "authentication", + "auth", + "authorization" + ] }, { "id": "uptime-kuma", @@ -340,7 +448,9 @@ "website": "https://uptime.kuma.pet/", "docs": "https://github.com/louislam/uptime-kuma/wiki" }, - "tags": ["monitoring"] + "tags": [ + "monitoring" + ] }, { "id": "n8n", @@ -353,7 +463,9 @@ "website": "https://n8n.io/", "docs": "https://docs.n8n.io/" }, - "tags": ["automation"] + "tags": [ + "automation" + ] }, { "id": "kestra", @@ -366,7 +478,9 @@ "website": "https://kestra.io", "docs": "https://kestra.io/docs" }, - "tags": ["automation"] + "tags": [ + "automation" + ] }, { "id": "wordpress", @@ -379,7 +493,9 @@ "website": "https://wordpress.org/", "docs": "https://wordpress.org/documentation/" }, - "tags": ["cms"] + "tags": [ + "cms" + ] }, { "id": "odoo", @@ -392,7 +508,9 @@ "website": "https://odoo.com/", "docs": "https://www.odoo.com/documentation/" }, - "tags": ["cms"] + "tags": [ + "cms" + ] }, { "id": "appsmith", @@ -405,7 +523,9 @@ "website": "https://appsmith.com/", "docs": "https://docs.appsmith.com/" }, - "tags": ["cms"] + "tags": [ + "cms" + ] }, { "id": "excalidraw", @@ -418,7 +538,9 @@ "website": "https://excalidraw.com/", "docs": "https://docs.excalidraw.com/" }, - "tags": ["drawing"] + "tags": [ + "drawing" + ] }, { "id": "documenso", @@ -431,7 +553,9 @@ "docs": "https://documenso.com/docs" }, "logo": "documenso.png", - "tags": ["document-signing"] + "tags": [ + "document-signing" + ] }, { "id": "nocodb", @@ -444,7 +568,12 @@ "docs": "https://docs.nocodb.com/" }, "logo": "nocodb.png", - "tags": ["database", "spreadsheet", "low-code", "nocode"] + "tags": [ + "database", + "spreadsheet", + "low-code", + "nocode" + ] }, { "id": "meilisearch", @@ -457,7 +586,9 @@ "website": "https://www.meilisearch.com/", "docs": "https://docs.meilisearch.com/" }, - "tags": ["search"] + "tags": [ + "search" + ] }, { "id": "mattermost", @@ -470,7 +601,10 @@ "website": "https://mattermost.com/", "docs": "https://docs.mattermost.com/" }, - "tags": ["chat", "self-hosted"] + "tags": [ + "chat", + "self-hosted" + ] }, { "id": "phpmyadmin", @@ -483,7 +617,9 @@ "website": "https://www.phpmyadmin.net/", "docs": "https://www.phpmyadmin.net/docs/" }, - "tags": ["database"] + "tags": [ + "database" + ] }, { "id": "rocketchat", @@ -496,7 +632,9 @@ "website": "https://rocket.chat/", "docs": "https://rocket.chat/docs/" }, - "tags": ["chat"] + "tags": [ + "chat" + ] }, { "id": "minio", @@ -509,7 +647,9 @@ "website": "https://minio.io/", "docs": "https://docs.minio.io/" }, - "tags": ["storage"] + "tags": [ + "storage" + ] }, { "id": "metabase", @@ -522,7 +662,10 @@ "website": "https://www.metabase.com/", "docs": "https://www.metabase.com/docs/" }, - "tags": ["database", "dashboard"] + "tags": [ + "database", + "dashboard" + ] }, { "id": "glitchtip", @@ -535,7 +678,9 @@ "website": "https://glitchtip.com/", "docs": "https://glitchtip.com/documentation" }, - "tags": ["hosting"] + "tags": [ + "hosting" + ] }, { "id": "open-webui", @@ -548,7 +693,9 @@ "website": "https://openwebui.com/", "docs": "https://docs.openwebui.com/" }, - "tags": ["chat"] + "tags": [ + "chat" + ] }, { "id": "mailpit", @@ -561,7 +708,10 @@ "website": "https://mailpit.axllent.org/", "docs": "https://mailpit.axllent.org/docs/" }, - "tags": ["email", "smtp"] + "tags": [ + "email", + "smtp" + ] }, { "id": "listmonk", @@ -574,7 +724,11 @@ "website": "https://listmonk.app/", "docs": "https://listmonk.app/docs/" }, - "tags": ["email", "newsletter", "mailing-list"] + "tags": [ + "email", + "newsletter", + "mailing-list" + ] }, { "id": "doublezero", @@ -587,7 +741,9 @@ "website": "https://www.double-zero.cloud/", "docs": "https://github.com/technomancy-dev/00" }, - "tags": ["email"] + "tags": [ + "email" + ] }, { "id": "umami", @@ -600,7 +756,9 @@ "website": "https://umami.is", "docs": "https://umami.is/docs" }, - "tags": ["analytics"] + "tags": [ + "analytics" + ] }, { "id": "jellyfin", @@ -613,7 +771,9 @@ "website": "https://jellyfin.org/", "docs": "https://jellyfin.org/docs/" }, - "tags": ["media system"] + "tags": [ + "media system" + ] }, { "id": "teable", @@ -626,7 +786,12 @@ "website": "https://teable.io/", "docs": "https://help.teable.io/" }, - "tags": ["database", "spreadsheet", "low-code", "nocode"] + "tags": [ + "database", + "spreadsheet", + "low-code", + "nocode" + ] }, { "id": "zipline", @@ -639,7 +804,10 @@ "website": "https://zipline.diced.sh/", "docs": "https://zipline.diced.sh/docs/" }, - "tags": ["media system", "storage"] + "tags": [ + "media system", + "storage" + ] }, { "id": "soketi", @@ -652,7 +820,9 @@ "website": "https://soketi.app/", "docs": "https://docs.soketi.app/" }, - "tags": ["chat"] + "tags": [ + "chat" + ] }, { "id": "aptabase", @@ -665,7 +835,10 @@ "website": "https://aptabase.com/", "docs": "https://github.com/aptabase/aptabase/blob/main/README.md" }, - "tags": ["analytics", "self-hosted"] + "tags": [ + "analytics", + "self-hosted" + ] }, { "id": "typebot", @@ -678,7 +851,11 @@ "website": "https://typebot.io/", "docs": "https://docs.typebot.io/get-started/introduction" }, - "tags": ["chatbot", "builder", "open-source"] + "tags": [ + "chatbot", + "builder", + "open-source" + ] }, { "id": "typecho", @@ -691,7 +868,11 @@ "website": "https://typecho.org/", "docs": "http://docs.typecho.org" }, - "tags": ["blog", "cms", "php"] + "tags": [ + "blog", + "cms", + "php" + ] }, { "id": "gitea", @@ -704,7 +885,10 @@ "website": "https://gitea.com/", "docs": "https://docs.gitea.com/installation/install-with-docker" }, - "tags": ["self-hosted", "storage"] + "tags": [ + "self-hosted", + "storage" + ] }, { "id": "gitea-mirror", @@ -717,7 +901,14 @@ "website": "https://github.com/arunavo4/gitea-mirror", "docs": "https://github.com/arunavo4/gitea-mirror#readme" }, - "tags": ["git", "mirror", "github", "gitea", "self-hosted", "automation"] + "tags": [ + "git", + "mirror", + "github", + "gitea", + "self-hosted", + "automation" + ] }, { "id": "roundcube", @@ -730,7 +921,11 @@ "website": "https://roundcube.net/", "docs": "https://roundcube.net/about/" }, - "tags": ["self-hosted", "email", "webmail"] + "tags": [ + "self-hosted", + "email", + "webmail" + ] }, { "id": "filebrowser", @@ -743,7 +938,10 @@ "website": "https://filebrowser.org/", "docs": "https://filebrowser.org/" }, - "tags": ["file-manager", "storage"] + "tags": [ + "file-manager", + "storage" + ] }, { "id": "focalboard", @@ -756,7 +954,9 @@ "website": "https://focalboard.com", "docs": "https://www.focalboard.com/docs/" }, - "tags": ["kanban"] + "tags": [ + "kanban" + ] }, { "id": "tolgee", @@ -769,7 +969,12 @@ "website": "https://tolgee.io", "docs": "https://tolgee.io/platform" }, - "tags": ["self-hosted", "i18n", "localization", "translations"] + "tags": [ + "self-hosted", + "i18n", + "localization", + "translations" + ] }, { "id": "portainer", @@ -782,7 +987,10 @@ "website": "https://www.portainer.io/", "docs": "https://docs.portainer.io/" }, - "tags": ["cloud", "monitoring"] + "tags": [ + "cloud", + "monitoring" + ] }, { "id": "plane", @@ -795,7 +1003,9 @@ "website": "https://plane.so", "docs": "https://docs.plane.so/" }, - "tags": ["kanban"] + "tags": [ + "kanban" + ] }, { "id": "pterodactyl", @@ -808,7 +1018,11 @@ "website": "https://pterodactyl.io", "docs": "https://pterodactyl.io/project/introduction.html" }, - "tags": ["self-hosted", "open-source", "management"] + "tags": [ + "self-hosted", + "open-source", + "management" + ] }, { "id": "pyrodactyl", @@ -821,7 +1035,11 @@ "website": "https://pyrodactyl.dev", "docs": "https://pyrodactyl.dev/docs" }, - "tags": ["self-hosted", "open-source", "management"] + "tags": [ + "self-hosted", + "open-source", + "management" + ] }, { "id": "influxdb", @@ -834,7 +1052,12 @@ "website": "https://www.influxdata.com/", "docs": "https://docs.influxdata.com/influxdb/v2/" }, - "tags": ["self-hosted", "open-source", "storage", "database"] + "tags": [ + "self-hosted", + "open-source", + "storage", + "database" + ] }, { "id": "infisical", @@ -847,7 +1070,10 @@ "website": "https://infisical.com/", "docs": "https://infisical.com/docs/documentation/getting-started/introduction" }, - "tags": ["self-hosted", "open-source"] + "tags": [ + "self-hosted", + "open-source" + ] }, { "id": "docmost", @@ -860,7 +1086,11 @@ "website": "https://docmost.com/", "docs": "https://docmost.com/docs/" }, - "tags": ["self-hosted", "open-source", "manager"] + "tags": [ + "self-hosted", + "open-source", + "manager" + ] }, { "id": "vaultwarden", @@ -873,7 +1103,9 @@ "website": "", "docs": "https://github.com/dani-garcia/vaultwarden/wiki" }, - "tags": ["open-source"] + "tags": [ + "open-source" + ] }, { "id": "linkding", @@ -886,7 +1118,10 @@ "website": "https://sissbruecker.github.io/linkding/", "docs": "https://github.com/sissbruecker/linkding/blob/master/docs/Options.md" }, - "tags": ["bookmark-manager", "self-hosted"] + "tags": [ + "bookmark-manager", + "self-hosted" + ] }, { "id": "linkwarden", @@ -899,7 +1134,10 @@ "website": "https://linkwarden.app/", "docs": "https://docs.linkwarden.app/" }, - "tags": ["bookmarks", "link-sharing"] + "tags": [ + "bookmarks", + "link-sharing" + ] }, { "id": "hi-events", @@ -912,7 +1150,11 @@ "website": "https://hi.events/", "docs": "https://hi.events/docs" }, - "tags": ["self-hosted", "open-source", "manager"] + "tags": [ + "self-hosted", + "open-source", + "manager" + ] }, { "id": "habitica", @@ -925,7 +1167,12 @@ "website": "https://habitica.com/", "docs": "https://habitica.fandom.com/wiki/Setting_up_Habitica_Locally" }, - "tags": ["productivity", "gamification", "habits", "self-hosted"] + "tags": [ + "productivity", + "gamification", + "habits", + "self-hosted" + ] }, { "id": "hoarder", @@ -938,7 +1185,11 @@ "website": "https://hoarder.app/", "docs": "https://docs.hoarder.app/" }, - "tags": ["self-hosted", "bookmarks", "link-sharing"] + "tags": [ + "self-hosted", + "bookmarks", + "link-sharing" + ] }, { "id": "windows", @@ -951,7 +1202,11 @@ "website": "", "docs": "https://github.com/dockur/windows?tab=readme-ov-file#how-do-i-use-it" }, - "tags": ["self-hosted", "open-source", "os"] + "tags": [ + "self-hosted", + "open-source", + "os" + ] }, { "id": "macos", @@ -964,7 +1219,11 @@ "website": "", "docs": "https://github.com/dockur/macos?tab=readme-ov-file#how-do-i-use-it" }, - "tags": ["self-hosted", "open-source", "os"] + "tags": [ + "self-hosted", + "open-source", + "os" + ] }, { "id": "coder", @@ -977,7 +1236,11 @@ "website": "https://coder.com/", "docs": "https://coder.com/docs" }, - "tags": ["self-hosted", "open-source", "builder"] + "tags": [ + "self-hosted", + "open-source", + "builder" + ] }, { "id": "stirling", @@ -990,7 +1253,10 @@ "website": "https://www.stirlingpdf.com/", "docs": "https://docs.stirlingpdf.com/" }, - "tags": ["pdf", "tools"] + "tags": [ + "pdf", + "tools" + ] }, { "id": "lobe-chat", @@ -1003,7 +1269,10 @@ "website": "https://chat-preview.lobehub.com/", "docs": "https://lobehub.com/docs/self-hosting/platform/docker-compose" }, - "tags": ["IA", "chat"] + "tags": [ + "IA", + "chat" + ] }, { "id": "peppermint", @@ -1016,7 +1285,11 @@ "website": "https://peppermint.sh/", "docs": "https://docs.peppermint.sh/" }, - "tags": ["api", "development", "documentation"] + "tags": [ + "api", + "development", + "documentation" + ] }, { "id": "windmill", @@ -1029,7 +1302,11 @@ "website": "https://www.windmill.dev/", "docs": "https://docs.windmill.dev/" }, - "tags": ["workflow", "automation", "development"] + "tags": [ + "workflow", + "automation", + "development" + ] }, { "id": "activepieces", @@ -1042,7 +1319,11 @@ "website": "https://www.activepieces.com/", "docs": "https://www.activepieces.com/docs" }, - "tags": ["automation", "workflow", "no-code"] + "tags": [ + "automation", + "workflow", + "no-code" + ] }, { "id": "invoiceshelf", @@ -1055,7 +1336,11 @@ "website": "https://invoiceshelf.com", "docs": "https://github.com/InvoiceShelf/invoiceshelf#readme" }, - "tags": ["invoice", "business", "finance"] + "tags": [ + "invoice", + "business", + "finance" + ] }, { "id": "postiz", @@ -1068,7 +1353,11 @@ "website": "https://postiz.com", "docs": "https://docs.postiz.com" }, - "tags": ["cms", "content-management", "publishing"] + "tags": [ + "cms", + "content-management", + "publishing" + ] }, { "id": "slash", @@ -1081,7 +1370,11 @@ "website": "https://github.com/yourselfhosted/slash#readme", "docs": "https://github.com/yourselfhosted/slash/wiki" }, - "tags": ["bookmarks", "link-shortener", "self-hosted"] + "tags": [ + "bookmarks", + "link-shortener", + "self-hosted" + ] }, { "id": "discord-tickets", @@ -1094,7 +1387,11 @@ "website": "https://discordtickets.app", "docs": "https://discordtickets.app/self-hosting/installation/docker/" }, - "tags": ["discord", "tickets", "support"] + "tags": [ + "discord", + "tickets", + "support" + ] }, { "id": "nextcloud-aio", @@ -1107,7 +1404,10 @@ "website": "https://nextcloud.com/", "docs": "https://docs.nextcloud.com/" }, - "tags": ["file-manager", "sync"] + "tags": [ + "file-manager", + "sync" + ] }, { "id": "blender", @@ -1120,7 +1420,11 @@ "website": "https://www.blender.org/", "docs": "https://docs.blender.org/" }, - "tags": ["3d", "rendering", "animation"] + "tags": [ + "3d", + "rendering", + "animation" + ] }, { "id": "heyform", @@ -1133,7 +1437,13 @@ "website": "https://heyform.net", "docs": "https://docs.heyform.net" }, - "tags": ["form", "builder", "questionnaire", "quiz", "survey"] + "tags": [ + "form", + "builder", + "questionnaire", + "quiz", + "survey" + ] }, { "id": "chatwoot", @@ -1146,7 +1456,11 @@ "website": "https://www.chatwoot.com", "docs": "https://www.chatwoot.com/docs" }, - "tags": ["support", "chat", "customer-service"] + "tags": [ + "support", + "chat", + "customer-service" + ] }, { "id": "discourse", @@ -1159,7 +1473,11 @@ "website": "https://www.discourse.org/", "docs": "https://meta.discourse.org/" }, - "tags": ["forum", "community", "discussion"] + "tags": [ + "forum", + "community", + "discussion" + ] }, { "id": "immich", @@ -1172,7 +1490,12 @@ "website": "https://immich.app/", "docs": "https://immich.app/docs/overview/introduction" }, - "tags": ["photos", "videos", "backup", "media"] + "tags": [ + "photos", + "videos", + "backup", + "media" + ] }, { "id": "twenty", @@ -1185,7 +1508,11 @@ "website": "https://twenty.com", "docs": "https://docs.twenty.com" }, - "tags": ["crm", "sales", "business"] + "tags": [ + "crm", + "sales", + "business" + ] }, { "id": "yourls", @@ -1198,7 +1525,10 @@ "website": "https://yourls.org/", "docs": "https://yourls.org/#documentation" }, - "tags": ["url-shortener", "php"] + "tags": [ + "url-shortener", + "php" + ] }, { "id": "ryot", @@ -1211,7 +1541,11 @@ "website": "https://ryot.io/", "docs": "https://docs.ryot.io/" }, - "tags": ["media", "tracking", "self-hosted"] + "tags": [ + "media", + "tracking", + "self-hosted" + ] }, { "id": "photoprism", @@ -1224,7 +1558,11 @@ "website": "https://www.photoprism.app/", "docs": "https://docs.photoprism.app/" }, - "tags": ["media", "photos", "self-hosted"] + "tags": [ + "media", + "photos", + "self-hosted" + ] }, { "id": "ontime", @@ -1237,7 +1575,9 @@ "website": "https://getontime.no", "docs": "https://docs.getontime.no" }, - "tags": ["event"] + "tags": [ + "event" + ] }, { "id": "triggerdotdev", @@ -1250,7 +1590,10 @@ "website": "https://trigger.dev/", "docs": "https://trigger.dev/docs" }, - "tags": ["event-driven", "applications"] + "tags": [ + "event-driven", + "applications" + ] }, { "id": "browserless", @@ -1263,7 +1606,10 @@ "website": "https://www.browserless.io/", "docs": "https://docs.browserless.io/" }, - "tags": ["browser", "automation"] + "tags": [ + "browser", + "automation" + ] }, { "id": "drawio", @@ -1276,7 +1622,10 @@ "website": "https://draw.io/", "docs": "https://www.drawio.com/doc/" }, - "tags": ["drawing", "diagrams"] + "tags": [ + "drawing", + "diagrams" + ] }, { "id": "kimai", @@ -1289,7 +1638,11 @@ "website": "https://www.kimai.org", "docs": "https://www.kimai.org/documentation" }, - "tags": ["invoice", "business", "finance"] + "tags": [ + "invoice", + "business", + "finance" + ] }, { "id": "logto", @@ -1302,7 +1655,10 @@ "website": "https://logto.io/", "docs": "https://docs.logto.io/introduction" }, - "tags": ["identity", "auth"] + "tags": [ + "identity", + "auth" + ] }, { "id": "pocket-id", @@ -1315,7 +1671,10 @@ "website": "https://pocket-id.org/", "docs": "https://pocket-id.org/docs" }, - "tags": ["identity", "auth"] + "tags": [ + "identity", + "auth" + ] }, { "id": "penpot", @@ -1328,7 +1687,10 @@ "website": "https://penpot.app/", "docs": "https://docs.penpot.app/" }, - "tags": ["design", "collaboration"] + "tags": [ + "design", + "collaboration" + ] }, { "id": "huly", @@ -1341,7 +1703,11 @@ "website": "https://huly.io/", "docs": "https://docs.huly.io/" }, - "tags": ["project-management", "community", "discussion"] + "tags": [ + "project-management", + "community", + "discussion" + ] }, { "id": "unsend", @@ -1354,7 +1720,11 @@ "website": "https://unsend.dev/", "docs": "https://docs.unsend.dev/get-started/" }, - "tags": ["e-mail", "marketing", "business"] + "tags": [ + "e-mail", + "marketing", + "business" + ] }, { "id": "langflow", @@ -1367,7 +1737,9 @@ "website": "https://www.langflow.org/", "docs": "https://docs.langflow.org/" }, - "tags": ["ai"] + "tags": [ + "ai" + ] }, { "id": "elastic-search", @@ -1380,7 +1752,10 @@ "website": "https://www.elastic.co/elasticsearch/", "docs": "https://docs.elastic.co/elasticsearch/" }, - "tags": ["search", "analytics"] + "tags": [ + "search", + "analytics" + ] }, { "id": "onedev", @@ -1393,7 +1768,10 @@ "website": "https://onedev.io/", "docs": "https://docs.onedev.io/" }, - "tags": ["self-hosted", "development"] + "tags": [ + "self-hosted", + "development" + ] }, { "id": "unifi", @@ -1406,7 +1784,10 @@ "website": "https://www.ui.com/", "docs": "https://help.ui.com/hc/en-us/articles/360012282453-Self-Hosting-a-UniFi-Network-Server" }, - "tags": ["self-hosted", "networking"] + "tags": [ + "self-hosted", + "networking" + ] }, { "id": "glpi", @@ -1419,7 +1800,11 @@ "website": "https://glpi-project.org/", "docs": "https://glpi-project.org/documentation/" }, - "tags": ["self-hosted", "project-management", "management"] + "tags": [ + "self-hosted", + "project-management", + "management" + ] }, { "id": "checkmate", @@ -1432,7 +1817,11 @@ "website": "https://bluewavelabs.ca", "docs": "https://bluewavelabs.gitbook.io/checkmate" }, - "tags": ["self-hosted", "monitoring", "uptime"] + "tags": [ + "self-hosted", + "monitoring", + "uptime" + ] }, { "id": "gotenberg", @@ -1445,7 +1834,12 @@ "website": "https://gotenberg.dev", "docs": "https://gotenberg.dev/docs/getting-started/introduction" }, - "tags": ["api", "backend", "pdf", "tools"] + "tags": [ + "api", + "backend", + "pdf", + "tools" + ] }, { "id": "actualbudget", @@ -1458,7 +1852,11 @@ "website": "https://actualbudget.org", "docs": "https://actualbudget.org/docs" }, - "tags": ["budgeting", "finance", "money"] + "tags": [ + "budgeting", + "finance", + "money" + ] }, { "id": "conduit", @@ -1471,7 +1869,10 @@ "website": "https://conduit.rs/", "docs": "https://docs.conduit.rs/" }, - "tags": ["matrix", "communication"] + "tags": [ + "matrix", + "communication" + ] }, { "id": "evolutionapi", @@ -1484,7 +1885,11 @@ "docs": "https://doc.evolution-api.com/v2/en/get-started/introduction", "website": "https://evolution-api.com/opensource-whatsapp-api/" }, - "tags": ["api", "whatsapp", "messaging"] + "tags": [ + "api", + "whatsapp", + "messaging" + ] }, { "id": "conduwuit", @@ -1497,7 +1902,13 @@ "website": "https://conduwuit.puppyirl.gay", "docs": "https://conduwuit.puppyirl.gay/configuration.html" }, - "tags": ["backend", "chat", "communication", "matrix", "server"] + "tags": [ + "backend", + "chat", + "communication", + "matrix", + "server" + ] }, { "id": "cloudflared", @@ -1510,7 +1921,12 @@ "website": "https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/", "docs": "https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/" }, - "tags": ["cloud", "networking", "security", "tunnel"] + "tags": [ + "cloud", + "networking", + "security", + "tunnel" + ] }, { "id": "couchdb", @@ -1523,7 +1939,10 @@ "website": "https://couchdb.apache.org/", "docs": "https://docs.couchdb.org/en/stable/" }, - "tags": ["database", "storage"] + "tags": [ + "database", + "storage" + ] }, { "id": "it-tools", @@ -1536,7 +1955,10 @@ "website": "https://it-tools.tech", "docs": "https://it-tools.tech/docs" }, - "tags": ["developer", "tools"] + "tags": [ + "developer", + "tools" + ] }, { "id": "superset", @@ -1549,7 +1971,13 @@ "website": "https://superset.apache.org", "docs": "https://superset.apache.org/docs/intro" }, - "tags": ["analytics", "bi", "dashboard", "database", "sql"] + "tags": [ + "analytics", + "bi", + "dashboard", + "database", + "sql" + ] }, { "id": "glance", @@ -1562,7 +1990,12 @@ "docs": "https://github.com/glanceapp/glance/blob/main/docs/configuration.md", "website": "https://glance.app/" }, - "tags": ["dashboard", "monitoring", "widgets", "rss"] + "tags": [ + "dashboard", + "monitoring", + "widgets", + "rss" + ] }, { "id": "homarr", @@ -1575,7 +2008,10 @@ "docs": "https://homarr.dev/docs/getting-started/installation/docker", "website": "https://homarr.dev/" }, - "tags": ["dashboard", "monitoring"] + "tags": [ + "dashboard", + "monitoring" + ] }, { "id": "erpnext", @@ -1609,7 +2045,10 @@ "website": "https://maybe.finance/", "docs": "https://docs.maybe.finance/" }, - "tags": ["finance", "self-hosted"] + "tags": [ + "finance", + "self-hosted" + ] }, { "id": "spacedrive", @@ -1622,7 +2061,11 @@ "docs": "https://www.spacedrive.com/docs/product/getting-started/introduction" }, "logo": "spacedrive.png", - "tags": ["file-manager", "vdfs", "storage"] + "tags": [ + "file-manager", + "vdfs", + "storage" + ] }, { "id": "registry", @@ -1635,7 +2078,11 @@ "docs": "https://distribution.github.io/distribution/" }, "logo": "registry.png", - "tags": ["registry", "docker", "self-hosted"] + "tags": [ + "registry", + "docker", + "self-hosted" + ] }, { "id": "alist", @@ -1648,7 +2095,11 @@ "website": "https://alist.nn.ci", "docs": "https://alist.nn.ci/guide/install/docker.html" }, - "tags": ["file", "webdav", "storage"] + "tags": [ + "file", + "webdav", + "storage" + ] }, { "id": "answer", @@ -1661,7 +2112,10 @@ "website": "https://answer.apache.org/", "docs": "https://answer.apache.org/docs" }, - "tags": ["q&a", "self-hosted"] + "tags": [ + "q&a", + "self-hosted" + ] }, { "id": "shlink", @@ -1674,7 +2128,11 @@ "website": "https://shlink.io", "docs": "https://shlink.io/documentation" }, - "tags": ["sharing", "shortener", "url"] + "tags": [ + "sharing", + "shortener", + "url" + ] }, { "id": "frappe-hr", @@ -1707,7 +2165,10 @@ "website": "https://formbricks.com/", "docs": "https://formbricks.com/docs" }, - "tags": ["forms", "analytics"] + "tags": [ + "forms", + "analytics" + ] }, { "id": "trilium", @@ -1720,7 +2181,11 @@ "website": "https://github.com/zadam/trilium", "docs": "https://github.com/zadam/trilium/wiki/" }, - "tags": ["self-hosted", "productivity", "personal-use"] + "tags": [ + "self-hosted", + "productivity", + "personal-use" + ] }, { "id": "convex", @@ -1733,7 +2198,11 @@ "website": "https://www.convex.dev/", "docs": "https://www.convex.dev/docs" }, - "tags": ["backend", "database", "api"] + "tags": [ + "backend", + "database", + "api" + ] }, { "id": "wikijs", @@ -1746,7 +2215,11 @@ "website": "https://js.wiki/", "docs": "https://docs.requarks.io/" }, - "tags": ["knowledge-base", "self-hosted", "documentation"] + "tags": [ + "knowledge-base", + "self-hosted", + "documentation" + ] }, { "id": "otterwiki", @@ -1759,7 +2232,12 @@ "website": "https://otterwiki.com/", "docs": "https://github.com/redimp/otterwiki/wiki" }, - "tags": ["wiki", "documentation", "knowledge-base", "markdown"] + "tags": [ + "wiki", + "documentation", + "knowledge-base", + "markdown" + ] }, { "id": "lowcoder", @@ -1772,7 +2250,11 @@ "website": "https://www.lowcoder.cloud/", "docs": "https://docs.lowcoder.cloud/lowcoder-documentation" }, - "tags": ["low-code", "no-code", "development"] + "tags": [ + "low-code", + "no-code", + "development" + ] }, { "id": "backrest", @@ -1785,7 +2267,9 @@ "docs": "https://garethgeorge.github.io/backrest/introduction/getting-started" }, "logo": "backrest.svg", - "tags": ["backup"] + "tags": [ + "backup" + ] }, { "id": "blinko", @@ -1798,7 +2282,12 @@ "website": "https://blinko.space/", "docs": "https://docs.blinko.space/" }, - "tags": ["productivity", "organization", "workflow", "nextjs"] + "tags": [ + "productivity", + "organization", + "workflow", + "nextjs" + ] }, { "id": "pgadmin", @@ -1811,7 +2300,11 @@ "docs": "https://www.pgadmin.org/docs/" }, "logo": "pgadmin.webp", - "tags": ["database", "postgres", "admin"] + "tags": [ + "database", + "postgres", + "admin" + ] }, { "id": "ackee", @@ -1824,7 +2317,10 @@ "website": "https://ackee.electerious.com/", "docs": "https://docs.ackee.electerious.com/" }, - "tags": ["analytics", "self-hosted"] + "tags": [ + "analytics", + "self-hosted" + ] }, { "id": "adguardhome", @@ -1837,7 +2333,12 @@ "website": "https://adguard.com", "docs": "https://github.com/AdguardTeam/AdGuardHome/wiki" }, - "tags": ["privacy", "security", "dns", "ad-blocking"] + "tags": [ + "privacy", + "security", + "dns", + "ad-blocking" + ] }, { "id": "adminer", @@ -1850,7 +2351,12 @@ "website": "https://www.adminer.org/", "docs": "https://www.adminer.org/en/plugins/" }, - "tags": ["databases", "developer-tools", "mysql", "postgresql"] + "tags": [ + "databases", + "developer-tools", + "mysql", + "postgresql" + ] }, { "id": "affinepro", @@ -1881,7 +2387,11 @@ "website": "https://github.com/Rudloff/alltube", "docs": "https://github.com/Rudloff/alltube/wiki" }, - "tags": ["media", "video", "downloader"] + "tags": [ + "media", + "video", + "downloader" + ] }, { "id": "ampache", @@ -1894,7 +2404,11 @@ "website": "http://ampache.org/", "docs": "https://github.com/ampache/ampache/wiki" }, - "tags": ["media", "music", "streaming"] + "tags": [ + "media", + "music", + "streaming" + ] }, { "id": "anythingllm", @@ -1907,7 +2421,11 @@ "website": "https://useanything.com", "docs": "https://github.com/Mintplex-Labs/anything-llm/tree/master/docs" }, - "tags": ["ai", "llm", "chatbot"] + "tags": [ + "ai", + "llm", + "chatbot" + ] }, { "id": "apprise-api", @@ -1920,7 +2438,10 @@ "website": "https://github.com/caronc/apprise-api", "docs": "https://github.com/caronc/apprise-api/wiki" }, - "tags": ["notifications", "api"] + "tags": [ + "notifications", + "api" + ] }, { "id": "arangodb", @@ -1933,7 +2454,11 @@ "website": "https://www.arangodb.com/", "docs": "https://www.arangodb.com/docs/" }, - "tags": ["database", "graph-database", "nosql"] + "tags": [ + "database", + "graph-database", + "nosql" + ] }, { "id": "anonupload", @@ -1946,7 +2471,10 @@ "docs": "https://github.com/Supernova3339/anonupload/blob/main/env.md", "website": "https://anonupload.com/" }, - "tags": ["file-sharing", "privacy"] + "tags": [ + "file-sharing", + "privacy" + ] }, { "id": "argilla", @@ -1959,7 +2487,11 @@ "website": "https://www.argilla.io/", "docs": "https://docs.argilla.io/" }, - "tags": ["machine-learning", "data-labeling", "ai"] + "tags": [ + "machine-learning", + "data-labeling", + "ai" + ] }, { "id": "audiobookshelf", @@ -1972,7 +2504,11 @@ "website": "https://www.audiobookshelf.org", "docs": "https://www.audiobookshelf.org/docs" }, - "tags": ["media", "audiobooks", "podcasts"] + "tags": [ + "media", + "audiobooks", + "podcasts" + ] }, { "id": "authorizer", @@ -1985,7 +2521,11 @@ "website": "https://authorizer.dev", "docs": "https://docs.authorizer.dev/" }, - "tags": ["authentication", "authorization", "security"] + "tags": [ + "authentication", + "authorization", + "security" + ] }, { "id": "automatisch", @@ -1998,7 +2538,11 @@ "website": "https://automatisch.io/docs", "docs": "https://automatisch.io/docs" }, - "tags": ["automation", "workflow", "integration"] + "tags": [ + "automation", + "workflow", + "integration" + ] }, { "id": "babybuddy", @@ -2011,7 +2555,11 @@ "website": "https://babybuddy.app", "docs": "https://docs.babybuddy.app" }, - "tags": ["parenting", "tracking", "family"] + "tags": [ + "parenting", + "tracking", + "family" + ] }, { "id": "baikal", @@ -2024,7 +2572,12 @@ "github": "https://sabre.io/baikal/", "docs": "https://sabre.io/baikal/install/" }, - "tags": ["calendar", "contacts", "caldav", "carddav"] + "tags": [ + "calendar", + "contacts", + "caldav", + "carddav" + ] }, { "id": "barrage", @@ -2037,7 +2590,11 @@ "website": "https://github.com/maulik9898/barrage", "docs": "https://github.com/maulik9898/barrage/blob/main/README.md" }, - "tags": ["torrents", "deluge", "mobile"] + "tags": [ + "torrents", + "deluge", + "mobile" + ] }, { "id": "bazarr", @@ -2050,7 +2607,11 @@ "website": "https://www.bazarr.media/", "docs": "https://www.bazarr.media/docs" }, - "tags": ["subtitles", "sonarr", "radarr"] + "tags": [ + "subtitles", + "sonarr", + "radarr" + ] }, { "id": "beszel", @@ -2063,7 +2624,11 @@ "website": "https://beszel.dev", "docs": "https://beszel.dev/guide/getting-started" }, - "tags": ["monitoring", "docker", "alerts"] + "tags": [ + "monitoring", + "docker", + "alerts" + ] }, { "id": "bytestash", @@ -2076,7 +2641,10 @@ "website": "https://bytestash.com", "docs": "https://bytestash.com/docs" }, - "tags": ["file-storage", "self-hosted"] + "tags": [ + "file-storage", + "self-hosted" + ] }, { "id": "bookstack", @@ -2089,7 +2657,10 @@ "website": "https://www.bookstackapp.com", "docs": "https://www.bookstackapp.com/docs" }, - "tags": ["documentation", "self-hosted"] + "tags": [ + "documentation", + "self-hosted" + ] }, { "id": "bytebase", @@ -2102,7 +2673,10 @@ "website": "https://www.bytebase.com", "docs": "https://www.bytebase.com/docs" }, - "tags": ["database", "self-hosted"] + "tags": [ + "database", + "self-hosted" + ] }, { "id": "botpress", @@ -2115,7 +2689,10 @@ "website": "https://botpress.com", "docs": "https://botpress.com/docs" }, - "tags": ["ai", "self-hosted"] + "tags": [ + "ai", + "self-hosted" + ] }, { "id": "calibre", @@ -2128,7 +2705,10 @@ "website": "https://calibre-ebook.com/", "docs": "https://manual.calibre-ebook.com/" }, - "tags": ["Documents", "E-Commerce"] + "tags": [ + "Documents", + "E-Commerce" + ] }, { "id": "carbone", @@ -2141,7 +2721,12 @@ "website": "https://carbone.io/", "docs": "https://carbone.io/documentation/design/overview/getting-started.html" }, - "tags": ["Document Generation", "Automation", "Reporting", "Productivity"] + "tags": [ + "Document Generation", + "Automation", + "Reporting", + "Productivity" + ] }, { "id": "casdoor", @@ -2177,7 +2762,11 @@ "website": "https://changedetection.io", "docs": "https://github.com/dgtlmoon/changedetection.io/wiki" }, - "tags": ["Monitoring", "Data", "Notifications"] + "tags": [ + "Monitoring", + "Data", + "Notifications" + ] }, { "id": "chevereto", @@ -2228,7 +2817,11 @@ "website": "https://www.classicpress.net/", "docs": "https://docs.classicpress.net/" }, - "tags": ["cms", "wordpress", "content-management"] + "tags": [ + "cms", + "wordpress", + "content-management" + ] }, { "id": "cloud9", @@ -2241,7 +2834,11 @@ "website": "https://aws.amazon.com/cloud9/", "docs": "https://docs.aws.amazon.com/cloud9/" }, - "tags": ["ide", "development", "cloud"] + "tags": [ + "ide", + "development", + "cloud" + ] }, { "id": "cloudcommander", @@ -2254,7 +2851,11 @@ "website": "https://cloudcmd.io", "docs": "https://cloudcmd.io/#install" }, - "tags": ["file-manager", "web-based", "console"] + "tags": [ + "file-manager", + "web-based", + "console" + ] }, { "id": "cockpit", @@ -2267,7 +2868,11 @@ "website": "https://getcockpit.com", "docs": "https://getcockpit.com/documentation" }, - "tags": ["cms", "content-management", "api"] + "tags": [ + "cms", + "content-management", + "api" + ] }, { "id": "chromium", @@ -2280,7 +2885,11 @@ "docs": "https://docs.linuxserver.io/images/docker-chromium", "website": "https://docs.linuxserver.io/images/docker-chromium" }, - "tags": ["browser", "development", "web"] + "tags": [ + "browser", + "development", + "web" + ] }, { "id": "codex-docs", @@ -2293,7 +2902,11 @@ "website": "https://codex.so", "docs": "https://docs.codex.so" }, - "tags": ["documentation", "development", "collaboration"] + "tags": [ + "documentation", + "development", + "collaboration" + ] }, { "id": "colanode", @@ -2306,7 +2919,11 @@ "website": "https://colanode.com", "docs": "https://colanode.com/docs/" }, - "tags": ["documentation", "knowledge-base", "collaboration"] + "tags": [ + "documentation", + "knowledge-base", + "collaboration" + ] }, { "id": "collabora-office", @@ -2319,7 +2936,11 @@ "website": "https://collaboraonline.com", "docs": "https://sdk.collaboraonline.com/docs" }, - "tags": ["office", "documents", "collaboration"] + "tags": [ + "office", + "documents", + "collaboration" + ] }, { "id": "confluence", @@ -2350,7 +2971,11 @@ "github": "https://github.com/souramoo/commentoplusplus" }, "logo": "logo.png", - "tags": ["comments", "discussion", "website"] + "tags": [ + "comments", + "discussion", + "website" + ] }, { "id": "commentoplusplus", @@ -2363,7 +2988,11 @@ "github": "https://github.com/souramoo/commentoplusplus" }, "logo": "logo.png", - "tags": ["comments", "website", "open-source"] + "tags": [ + "comments", + "website", + "open-source" + ] }, { "id": "coralproject", @@ -2376,7 +3005,11 @@ "github": "https://github.com/coralproject/talk" }, "logo": "logo.png", - "tags": ["communication", "community", "privacy"] + "tags": [ + "communication", + "community", + "privacy" + ] }, { "id": "rsshub", @@ -2389,7 +3022,11 @@ "website": "https://rsshub.app/", "docs": "https://docs.rsshub.app/" }, - "tags": ["rss", "api", "self-hosted"] + "tags": [ + "rss", + "api", + "self-hosted" + ] }, { "id": "tailscale-exitnode", @@ -2402,7 +3039,9 @@ "website": "https://tailscale.com/", "docs": "https://tailscale.com/kb/1408/quick-guide-exit-nodes" }, - "tags": ["network"] + "tags": [ + "network" + ] }, { "id": "homebridge", @@ -2415,7 +3054,13 @@ "website": "https://homebridge.io/", "docs": "https://github.com/homebridge/homebridge/wiki" }, - "tags": ["iot", "homekit", "internet-of-things", "self-hosted", "server"] + "tags": [ + "iot", + "homekit", + "internet-of-things", + "self-hosted", + "server" + ] }, { "id": "homeassistant", @@ -2447,7 +3092,11 @@ "website": "https://tooljet.ai/", "docs": "https://docs.tooljet.ai/" }, - "tags": ["file-sync", "file-sharing", "self-hosted"] + "tags": [ + "file-sync", + "file-sharing", + "self-hosted" + ] }, { "id": "onetimesecret", @@ -2460,7 +3109,12 @@ "website": "https://onetimesecret.com", "docs": "https://docs.onetimesecret.com" }, - "tags": ["auth", "password", "secret", "secure"] + "tags": [ + "auth", + "password", + "secret", + "secure" + ] }, { "id": "bugsink", @@ -2473,7 +3127,11 @@ "website": "https://www.bugsink.com/", "docs": "https://www.bugsink.com/docs/" }, - "tags": ["hosting", "self-hosted", "development"] + "tags": [ + "hosting", + "self-hosted", + "development" + ] }, { "id": "bolt.diy", @@ -2486,7 +3144,14 @@ "website": "https://stackblitz-labs.github.io/bolt.diy/", "docs": "https://stackblitz-labs.github.io/bolt.diy/" }, - "tags": ["ai", "self-hosted", "development", "chatbot", "ide", "llm"] + "tags": [ + "ai", + "self-hosted", + "development", + "chatbot", + "ide", + "llm" + ] }, { "id": "qdrant", @@ -2499,7 +3164,11 @@ "website": "https://qdrant.tech/", "docs": "https://qdrant.tech/documentation/" }, - "tags": ["vector-db", "database", "search"] + "tags": [ + "vector-db", + "database", + "search" + ] }, { "id": "trmnl-byos-laravel", @@ -2512,7 +3181,9 @@ "website": "https://docs.usetrmnl.com/go/diy/byos", "docs": "https://github.com/usetrmnl/byos_laravel/blob/main/README.md" }, - "tags": ["e-ink"] + "tags": [ + "e-ink" + ] }, { "id": "chibisafe", @@ -2525,7 +3196,11 @@ "website": "https://chibisafe.app", "docs": "https://chibisafe.app/docs/intro" }, - "tags": ["media system", "storage", "file-sharing"] + "tags": [ + "media system", + "storage", + "file-sharing" + ] }, { "id": "rybbit", @@ -2538,7 +3213,9 @@ "website": "https://rybbit.io", "docs": "https://www.rybbit.io/docs" }, - "tags": ["analytics"] + "tags": [ + "analytics" + ] }, { "id": "seafile", @@ -2551,7 +3228,11 @@ "website": "https://seafile.com", "docs": "https://manual.seafile.com/12.0" }, - "tags": ["file-manager", "file-sharing", "storage"] + "tags": [ + "file-manager", + "file-sharing", + "storage" + ] }, { "id": "flagsmith", @@ -2582,7 +3263,9 @@ "website": "https://www.docuseal.com/", "docs": "https://www.docuseal.com/" }, - "tags": ["document-signing"] + "tags": [ + "document-signing" + ] }, { "id": "kutt", @@ -2595,7 +3278,10 @@ "website": "https://kutt.it", "docs": "https://github.com/thedevs-network/kutt#kuttit" }, - "tags": ["link-shortener", "link-sharing"] + "tags": [ + "link-shortener", + "link-sharing" + ] }, { "id": "kener", @@ -2608,7 +3294,12 @@ "website": "https://kener.ing/", "docs": "https://kener.ing/docs/" }, - "tags": ["monitoring", "status-page", "alerting", "self-hosted"] + "tags": [ + "monitoring", + "status-page", + "alerting", + "self-hosted" + ] }, { "id": "palmr", @@ -2621,7 +3312,11 @@ "website": "https://palmr.kyantech.com.br/", "docs": "https://palmr.kyantech.com.br/docs/3.0-beta" }, - "tags": ["file-sharing", "self-hosted", "open-source"] + "tags": [ + "file-sharing", + "self-hosted", + "open-source" + ] }, { "id": "karakeep", @@ -2703,7 +3398,12 @@ "website": "https://github.com/aldinokemal/go-whatsapp-web-multidevice", "docs": "https://github.com/aldinokemal/go-whatsapp-web-multidevice" }, - "tags": ["whatsapp", "self-hosted", "open-source", "api"] + "tags": [ + "whatsapp", + "self-hosted", + "open-source", + "api" + ] }, { "id": "rabbitmq", @@ -2716,7 +3416,11 @@ "website": "https://www.rabbitmq.com/", "docs": "https://www.rabbitmq.com/documentation.html" }, - "tags": ["message-broker", "queue", "rabbitmq"] + "tags": [ + "message-broker", + "queue", + "rabbitmq" + ] }, { "id": "ezbookkeeping", @@ -2772,7 +3476,11 @@ "website": "https://gchq.github.io/CyberChef/", "docs": "https://github.com/gchq/CyberChef/wiki" }, - "tags": ["security", "encryption", "data-analysis"] + "tags": [ + "security", + "encryption", + "data-analysis" + ] }, { "id": "filestash", @@ -2785,7 +3493,11 @@ "website": "https://www.filestash.app/", "docs": "https://www.filestash.app/docs/" }, - "tags": ["file-manager", "document-editor", "self-hosted"] + "tags": [ + "file-manager", + "document-editor", + "self-hosted" + ] }, { "id": "mazanoke", @@ -2798,7 +3510,13 @@ "website": "https://github.com/civilblur/mazanoke", "docs": "https://github.com/civilblur/mazanoke" }, - "tags": ["image-hosting", "file-sharing", "self-hosted", "media", "gallery"] + "tags": [ + "image-hosting", + "file-sharing", + "self-hosted", + "media", + "gallery" + ] }, { "id": "ihatemoney", @@ -2850,7 +3568,11 @@ "website": "https://www.usememos.com/", "docs": "https://www.usememos.com/docs" }, - "tags": ["productivity", "notes", "bookmarks"] + "tags": [ + "productivity", + "notes", + "bookmarks" + ] }, { "id": "linkstack", @@ -2863,7 +3585,12 @@ "website": "https://linkstack.org/", "docs": "https://docs.linkstack.org/" }, - "tags": ["bio", "personal", "cms", "php"] + "tags": [ + "bio", + "personal", + "cms", + "php" + ] }, { "id": "opengist", @@ -2876,7 +3603,12 @@ "website": "https://github.com/thomiceli/opengist", "docs": "https://github.com/thomiceli/opengist" }, - "tags": ["pastebin", "code", "snippets", "self-hosted"] + "tags": [ + "pastebin", + "code", + "snippets", + "self-hosted" + ] }, { "id": "snapp", @@ -2889,7 +3621,12 @@ "website": "https://github.com/UraniaDev/snapp", "docs": "https://github.com/UraniaDev/snapp" }, - "tags": ["screenshot", "sharing", "self-hosted", "authentication"] + "tags": [ + "screenshot", + "sharing", + "self-hosted", + "authentication" + ] }, { "id": "commafeed", @@ -2902,7 +3639,11 @@ "website": "https://www.commafeed.com/", "docs": "https://github.com/Athou/commafeed/wiki" }, - "tags": ["feed-reader", "news-aggregator", "rss"] + "tags": [ + "feed-reader", + "news-aggregator", + "rss" + ] }, { "id": "convertx", @@ -2915,7 +3656,11 @@ "website": "https://github.com/c4illin/ConvertX", "docs": "https://github.com/c4illin/ConvertX#environment-variables" }, - "tags": ["media", "converter", "ffmpeg"] + "tags": [ + "media", + "converter", + "ffmpeg" + ] }, { "id": "metube", @@ -2928,7 +3673,11 @@ "website": "https://github.com/alexta69/metube", "docs": "https://github.com/alexta69/metube/wiki" }, - "tags": ["downloader", "youtube", "media"] + "tags": [ + "downloader", + "youtube", + "media" + ] }, { "id": "pinchflat", @@ -2941,7 +3690,11 @@ "website": "https://github.com/kieraneglin/pinchflat", "docs": "https://github.com/kieraneglin/pinchflat" }, - "tags": ["youtube", "downloader", "media"] + "tags": [ + "youtube", + "downloader", + "media" + ] }, { "id": "yt-dlp-webui", @@ -2954,7 +3707,12 @@ "website": "https://github.com/marcopiovanello/yt-dlp-web-ui", "docs": "https://github.com/marcopiovanello/yt-dlp-web-ui" }, - "tags": ["downloader", "youtube", "media", "webui"] + "tags": [ + "downloader", + "youtube", + "media", + "webui" + ] }, { "id": "flaresolverr", @@ -2967,7 +3725,12 @@ "website": "https://github.com/FlareSolverr/FlareSolverr", "docs": "https://github.com/FlareSolverr/FlareSolverr" }, - "tags": ["proxy", "cloudflare", "bypass", "ddos-guard"] + "tags": [ + "proxy", + "cloudflare", + "bypass", + "ddos-guard" + ] }, { "id": "neko", @@ -2980,7 +3743,12 @@ "website": "https://github.com/m1k1o/neko", "docs": "https://github.com/m1k1o/neko" }, - "tags": ["browser", "virtual", "sharing", "remote"] + "tags": [ + "browser", + "virtual", + "sharing", + "remote" + ] }, { "id": "omni-tools", @@ -2993,7 +3761,12 @@ "website": "https://github.com/iib0011/omni-tools", "docs": "https://github.com/iib0011/omni-tools" }, - "tags": ["tools", "utilities", "collection", "self-hosted"] + "tags": [ + "tools", + "utilities", + "collection", + "self-hosted" + ] }, { "id": "openhands", @@ -3006,7 +3779,12 @@ "website": "https://github.com/all-hands-ai/OpenHands", "docs": "https://github.com/all-hands-ai/OpenHands" }, - "tags": ["ai", "agents", "llm", "openai"] + "tags": [ + "ai", + "agents", + "llm", + "openai" + ] }, { "id": "web-check", @@ -3019,7 +3797,12 @@ "website": "https://github.com/lissy93/web-check", "docs": "https://github.com/lissy93/web-check" }, - "tags": ["website-analyzer", "security", "performance", "seo"] + "tags": [ + "website-analyzer", + "security", + "performance", + "seo" + ] }, { "id": "dumbdrop", @@ -3032,7 +3815,11 @@ "website": "https://www.dumbware.io/software/DumbDrop/", "docs": "https://github.com/dumbwareio/dumbdrop" }, - "tags": ["file-sharing", "self-hosted", "simple"] + "tags": [ + "file-sharing", + "self-hosted", + "simple" + ] }, { "id": "dumbassets", @@ -3045,7 +3832,11 @@ "website": "https://www.dumbware.io/software/DumbAssets/", "docs": "https://github.com/dumbwareio/dumbassets" }, - "tags": ["asset-tracking", "self-hosted", "simple"] + "tags": [ + "asset-tracking", + "self-hosted", + "simple" + ] }, { "id": "dumbpad", @@ -3058,7 +3849,11 @@ "website": "https://www.dumbware.io/software/DumbPad/", "docs": "https://github.com/dumbwareio/dumbpad" }, - "tags": ["notepad", "self-hosted", "simple"] + "tags": [ + "notepad", + "self-hosted", + "simple" + ] }, { "id": "dumbbudget", @@ -3071,7 +3866,12 @@ "website": "https://www.dumbware.io/software/DumbBudget/", "docs": "https://github.com/dumbwareio/dumbbudget" }, - "tags": ["budget", "finance", "self-hosted", "simple"] + "tags": [ + "budget", + "finance", + "self-hosted", + "simple" + ] }, { "id": "tianji", @@ -3084,7 +3884,12 @@ "website": "https://github.com/msgbyte/tianji", "docs": "https://github.com/msgbyte/tianji" }, - "tags": ["analytics", "monitoring", "web", "uptime"] + "tags": [ + "analytics", + "monitoring", + "web", + "uptime" + ] }, { "id": "directory-lister", @@ -3097,7 +3902,11 @@ "website": "https://www.directorylister.com/", "docs": "https://docs.directorylister.com/" }, - "tags": ["file-manager", "directory-listing", "php"] + "tags": [ + "file-manager", + "directory-listing", + "php" + ] }, { "id": "grimoire", @@ -3110,7 +3919,11 @@ "website": "https://github.com/goniszewski/grimoire", "docs": "https://github.com/goniszewski/grimoire" }, - "tags": ["bookmarks", "self-hosted", "knowledge-management"] + "tags": [ + "bookmarks", + "self-hosted", + "knowledge-management" + ] }, { "id": "keycloak", @@ -3123,7 +3936,13 @@ "website": "https://www.keycloak.org/", "docs": "https://www.keycloak.org/documentation" }, - "tags": ["authentication", "identity", "sso", "oauth2", "openid-connect"] + "tags": [ + "authentication", + "identity", + "sso", + "oauth2", + "openid-connect" + ] }, { "id": "openpanel", @@ -3136,10 +3955,11 @@ "website": "https://openpanel.dev/", "docs": "https://openpanel.dev/docs" }, - "tags": ["analytics"] + "tags": [ + "analytics" + ] }, { - "id": "wg-easy", "name": "WG-Easy", "version": "15", @@ -3150,7 +3970,11 @@ "website": "https://wg-easy.github.io/", "docs": "https://github.com/wg-easy/wg-easy/wiki" }, - "tags": ["vpn", "wireguard", "networking"] + "tags": [ + "vpn", + "wireguard", + "networking" + ] }, { "id": "open_notebook", @@ -3163,7 +3987,12 @@ "website": "https://www.open-notebook.ai/", "docs": "https://www.open-notebook.ai/get-started.html" }, - "tags": ["notebook", "ai", "database", "surrealdb"] + "tags": [ + "notebook", + "ai", + "database", + "surrealdb" + ] }, { "id": "booklore", @@ -3176,7 +4005,12 @@ "website": "https://github.com/booklore-app/BookLore", "docs": "https://github.com/booklore-app/BookLore/tree/develop/docs" }, - "tags": ["books", "library", "database", "mariadb"] + "tags": [ + "books", + "library", + "database", + "mariadb" + ] }, { "id": "scrypted", @@ -3189,6 +4023,11 @@ "website": "https://www.scrypted.app/", "docs": "https://docs.scrypted.app/" }, - "tags": ["home-automation", "nvr", "smart-home", "surveillance"] + "tags": [ + "home-automation", + "nvr", + "smart-home", + "surveillance" + ] } -] +] \ No newline at end of file