The database password gets pasted into a connection URL
A personal note repository that looks different🤔
At a glance
- What is it?
- A self-hosted notes application with a separated frontend and backend, an optional AI layer over your own notes, and an iOS client that can point at your own server. The deployment instructions are unusually explicit about the traps, and several of those traps are load-bearing: a password format restriction, a pull policy that defeats version pinning, and an AI feature that is not in the stable image.
- Who is it for?
- This is a well-run self-hosted notes project that takes the boring parts seriously: a generated password requirement rather than an optional one, a health-gated database dependency, a health check, and a migration step that runs at startup rather than by hand. Two things to decide before you install.
- 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 received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The database password gets pasted into a connection URL
The compose file builds its database connection by interpolating the password straight into a connection string, and the instructions warn about it in four separate sentences. Use a strong password. Use one that is URL safe. Avoid the characters that are legal in a URL but reserved inside a credential. And, the one that catches people, keep the password unchanged after the database volume has been initialised, because the database has already stored the old one. The default value shipped in the documentation is a placeholder that everyone pastes unchanged on a first run:
# 1. Create a .env file beside docker-compose.yml
cat > .env <<'EOF'
VITE_API_BASE=http://YOUR_SERVER_IP:18000
POSTGRES_PASSWORD=change_this_password
EOF
# 2. Replace YOUR_SERVER_IP and change_this_password before first start.
# Use a strong URL-safe password. Avoid characters such as @ : / # % in POSTGRES_PASSWORD.
# Keep this password unchanged after the database volume has been initialized.
# 3. Start Rote with the latest stable image
docker compose up -dThe compose file does at least make the variable mandatory, failing with a message if it is unset rather than starting with an empty password. It is still a password in a URL, so any process that can read the environment can read it.
Pinning a version tag is undone by the pull policy
The compose file sets the image tag from a variable that defaults to the latest stable release, and the documentation tells you how to pin a specific version instead. The same service also sets a pull policy of always, and a compose file that always pulls will re-fetch a tag on every start rather than trusting what is already present. If the tag you pinned is a moving one, which is exactly what the default is, that is not surprising. If the tag is a version number, the policy is harmless but pointless. The comment beside it explains the intent, that the default is deliberately stable and the development tag is for testing unreleased features before promotion, which is a good reason to have two tags and not a good reason to always pull one. The same list of available tags also names a second tag as identical to the first, alongside a branch tag and a main tag.
The headline AI feature is not in the stable image
Memory is the capability that distinguishes this from any other notes application: chat over your own notes and articles, semantic search, related notes, streamed answers and source references. It is also optional, disabled by default, described as available in the development image, and said to be available in stable images after the next release that includes it. The feature list on the same page presents it as shipping. So the thing you came for is behind a tag, and the documentation tells you to enable it from an admin screen only after configuring chat and embedding providers, turning on the vector extension and backfilling everything already written. Upgrading an existing database to the vector layout is a separate migration, and the guide for it is written in Chinese.
Public semantic discovery is a switch apart from private search
The AI feature list has one bullet that deserves to be read on its own, because it separates two things that usually arrive bundled. AI, vector storage and automatic indexing are off until an administrator turns them on, and public semantic discovery is a fourth item on the same list, also off by default. Private semantic search over your own notes is therefore an admin decision, and letting anyone else find your notes by meaning is a second, separate one. Access itself is a permission that can be granted by role or per user, and only users holding it get their notes indexed. One useful boundary is stated plainly: AI conversations live in the current browser session and are not written to the database, so the chat history disappears with the tab.
The iOS client configures itself behind a multi-tap gesture
There is a native client in the app store, and it can point at a self-hosted backend. The documented procedure has three steps and the first of them is a piece of interface folklore: on the login page, tap the welcome text at the top several times to open the configuration dialog, then set the base address to your public or proxied URL, then log in normally. There is no menu item, no settings row and no documented way to discover the gesture other than being told about it. That is a reasonable pattern for a client that connects to somebody else's server, and a poor one for support, because the first report of a user who cannot connect is a user who cannot find the field. The base address has to be a URL reachable from the phone, which is the other thing the step quietly depends on.
Two host ports and a custom domain that needs a second variable
The quick start asks you to set one variable to your server address on the backend port, and the compose file publishes that port to an internal one. Then it tells you to open a different port to reach the setup page, which is the web service rather than the API. So a first run touches two host ports, and the variable you just set is not the one you browse to. The second deployment path, a platform that generates a domain for you and offers Rote as a template, has a documented foot-gun: if you attach your own domain instead of the generated one, you must remember to set the same variable again, or the frontend will keep talking to the address from before. A reverse proxy adds one more place to get it wrong, since the variable has to point at the backend address behind the proxy rather than at the public site.
Two of the five documentation links are Chinese only
The documentation list offers five guides, and the page around them is in English with a language switch at the top for the main readme. The API endpoint guide and the API key guide are English. The guide for upgrading an existing database to the vector layout is Chinese, and the guide for running a small model on the user's own machine so that model requests never pass through the server is also Chinese, and both file names carry the language suffix while the link text does not. So a reader who needs the migration path, which is exactly the reader with an existing installation, ends up reading a document in the other language. The alternative for the local model route is spelled out in its title, which is the useful part: the point of that guide is that the model runs on the user's machine rather than on the server.
Editorial conclusion
This is a well-run self-hosted notes project that takes the boring parts seriously: a generated password requirement rather than an optional one, a health-gated database dependency, a health check, and a migration step that runs at startup rather than by hand. Two things to decide before you install. The database password is interpolated into a connection URL, so choose a URL-safe one and never change it after the volume initialises, because the second half of that sentence is the kind of instruction people discover three months later when a restart fails. And the AI layer, which is the most interesting part of the product, ships disabled and is not in the stable image yet, so plan to test against the development tag and accept that it can change underneath you.
Frequently asked questions
How do I deploy Rote?
Copy the compose file to a server with Docker and Docker Compose, create an environment file beside it with the API base address set to your server on the backend port and a database password you choose, then start the stack. After the containers are up you open the web port, complete the setup page and create the first administrator account.
Why does my Rote database password have character restrictions?
Because the compose file interpolates it into a database connection URL. The instructions ask for a strong URL-safe password and warn against characters that are legal in a URL but reserved inside a credential, and they also say to keep the same value after the database volume has been initialised.
Is the Rote AI feature available in the stable release?
Not yet. The documentation describes it as available in the development image and due in stable images after the next release that includes it. It is disabled by default even there, and an administrator has to configure chat and embedding providers, enable the vector extension and backfill existing notes before using it.
Are my AI conversations stored on the server?
No. The documentation states that AI conversations stay in the current browser session and are not persisted to the database. Notes and articles are indexed only for users who hold the AI chat permission, and only when an administrator has turned on vector storage and automatic indexing.
Can the Rote iOS app use my own server?
Yes. On the login page you tap the welcome text at the top several times to open a configuration dialog, set the base address to your public or proxied backend URL, and then log in normally. The gesture is the only documented way to reach that setting.
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/rabithua-rote)