Many Notes: a self-hosted Markdown vault app in PHP and Docker
Markdown note-taking web application designed for simplicity
At a glance
- What is it?
- Many Notes is a self-hosted Markdown note app that keeps its data in both SQLite and plain files. Here is how the Docker install works, what the database-plus-filesystem design costs you, and who should skip it.
- Who is it for?
- Adopt Many Notes if you want a self-hosted Markdown vault with real user accounts, OIDC login and PDF export, and you are willing to run PHP behind a reverse proxy with HTTPS. Do not adopt it if you need a desktop client, an offline-first sync engine, or a storage model where the filesystem is the single source of truth.
- 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 29 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 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Many Notes solves, and for whom
Many Notes is a Markdown note-taking web application written in PHP, released under the MIT licence. The README frames it as "designed for simplicity", and the feature list is aimed at one deployment shape: a server you control, reached through a browser, holding notes that stay readable as plain files.
The audience is narrow and fairly clear. It is for people who already run Docker and a reverse proxy, and who want several users on one instance rather than one person with one folder. The README lists multiple users, multiple vaults per user, OpenID Connect and OAuth, collaboration through vault invitations, and real-time broadcasting. A single-user setup is possible, but you are paying for the multi-user machinery either way.
The second audience is anyone who has been burned by a note app that locks content in a proprietary store. The README states that the application "uses a database to power its features, but your files are also saved in the filesystem", which the project presents as control and portability. That promise is the main reason to look at this project rather than a hosted alternative, and it is also where the interesting trade-offs live.
The database-plus-filesystem storage model
The architecture is a Laravel application with a Vue front end. The repository layout confirms the stack: app/, config/, database/, routes/, resources/ and tests/ sit alongside composer.json, package.json, vite.config.js and typesense/. The front end is a Vue single-page app built with Vite and Inertia, using TipTap for the editor and Tailwind for styling. The environment example sets DB_CONNECTION=sqlite, SESSION_DRIVER=database, QUEUE_CONNECTION=database and CACHE_STORE=database, so a default install leans on the database for more than note content.
The part worth understanding before you commit is the split between the database and the filesystem. The compose file mounts four named volumes: database:/var/www/html/database/sqlite for the SQLite file, logs:/var/www/html/storage/logs, private:/var/www/html/storage/app/private, and typesense:/var/www/html/typesense. A fifth path is not mounted at all in the default example: the vault files themselves. The README's bind-mounts guide exists precisely because people want the note directory visible on the host, which tells you the default volume layout does not put your Markdown where you can casually browse it.
Typesense is the second piece of infrastructure. The README advertises "fast and typo-tolerant search", and a dedicated typesense volume plus a typesense/ directory in the repository point to a search service rather than SQL LIKE queries. That is a real design decision with a real cost: search is only as current as the index, and the index is another thing to back up. The README does not describe index rebuild behaviour, so treat search freshness as something to verify on your own instance rather than assume.
Installing Many Notes with Docker Compose
The README gives Docker with volumes as the simpler path, with bind mounts and a non-SQLite database documented separately in docs/installation/. Create a compose.yaml in an empty directory with the service definition from the README, adjusting APP_URL to the address you will actually use:
services:
php:
image: brufdev/many-notes:latest
restart: unless-stopped
environment:
- APP_URL=http://localhost
volumes:
- database:/var/www/html/database/sqlite
- logs:/var/www/html/storage/logs
- private:/var/www/html/storage/app/private
- typesense:/var/www/html/typesense
ports:
- 80:8080
volumes:
database:
logs:
private:
typesense:The container listens on 8080 internally and the example publishes it on host port 80. Start it in the background:
# starts the php service and creates the four named volumes
docker compose up -dAfter the container starts, open the address in APP_URL. The README mentions a starter vault that helps you get started, so expect the first login to offer something rather than an empty screen. If you change the host port away from 80, the README is explicit that APP_URL must match, for example APP_URL=http://localhost:8080, otherwise redirects and asset URLs point at the wrong place.
Two settings are worth changing before you put real notes in. Set the timezone, since the default is UTC:
environment:
- APP_TIMEZONE=Europe/AmsterdamAnd raise the upload ceiling if you plan to import large vaults, because the default post and upload limits are 500M:
environment:
- PHP_POST_MAX_SIZE=1G
- PHP_UPLOAD_MAX_FILE_SIZE=1GThe README recommends running the application behind a reverse proxy serving HTTPS. It gives two concrete reasons: secure traffic, and access to PWA support and copying to clipboard from code blocks. Those two features depend on a secure context, so a plain HTTP deployment loses them.
Authentication choices and what disabling local login means
Local authentication is on by default. The README shows how to turn it off by configuring an OpenID Connect provider and supplying a post-logout redirect, with SETTINGS_LOCAL_AUTH_ENABLED=false. The example uses Pocket ID, and the README names Keycloak, Authentik, Entra ID, Auth0, Okta and Google as providers that work through OIDC. Dedicated providers exist for GitHub, GitLab and Slack, documented in docs/customization/oauth.md.
The failure mode here is worth stating plainly. Once local authentication is disabled, the identity provider becomes the only way in. If the provider is unreachable, or the client secret is wrong, or OIDC_REDIRECT_URI does not match the URL the browser actually uses, you have a running application and no way to log into it. The README does not document a recovery path for that state, and there is no mention of a local break-glass account. Keep the compose file under version control so you can flip SETTINGS_LOCAL_AUTH_ENABLED back and restart if you lock yourself out.
The redirect URI is the other common trap. The example value is http://localhost/oauth/oidc/callback, which must match the callback registered with the provider and the scheme and host in APP_URL. Behind a reverse proxy, this is where mismatched APP_URL settings surface as login loops rather than clear errors.
Where Many Notes is the wrong tool
The most obvious limitation is that there is no desktop client. The repository is a Laravel web application with a Vue front end and a PWA plugin; the README's portability story is about files on the server, not about a native app that syncs a local folder. If your workflow depends on editing notes offline on a laptop and having them reconcile later, nothing in the README describes that.
The storage model is the second constraint. Notes are described as saved in the filesystem, but the default Docker install keeps that filesystem inside a named volume, and the database sits alongside it. The README's bind-mount guide is the supported way to get shared paths on the host, which means anyone who wants their Markdown visible at a known path should read docs/installation/docker-bind-mounts.md rather than assume the default layout gives it to them. If you want the filesystem to be the single source of truth, with no application database in the middle, this is not that application.
The upgrade path is the third. The README opens the installation section with a pointed instruction to read UPGRADING.md when moving from a previous version, and the release history shows why: v0.16.2 in June 2026, then v0.17.0 and v0.18.0 in late August and early September 2026. Two minor releases in a week is a normal pace for a young project, and it means upgrade notes are not optional reading. If you cannot tolerate a migration step between versions, wait.
Finally, scale. Everything in the default compose file is one PHP service with SQLite, a database-backed queue and cache, and a local Typesense index. The README offers a guide for using a different database, but nothing about horizontal scaling or multiple application nodes. This is a personal or small-team instance, not a platform.
Alternatives and how they differ in approach
Obsidian is the comparison people reach for, and the difference is architectural rather than cosmetic. Obsidian is a local desktop application whose vault is a folder on your machine; collaboration and sync are add-ons around that core. Many Notes inverts it: the server is the core, the vault lives in a Docker volume, and the browser is the client. If you want a local-first vault that works on a plane, the desktop model wins. If you want a URL your collaborators can open with their own accounts, Many Notes is built for that from the start.
Self-hosted note servers are the closer comparison. The topics list groups this project with wiki and knowledge-base software, and the related searches people run against it include Memos, Blinko, Trilium Notes and Standard Notes. The meaningful difference to check is the storage contract. Many Notes keeps a database for features and files for content, and the README's portability claim rests on the second half. A system that treats the filesystem as the only store has a simpler backup story. A system that treats the database as the only store has a simpler consistency story. Many Notes asks you to back up both, which is the price of the feature set it advertises.
Within the same stack, the honest alternative is a plain Laravel application with a Markdown editor, or a static site generator over a Git repository. Both are less capable and much easier to reason about. Many Notes earns its place when you specifically need accounts, vault-level sharing, live updates and search in one installable unit.
Maintenance, upgrades and licence
The repository is not archived, and the last push was on 2026-09-01, which is recent enough that the project is being worked on. The release cadence supports that: v0.18.0 on 2026-09-01, v0.17.0 on 2026-08-26, and v0.16.2 on 2026-06-13. Version numbers are still in the 0.x range, which is the project's own signal that interfaces and upgrade steps can change.
Operationally, the cost is four volumes and a PHP container. The database, logs, private storage and Typesense index all need to be in your backup set, and UPGRADING.md is the file to read before any version bump. The README also mentions an automatic update check that notifies you when a new version is available, so the application will tell you when you are behind; it does not upgrade itself.
The licence is MIT, which is permissive and places few obligations on how you deploy or modify the code. That is a statement about the licence text, not legal advice, and it says nothing about the licences of the bundled dependencies in composer.json and package.json, which you would need to review separately if you redistribute the application.
Editorial conclusion
Adopt Many Notes if you want a self-hosted Markdown vault with real user accounts, OIDC login and PDF export, and you are willing to run PHP behind a reverse proxy with HTTPS. Do not adopt it if you need a desktop client, an offline-first sync engine, or a storage model where the filesystem is the single source of truth. Before trusting a vault to it, verify the UPGRADING.md notes for your starting version, confirm that the private and typesense volumes are in your backup set, and test one vault import and export round trip.
Frequently asked questions
What is a Markdown note in Many Notes?
It is a note written in Markdown and stored by the application, which the README describes as saving your files in the filesystem while using a database to power its features. The editor is built on TipTap, and the feature list includes links, backlinks and tags for connecting notes.
Is there a limit to how many notes you can have in Many Notes?
The README does not state a note count limit. It does document a default upload size limit of 500M, configurable through PHP_POST_MAX_SIZE and PHP_UPLOAD_MAX_FILE_SIZE, which matters when importing a vault rather than when creating notes one at a time.
How does Many Notes compare to Obsidian?
Many Notes is a self-hosted web application with server-side user accounts, vault sharing and OIDC login, installed through Docker. Obsidian is not covered by this project's documentation, so the comparison the documentation supports is only about deployment shape: Many Notes runs on a server you reach through a browser.
What is the best shareable note-taking app?
That is a general question rather than one about Many Notes. What the README documents for this project is vault sharing through invitations, multiple users behind authentication, and OpenID Connect or OAuth login, all on an instance you host yourself.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/brufdev-many-notes)