Many Notes: a PHP Markdown vault that keeps files on disk and metadata in SQLite
Markdown note-taking web application designed for simplicity
At a glance
- What is it?
- Many Notes is a self-hosted Markdown note web application written in PHP, with a Docker image, a SQLite-backed index, and an optional Typesense volume for search. It is aimed at people who want Obsidian-style vaults without a desktop client, and who are willing to run a reverse proxy in front of it.
- Who is it for?
- Adopt Many Notes if you already run Docker and a reverse proxy, want Markdown files you can read without the application, and need multi-user vault sharing with OIDC. Do not adopt it if you want a single-binary install, a hosted service, or an editor that works offline without a server.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 14 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Many Notes targets: Markdown files you own, served over HTTP
The README frames the project around a specific split: a database powers the features, but the files are also saved in the filesystem. That sentence is the whole design argument. Vaults are described as storage containers for files, and the application lets you keep everything in one vault or divide it into several. The audience is therefore narrower than the note-taking category in general. It is for someone who wants the files to remain readable and portable outside the application, and who is willing to run a PHP container to get a browser interface on top of them. The listed features point the same way: multiple users behind authentication, multiple vaults per user, collaboration through vault invitations, import and export of whole vaults, and an export to PDF. None of that is a single-user desktop tool. It is closer to a small internal wiki where the storage format happens to be Markdown. If you want a note app that runs on your laptop with no server, this is the wrong shape, and the repository does not pretend otherwise.
How the data is split between SQLite, the filesystem and Typesense
The default compose file mounts four volumes into the container: database at /var/www/html/database/sqlite, logs at /var/www/html/storage/logs, private at /var/www/html/storage/app/private, and typesense at /var/www/html/typesense. Those four paths tell you most of the architecture. SQLite holds the relational state, the private directory holds application-side files, and Typesense is a separate search engine whose data is persisted in its own volume. The README advertises typo-tolerant search, which is a Typesense capability rather than something SQLite would provide on its own. So the write path is roughly: Markdown goes to disk, index metadata goes to SQLite, and searchable text goes into Typesense. The README does not document the sync order or what happens if Typesense is unreachable while SQLite is writable, and that gap matters. If the search volume is lost or the engine fails to start, the notes themselves are unaffected, but the search feature described as fast and typo-tolerant depends on that fourth volume being present and persistent. Treat the typesense volume as required infrastructure, not a cache you can drop.
Installing it: one compose file, four volumes, and an APP_URL you must change
The README's primary install path is Docker with volumes. You write a compose.yaml with a single php service using the image brufdev/many-notes:latest, restart unless-stopped, the four volume mounts above, and a port mapping of 80:8080. Then you run docker compose up -d. The one setting the README insists you change is APP_URL, which defaults to http://localhost and is described as the address used to access the application. If you move the published port or put a reverse proxy in front, APP_URL has to match, and the README gives the example of APP_URL=http://localhost:8080 for a changed port. Two other environment variables are documented in the same section: APP_TIMEZONE, default UTC, with a link to the PHP timezone list, and PHP_POST_MAX_SIZE plus PHP_UPLOAD_MAX_FILE_SIZE, both defaulting to 500M, which you raise if you plan to import large vaults. The README also documents alternatives to the default setup: bind mounts for host-visible paths, and a different database if you do not want SQLite, each in its own file under docs/installation/.
Authentication: local accounts by default, OIDC when you configure it
Local authentication is on by default, and the README notes that you disable it by configuring an OAuth provider and specifying a post-logout redirect URL. The OpenID Connect block is the most concrete configuration in the document. It uses OIDC_NAME for the login button label, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_REDIRECT_URI, and OIDC_BASE_URL. The example redirect is http://localhost/oauth/oidc/callback, and the README names Pocket ID, Keycloak, Authentik, Entra ID, Auth0, Okta and Google as providers it works with, noting that several OIDC providers can be enabled at once. Dedicated providers for GitHub, GitLab and Slack are mentioned as a separate path with their own documentation. To make OIDC the only way in, you add OIDC_POST_LOGOUT_REDIRECT_URI and set SETTINGS_LOCAL_AUTH_ENABLED=false. That last key is the one to get right before you close the door on local login. There is also a mail block for registration and password reset, with MAIL_MAILER, MAIL_HOST, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD, MAIL_ENCRYPTION, MAIL_FROM_ADDRESS and MAIL_FROM_NAME. If you disable local auth and never configure mail, password reset is not part of your setup, and the README does not describe a recovery path for that case.
The reverse proxy requirement is not optional in practice
The README marks a block as important and states that running Many Notes behind a reverse proxy serving HTTPS is recommended, adding that this secures traffic and gives access to features like PWA support or copying to clipboard from code blocks. Read that second clause carefully. Two advertised features, the progressive web app and clipboard copying from code blocks, are tied to a secure context. The clipboard API in browsers is generally restricted outside HTTPS, and service workers, which a PWA depends on, have the same restriction. So the reverse proxy is not a hardening suggestion you can defer; it is the precondition for part of the feature list. The compose example publishes plain HTTP on port 80, which means the default install is the configuration where those features will not work. That is a real friction point for a first-time user who follows the quickstart exactly and then wonders why the app cannot be installed to a home screen.
Where the design strains: search coupling, upgrade guides and the missing operational detail
The most obvious failure mode is the Typesense dependency. Search is one of the headline features, and it lives in a fourth volume that the README lists without explaining what happens when it is unavailable. A container that starts with SQLite and the filesystem intact but no reachable search backend is not described anywhere in the supplied material. Beyond that, the README points at an UPGRADING.md file and warns you to read it if you are upgrading from a previous version. That warning exists for a reason, and it implies that at least some releases in this project's history required manual steps. The release cadence visible in the repository metadata shows v0.18.0 and v0.17.0 one week apart, with v0.16.2 roughly two and a half months earlier. A project still in the 0.x range with that kind of spacing will occasionally break things, and the upgrade document is the place that cost is recorded. The README also does not cover backup and restore beyond the import and export vaults feature, does not describe resource requirements, and does not say what the private volume holds. Anyone planning to run this for a team should read UPGRADING.md and the docs/installation files before the first deploy, not after.
Alternatives and the actual difference in approach
The closest widely used alternative is a file-first wiki such as Wiki.js or a Git-backed documentation tool, and the difference is where the source of truth lives. Many Notes keeps a database in the loop: SQLite carries the relational state and Typesense carries the search index, while the Markdown files sit on disk as a portable copy. A Git-backed tool inverts that, treating the repository as the only state and rebuilding any index from it, which means a lost volume costs you a reindex rather than a restore. The trade-off runs the other way too. A pure file-and-Git approach makes collaboration a merge problem, whereas Many Notes handles it through vault invitations and the broadcasting feature that the README describes as real-time, live-updating user interfaces. If your team already resolves Markdown conflicts in pull requests, Many Notes is solving a problem you have already solved, and it adds two stateful volumes you now have to back up. If your team does not want to touch Git at all, that is exactly the case this project is built for.
Licence and the ongoing cost of running it
The project is MIT licensed, which the repository metadata and the README badge both confirm. In practical terms that permits commercial use and modification, but this is not legal advice and you should read the licence text yourself if you plan to redistribute a modified image. The maintenance cost is the part worth being honest about. You are running a PHP application container plus a search engine, with four named volumes to persist and back up. Every upgrade should go through UPGRADING.md, and the recent release spacing suggests those upgrades arrive often. The README mentions an automatic update check that notifies you when a new version is available, so the application will tell you when there is work to do. Budget for reading release notes and the upgrade guide on a regular schedule, and for testing the restore path of the database, private and typesense volumes at least once before you trust the setup with notes you care about.
Editorial conclusion
Adopt Many Notes if you already run Docker and a reverse proxy, want Markdown files you can read without the application, and need multi-user vault sharing with OIDC. Do not adopt it if you want a single-binary install, a hosted service, or an editor that works offline without a server. Before committing, verify three things on your own host: that the typesense volume is writable and persists across container recreation, that your reverse proxy terminates HTTPS at the APP_URL you set, and that your chosen OIDC provider returns the exact OIDC_REDIRECT_URI you configured, since the README lists that callback path explicitly.
Community notes