Add Synaplan - #5962
Open
cristiangrxs wants to merge 1 commit into
Open
Conversation
cristiangrxs
added a commit
to metadist/synaplan
that referenced
this pull request
Aug 7, 2026
The package went in at getumbrel/umbrel-apps#5962; the placeholder can now point at the real pull request.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type
New app
App
App ID:
synaplanUpstream project: https://github.com/metadist/synaplan
Version: 4.0.15
Summary
Synaplan is a self-hosted AI workspace: chat against the provider of your choice,
upload documents and search them by meaning, keep long-term memories, and publish
embeddable chat widgets for your own websites. It is AGPL-3.0, developed by
Metadist, and this package is maintained by us as the upstream project.
The package runs nine services: three app roles that share one image (
web,worker,scheduler), MariaDB, Redis, Centrifugo for realtime, Apache Tika fordocument text extraction, and Qdrant for vector search.
Cloud AI only. The reference deployment ships optional Ollama and Whisper
services; they are deliberately absent here. Local inference needs far more memory
than a typical Umbrel device has, and umbrelOS already offers Ollama as its own
app. After the first login the user adds a provider key under Admin > AI Providers.
The manifest description says so near the top, because it is required before the
first answer.
Verification
Umbrel testing performed:
Installed from a clean umbrelOS 1.7.4 instance with this exact package, running
the pinned digest unmodified (
docker inspectconfirmsghcr.io/metadist/synaplan@sha256:0aa4123d5e74d683a2f26e904e8f1421629575030f62ab2335fcf4ec93230d7b).healthy;apps.state.queryreportsready.app_proxyport and umbrelOS shows thedeterministicPasswordcredentials before launch.Set-CookiecarriesHttpOnly; SameSite=Strictand noSecure. This was a realblocker — up to 4.0.13 Synaplan marked its auth cookies
SecurewheneverAPP_ENV=prod, so on umbrelOS the user logged in and was anonymous again onerequest later. 4.0.14 derives the flag from the
APP_URLscheme instead.the setup banner clears and the first message is answered. This was the second
blocker, and the reason the pin is 4.0.15 rather than 4.0.14. Fresh accounts are
created with per-user model bindings that point at a recommended provider, which
on an App Store install is chosen before any key exists — so the bootstrap
administrator kept being routed at a provider they never configured, and the
composer stayed locked behind "no AI provider connected" no matter which key they
added. 4.0.15 falls back to the working global default and reactivates the stored
preference once its provider has credentials.
PROXY_AUTH_ADD: "false": an admin endpoint answers401without a session and
200with one;/widget.jsstays public withAccess-Control-Allow-Origin: *./connection/websocketupgrades with101 Switching Protocolsthroughapp_proxyand Caddy.mount and from the worker container.
document is still listed, and the generated secrets file is byte-identical.
is byte-identical, the app still opens its database, the original admin password
still works, and the uploaded document is still there (see Notes).
Environment tested:
Architecture tested:
amd64is published in the same manifest list and built and tested in our CI, butthe runtime install above was done on
arm64only.Known lint warnings or caveats:
npm run lint:apps -- synaplan --check-imagesreports no issues.Notes
No host access. No privileged mode, no host networking, no Docker socket, no
device or host mounts, no
permissions:, nodependencies:. All state lives under${APP_DATA_DIR}/data/....PROXY_AUTH_ADD: "false"is deliberate. Synaplan has its own multi-useraccounts with roles, and three of its surfaces cannot carry an Umbrel session
cookie at all: the chat widget embedded on third-party websites, the MCP endpoint
with its OAuth discovery documents, and mobile clients authenticating with a bearer
token. A path whitelist would have to cover most of the API, so the app's own auth
is the boundary — verified above.
Default credentials.
admin@umbrel.localwithdeterministicPassword: true.BOOTSTRAP_ADMIN_PASSWORDis wired to${APP_PASSWORD}and read only while noadministrator exists, so a changed value cannot lock anyone out.
Secrets are derived once and then persisted.
exports.shderives six secretswith
derive_entropyand keeps them indata/secrets.env(mode0600), which winson every later start. The reason is a specific failure mode: an umbrelOS backup
contains
homeandapp-dataonly, while the seed lives indb/umbrel-seedand isregenerated at random when missing. Restoring this app onto a different device would
otherwise derive a new database password while the restored data directory still
expects the old one — a permanent lockout with no user-visible cause. Happy to drop
this and rely on
derive_entropyalone if you prefer.One cosmetic consequence remains and we could not avoid it: after such a restore
Umbrel derives the password it displays from the new device's seed, while the
account keeps the one it was created with. The data is intact; only the displayed
credential is wrong.
Two environment variables exist for the shared network. Every app on a device
shares
umbrel_main_network, so bare service names likeredisorcentrifugoareambiguous between apps. All internal addresses use the injected container names. Two
of them are not plain application config, so upstream gained
REALTIME_UPSTREAM_ADDR(the Caddy upstream for/connection/*) andSYNAPLAN_WEB_HEALTH_URL(what the worker and scheduler block on) for this purpose.LAN-only limitations, all documented in the manifest description or expected on
an Umbrel: WhatsApp media delivery and Google/GitHub/Apple sign-in need a publicly
reachable instance; a widget embedded on a public website cannot open its realtime
connection because
REALTIME_ALLOWED_ORIGINSis pinned to the Umbrel origin;reaching the app by IP or through a Tailscale hostname keeps everything working
except that realtime channel.
Screenshots and logo
Not committed —
galleryis[]as the packaging guide asks, so these are reviewmaterial for you to work from.
Logo (512×512 PNG, source SVG)
Screenshots (1600×1000 at 2×, light theme, captured from a running install)