jotty

jotty

Docker app from fccview's Repository

Overview

jotty-page is a lightweight alternative for managing your personal checklists and notes. It's extremely easy to deploy, keeps all your data on your own server and allows you to encrypt/decrypt your notes for your personal peace of mind.

Jotty Logo

jotty·page


A self-hosted app for your checklists and notes.

jotty·page is a lightweight alternative for managing your personal checklists and notes. It's extremely easy to deploy, keeps all your data on your own server and allows you to encrypt/decrypt your notes for your personal peace of mind.

ex rwMarkable




Join our communities



Clean, intuitive interface for managing your checklists and tasks.

Notes Home View

Rich text editor for notes.

Note Editor

Quick nav


Buy me a coffee

Features

  • Checklists: Create task lists with drag & drop reordering, progress bars, and categories. Supports both simple checklists and advanced task projects with Kanban boards and time tracking.
  • Rich Text Notes: A clean WYSIWYG editor for your notes, powered by TipTap with full Markdown support and syntax highlighting.
  • Sharing: Share checklists or notes with other users on your instance, including public sharing with shareable links.
  • File-Based: No database needed! Everything is stored in simple Markdown and JSON files in a single data directory.
  • User Management: An admin panel to create and manage user accounts with session tracking.
  • Customisable: 14 built-in themes plus custom theme support with custom emojis and icons.
  • Encryption: Full on PGP encryption, read more about it in howto/ENCRYPTION.md
  • API Access: Programmatic access to your checklists and notes via REST API with authentication.
  • PWA Jotty doesn't have a native app, but it's built mobile first. Once installed the PWA on your device it will feel like you installed it from the app store. There's also partial offline caching, as long as you visited a page while online Jotty will allow you to re-visit it while offline. At the moment there's no current support for offline CRUD operation.

Getting Started

My recommended way to run jotty·page is with Docker. You can also use:

Docker Compose (Recommended)

  1. Create a docker-compose.yml file:

    📖 For advanced settings and more information about how the docker compose file works and what these variables do, please read howto/DOCKER.md

    services:
      jotty:
        image: ghcr.io/fccview/jotty:latest
        container_name: jotty
        user: "1000:1000"
        ports:
          - "1122:3000"
        volumes:
          - ./data:/app/data:rw
          - ./config:/app/config:rw
          - ./cache:/app/.next/cache:rw
        restart: unless-stopped
        environment:
          - NODE_ENV=production
    
  2. Create the data directory and set permissions:

    mkdir -p config data/users data/checklists data/notes data/sharing data/encryption cache
    sudo chown -R 1000:1000 data/
    sudo chown -R 1000:1000 config/
    sudo chown -R 1000:1000 cache/
    

    Note: The cache directory is optional. If you don't want cache persistence, you can comment out the cache volume line in your docker-compose.yml.

  3. Start the container:

    docker compose up -d
    

The application will be available at http://localhost:1122.

Initial Setup

On your first visit, you'll be redirected to /auth/setup to create your admin account if SSO is disabled, otherwise you'll be prompted to sign in via your choosen SSO provider.

Once that's done, you're ready to go! First user will be admin by default.

Data Storage

jotty·page uses a simple file-based storage system inside the data/ directory.

  • data/checklists/: Stores all checklists as .md files.
  • data/notes/: Stores all notes as .md files.
  • data/users/: Contains users.json and sessions.json.
  • data/sharing/: Contains shared-items.json.
  • data/encryption/: Contains all public/private keys for all users.

Make sure you back up the data directory!

Versioning Scheme

This project uses a [STABLE].[FEATURE].[FIX] versioning scheme, not strict SemVer. As a product (not a package), this format makes more sense for my specific release cycle.

My format is 1.10.1, which breaks down as:

  • 1.x.x (Stable): The 1 represents the current stable generation. I will only change this (e.g., to 2.0.0) for a complete rewrite or a fundamental shift in the product or seriously breaking changes.

  • x.10.x (Feature): This is the main release number. I increment this for new features, code refactors, or significant changes (e.g., 1.9.0 -> 1.10.0). This is the equivalent of a SemVer MINOR bump.

  • x.x.1 (Fix): This is incremented only for hotfixes, bug-fix-only and very minor feature releases (e.g., 1.10.0 -> 1.10.1). This is the equivalent of a SemVer PATCH bump.

A Note on "Breaking" Changes

A Feature release (like 1.10.0) may include major backend or data structure changes. When this happens, I will always provide an automatic migration script that runs on first launch to update your data seamlessly.

Because the migration is automatic, I do not consider this a "breaking" change that requires a 2.0.0 version.

I will always detail these migrations in the release notes. I highly recommend you back up your data before any feature update, just in case.

SUPPORTED MARKDOWN

jotty·page supports GitHub Flavored Markdown (GFM) and some custom syntax for complex functionality.

📖 For the complete MARKDOWN documentation, see howto/MARKDOWN.md

ENCRYPTION

jotty·page uses industry standard PGP encryption.

📖 For the complete ENCRYPTION documentation, see howto/ENCRYPTION.md

API

jotty·page includes a REST API for programmatic access to your checklists and notes. This is perfect for:

  • Automation: Create tasks from external systems
  • Integrations: Connect with other tools and services
  • Scripts: Automate repetitive tasks
  • Dashboards: Build custom interfaces

📖 For the complete API documentation, see howto/API.md

SHORTCUTS

jotty·page supports a wide range of keyboard shortcuts to help you navigate and edit more efficiently without leaving the keyboard. They are divided into two main categories: global shortcuts that work anywhere in the app, and editor-specific shortcuts that work when you are writing a note.

📖 For the complete SHORTCUTS documentation, see howto/SHORTCUTS.md

Single Sign-On (SSO) with OIDC

jotty·page supports any OIDC provider (Authentik, Auth0, Keycloak, Okta, Google, EntraID, etc.)

📖 For the complete SSO documentation, see howto/SSO.md

Multi-Factor Authentication (MFA)

jotty·page supports MFA, this needs to be enabled in settings -> profile

📖 For the complete MFA documentation, see howto/MFA.md

Translations

jotty·page can be translated in multiple languages, all translations are community driven and can be found in the app/_translations directory.

📖 For the complete translations documentation, see howto/TRANSLATIONS.md

Custom Manifest

You can completely customize your PWA by creating an override manifest file. This allows you to change the app name, description, icons, colors, and more. Custom themes and emojis can be managed through the admin UI.

📖 For the complete customisation documentation, see howto/CUSTOMISATIONS.md 📖 For better understanding on how the PWA works see howto/PWA.md

Community shouts

I would like to thank the following members for raising issues and help test/debug them!


davehope

seigel

mariushosting

Isotop7

gavdgavd
IGOLz
IGOLz

floqui-nl
fruiz1972
fruiz1972

Sku1ly

ItsNoted
red-bw
red-bw

kn0rr0x

mroovers

Ryderjj89

spaghetti-coder

hurleyy

schneider-de-com

zolakt

Justus0405

mgrimace

bluegumcity

4rft5

godsking121

pbuzdygan

rcallison

BaccanoMob

DaxtonD

wein-geist

Star History

Star History Chart

Media gallery

1 / 2

Install Jotty on Unraid in a few clicks.

Find Jotty in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for Jotty Review the template variables and paths Click Install

Requirements

Don't forget to click **Show more settings...** for all **Variables**!

Download Statistics

18,453
Total Downloads
3,784
This Month
3,784
Avg / Month

Total Downloads Over Time

Loading chart...

Related apps

Details

Repository
ghcr.io/fccview/jotty:latest
Last Updated2026-06-16
First Seen2026-02-05

Runtime arguments

Web UI
http://[IP]:[PORT:3000]
Network
bridge
Privileged
false

Template configuration

PORTPorttcp

You can change 1122 to any available port on your host system.

Target
3000
Default
1122
Value
1122
Appdata: dataPathrw
Target
/app/data
Value
/mnt/user/appdata/jotty/data
Appdata: configPathrw
Target
/app/config
Value
/mnt/user/appdata/jotty/config
Appdata: cachePathrw
Target
/app/.next/cache
Value
/mnt/user/appdata/jotty/cache
NODE_ENVVariable

Sets the Node.js environment to production mode for optimal performance and security.

Default
production
Value
production
PUIDVariable

Process User ID that the container will run as.

Default
99
Value
99
PGIDVariable

Process Group ID that the container will run as.

Default
100
Value
100
UMASKVariable

Sets the default file creation mask.

Default
002
Value
002
HTTPSVariable

Enables HTTPS mode for secure connections.

Default
false|true
Value
false
App URLVariable

Base URL of your jotty·page instance. Required for secure session (https) and SSO. Include the https://

Target
APP_URL
Serve Public ImagesVariable

Allows public access to uploaded images via direct URLs.

Target
SERVE_PUBLIC_IMAGES
Default
yes|no
Value
yes
Serve Public VideosVariable

Allows public access to uploaded files via direct URLs.

Target
SERVE_PUBLIC_VIDEOS
Default
yes|no
Value
yes
Serve Public FilesVariable

Allows public access to uploaded files via direct URLs.

Target
SERVE_PUBLIC_FILES
Default
yes|no
Value
yes
Stop Check UpdatesVariable

If set to yes stops the github api call and won't give you a toast when a new update is available.

Target
STOP_CHECK_UPDATES
Default
no|yes
Value
no
Disable Bruteforce ProtectionVariable

Optional. Disables brute force protection for local login authentication. By default, accounts are temporarily locked after 3 failed login attempts with exponential delays (10s, 30s, 60s, etc.). Set to true to completely disable this security feature.

Target
DISABLE_BRUTEFORCE_PROTECTION
Default
false|true
Value
false
Default LocaleVariable

Optional. Sets the default language for the application (e.g., on the login page) when no user is logged in or a user hasn't set a preference.

Target
DEFAULT_LOCALE
Default
en
Value
en
Enable PWA ZoomVariable

Optional. Enables zooming on the PWA for accessibility reasons.

Target
ENABLE_PWA_ZOOM
Default
no|yes
Value
no
Auth ModeVariable

Enables OIDC (OpenID Connect) single sign-on or LDAP/Active Directory authentication. Set to 'oidc' or 'ldap'. Supersedes SSO_MODE.

Target
AUTH_MODE
Default
|oidc|ldap
SSO Mode (legacy)Variable

Legacy fallback for AUTH_MODE. Kept for backward compatibility with existing setups — prefer AUTH_MODE for new installs. Leave empty if AUTH_MODE is set.

Target
SSO_MODE
Default
|oidc
OIDC IssuerVariable

URL of your OIDC provider (e.g., Authentik, Auth0, Keycloak).

Target
OIDC_ISSUER
OIDC Client IDVariable

Client ID from your OIDC provider configuration.

Target
OIDC_CLIENT_ID
OIDC Client SecretVariable

Optional. Client secret for confidential OIDC client authentication.

Target
OIDC_CLIENT_SECRET
OIDC Client ID FileVariable

Optional. Path to file containing the OIDC client ID. If set, takes priority over OIDC_CLIENT_ID. Useful for Docker Secrets.

Target
OIDC_CLIENT_ID_FILE
OIDC Client Secret FileVariable

Optional. Path to file containing the OIDC client secret. If set, takes priority over OIDC_CLIENT_SECRET. Useful for Docker Secrets.

Target
OIDC_CLIENT_SECRET_FILE
Local Auth FallbackVariable

Optional. Allows both SSO and local authentication methods.

Target
SSO_FALLBACK_LOCAL
Default
yes|no
Value
yes
OIDC Admin GroupsVariable

Optional. Comma-separated list of OIDC groups that should have admin privileges.

Target
OIDC_ADMIN_GROUPS
Default
admins
Value
admins
OIDC Admin RolesVariable

Optional. Comma-separated list of OIDC roles that should have admin privileges.

Target
OIDC_ADMIN_ROLES
Default
admin
Value
admin
OIDC User GroupsVariable

Optional. Comma-separated list of OIDC groups allowed to access the application. If set, only users in these groups (or admins) can log in.

Target
OIDC_USER_GROUPS
OIDC User RolesVariable

Optional. Comma-separated list of OIDC roles allowed to access the application. If set, only users with these roles (or admins) can log in.

Target
OIDC_USER_ROLES
OIDC Groups ScopeVariable

Scope to request for groups. Defaults to 'groups'. Set to empty string or 'no' to disable for providers like Entra ID that don't support the groups scope.

Target
OIDC_GROUPS_SCOPE
Default
groups
Value
groups
OIDC Logout URLVariable

Optional. Custom logout URL for global logout. Full URL to redirect to when logging out.

Target
OIDC_LOGOUT_URL
LDAP URLVariable

URL of your LDAP server (e.g., ldap://ldap.example.com:389). Use ldaps:// on port 636 for TLS. Required when AUTH_MODE=ldap.

Target
LDAP_URL
LDAP Bind DNVariable

Distinguished name of the service account used to search the directory (e.g., cn=service,dc=example,dc=com). Required when AUTH_MODE=ldap.

Target
LDAP_BIND_DN
LDAP Bind PasswordVariable

Password of the LDAP service account. Required when AUTH_MODE=ldap (unless LDAP_BIND_PASSWORD_FILE is set).

Target
LDAP_BIND_PASSWORD
LDAP Bind Password FileVariable

Optional. Path to a file containing the LDAP service account password. Takes priority over LDAP_BIND_PASSWORD. Useful for Docker Secrets.

Target
LDAP_BIND_PASSWORD_FILE
LDAP Base DNVariable

Base DN under which to search for users (e.g., ou=users,dc=example,dc=com). Required when AUTH_MODE=ldap.

Target
LDAP_BASE_DN
LDAP User AttributeVariable

Optional. The LDAP attribute matched against the submitted username. Defaults to 'uid'. Use 'sAMAccountName' for Active Directory.

Target
LDAP_USER_ATTRIBUTE
Default
uid
LDAP Admin GroupsVariable

Optional. Pipe-separated list of group DNs granted admin rights on first login (e.g., cn=admins,ou=groups,dc=example,dc=com). Use '|' as separator since DNs contain commas. Requires memberof overlay on the LDAP server.

Target
LDAP_ADMIN_GROUPS
LDAP User GroupsVariable

Optional. Pipe-separated list of group DNs allowed to log in. Only members of these groups (or admin groups) can authenticate. Requires memberof overlay on the LDAP server.

Target
LDAP_USER_GROUPS
Node Extra CA CertsVariable

Optional. Path (inside the container) to a CA certificate file. Use this for LDAPS with a self-signed certificate (e.g., /app/config/ldap-ca.crt).

Target
NODE_EXTRA_CA_CERTS
Internal API URLVariable

Use if getting 403 errors after SSO login: Set to http://localhost:3000

Target
INTERNAL_API_URL
DEBUGGERVariable