This fork has following changes compared to upstream
- Available on GitHub Container Registry -
ghcr.io/rubberverse/flatnotes:latest(arm64builds provided as-is, can't test them) - Merged PR from upstream: OIDC support by
anujc4via #351 - Merged PR from upstream: Prevent focus on background element while Modal is open by
noahhefnervia #349 - Merged PR from upstream: Shell hooks by
reddecvia #190 only onalpine-97c5bedand97c5bedtag. - Rootless user by default inside container
- Removes
entrypoint.shandhealtcheck.shas they're no longer needed,curlalso didn't make the cut - Runs app on
0.0.0.0:9102, override entrypoint if you want something different - Cleaner
Containerfilethat I threw up together - Debian Trixie & Alpine Linux images for both builder (
node:lts) and runner (python:3.13.13) - Adds Podman Quadlet files inside
quadlet/directory so you can quickly spin this up yourself - Updates all
NodeJSandPipfiledependencies and packages to latest version - Proper package locking for both Pipfile and NodeJS
- Upgraded Tailwind CSS to V4 (from V3)
- Updated stylesheet to support Tailwind V4 in
client/style.css - Uses
Python 3.13.13instead ofPython 3.10 - Added
@tailwind/postcssplugin topostcss.config.jsanddevDependenciesinpackage.json - Fixed bugs related to Tailwind CSS upgrade in
client/components/PrimeToast.vue,client/partials/SearchModal.vue - Removed extra checkmark from toast notification in
client/views/Note.vue - Hamburger menu has hover over mouse effects now, not sure if it always had but it also broke with Tailwind CSS upgrade in
client/components/PrimeMenu.vue
FYI, Alpine image is smaller by 100MB compared to Debian - 161MB (Alpine) vs 261MB (Debian)
I'll preface by saying that I'm not a web developer, I can dabble into it and know how to modify HTML or CSS, however that's where my knowledge ends. I've tried my best by reading documentation of each component used here and I've only consulted a clanker in case I've needed an advice, or I didn't understand why something happens. Most of the time I came to conclusion myself mid-way but there were special cases where I didn't and had to delve more into understanding as to why something happens. Once I felt comfortable enough and knew it wasn't anything bogus, I've done a small change. This mostly just touched two files.
style.css as I initially had no idea how to move those colors from tailwind.css.js, though the final change was made by me after reading this stackoverflow thread regarding theme vs theme inline.
client/components/PrimeToast.vue was beating me into the mud but the fix was very simple to do. I'm ashamed to say that I had to bow down to the clanker for this one, as the solution would've been easily figured out if I actually read words on my screen and connected the dots. Such is life I guess.
The rest was me figuring out things and messing around as apart of my smol learning adventure. Crap like new Pipfile.lock, Containerfile, package-lock.json etc. so now I know how to do 'em for future projects of mine. Shoutouts to Tailwind CSS for their amazing documentation for the note. They even had an utility which made jumping versions easier. It wasn't 100% magical switch but it made things way more manageable. Also various StackOverflow and Reddit threads I've stumbled upon ig.
Original project description can be found below this line.
It's shrimple. Create a client in your OIDC provider and then copy and fill this .env out. Here's an example for VoidAuth
FLATNOTES_AUTH_TYPE=oidc
FLATNOTES_OIDC_PROVIDER_NAME=MyProvider
FLATNOTES_OIDC_AUTO_REDIRECT=false
FLATNOTES_OIDC_PROVIDER_URL=https://auth.localhost.domain.tld/oidc
FLATNOTES_OIDC_REDIRECT_URI=https://notes.localhost.domain.tld/api/auth/oidc/callback
FLATNOTES_OIDC_CLIENT_ID=ClientIDFromDashboard
FLATNOTES_OIDC_CLIENT_SECRET=ClientSecretFromDashboard
FLATNOTES_SECRET_KEY=RandomlyGenerated32CharLongStringYou can mount it to the container afterwards like so
EnvironmentFile=%h/Environments/Flatnotes/.envNote
If you keep getting redirect_uri with container_name:port then you need to configure your reverse proxy properly.
uvicorn by default will trust proxy headers in current container entrypoint. If you modified entrypoint and forgot to pass --proxy-headers to uvicorn then that's why.
Here's an example for Caddy. Some of these are reduntant but in case X-Forwarded-Host or X-Forwarded-For is not being set, you'll see that problem above. Explictly setting it like this works wonders.
notes.domain.tld {
reverse_proxy flatnotes:9102 {
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Port {server_port}
}
}A self-hosted, database-less note-taking web app that utilises a flat folder of markdown files for storage.
Log into the demo site and take a look around. Note: This site resets every 15 minutes.
flatnotes is designed to be a distraction-free note-taking app that puts your note content first. This means:
- A clean and simple user interface.
- No folders, notebooks or anything like that. Just all of your notes, backed by powerful search and tagging functionality.
- Quick access to a full-text search from anywhere in the app (keyboard shortcut "/").
Another key design principle is not to take your notes hostage. Your notes are just markdown files. There's no database, proprietary formatting, complicated folder structures or anything like that. You're free at any point to just move the files elsewhere and use another app.
Equally, the only thing flatnotes caches is the search index and that's incrementally synced on every search (and when flatnotes first starts). This means that you're free to add, edit & delete the markdown files outside of flatnotes even whilst flatnotes is running.
- Mobile responsive web interface.
- Raw/WYSIWYG markdown editor modes.
- Advanced search functionality.
- Note "tagging" functionality.
- Customisable home page.
- Wikilink support to easily link to other notes (
[[My Other Note]]). - Light/dark themes.
- Multiple authentication options (none, read-only, username/password, 2FA).
- Restful API.
See the wiki for more details.
A quick and easy way to get started with flatnotes is to host it on PikaPods. Just click the button below and follow the instructions.
If you'd prefer to host flatnotes yourself then the recommendation is to use Docker.
docker run -d \
-e "PUID=1000" \
-e "PGID=1000" \
-e "FLATNOTES_AUTH_TYPE=password" \
-e "FLATNOTES_USERNAME=user" \
-e 'FLATNOTES_PASSWORD=changeMe!' \
-e "FLATNOTES_SECRET_KEY=aLongRandomSeriesOfCharacters" \
-v "$(pwd)/data:/data" \
-p "8080:8080" \
dullage/flatnotes:latestversion: "3"
services:
flatnotes:
container_name: flatnotes
image: dullage/flatnotes:latest
environment:
PUID: 1000
PGID: 1000
FLATNOTES_AUTH_TYPE: "password"
FLATNOTES_USERNAME: "user"
FLATNOTES_PASSWORD: "changeMe!"
FLATNOTES_SECRET_KEY: "aLongRandomSeriesOfCharacters"
volumes:
- "./data:/data"
# Optional. Allows you to save the search index in a different location:
# - "./index:/data/.flatnotes"
ports:
- "8080:8080"
restart: unless-stoppedSee the Environment Variables article in the wiki for a full list of configuration options.
I want to keep flatnotes as simple and distraction-free as possible which means limiting new features. This said, I welcome feedback and suggestions.
If you're interested in contributing to flatnotes, then please read the CONTRIBUTING.md file.
If you find this project useful, please consider buying me a beer. It would genuinely make my day.
A special thanks to 2 fantastic open-source projects that make flatnotes possible.
- Whoosh - A fast, pure Python search engine library.
- TOAST UI Editor - A GFM Markdown and WYSIWYG editor for the browser.