Find a file
igor 512824693c
Some checks failed
Build and push Joplock image / build-and-push (push) Has been cancelled
enforce vault note encryption at Joplin Server proxy layer
- add app/proxy/vaultProxyGuard.js: inspects proxied note writes and
  deletes before forwarding to upstream Joplin Server
- covers single PUT /api/items/root:/<id>.md:/content, batch PUT
  /api/batch_items, single DELETE, and batch DELETE
- rejects with 403 when a vault note body lacks the encrypted marker,
  or when a vault note is deleted via the sync proxy
- bodies over 10 MB stream through without inspection (resource blobs)
- unauthenticated requests stream through (upstream handles 401)
- wire guard into createServer.js proxy entry point; replay buffered
  body via Readable.from() on allow
- 34 new unit tests, all 394 tests passing
2026-05-21 16:09:09 +12:00
.github/workflows Publish multi-arch Docker images 2026-05-07 14:30:50 +12:00
app enforce vault note encryption at Joplin Server proxy layer 2026-05-21 16:09:09 +12:00
cm-build fix mobile resume startup and editor targeting 2026-04-25 20:51:37 +12:00
hljs-build Add BASIC language syntax highlighting support 2026-05-18 12:17:14 +12:00
playwright-tests add vault-move playwright safety net for unified note I/O refactor 2026-05-20 13:01:44 +12:00
public polish backup actions and size display 2026-05-20 23:20:35 +12:00
scripts fix mobile resume startup and editor targeting 2026-04-25 20:51:37 +12:00
tests enforce vault note encryption at Joplin Server proxy layer 2026-05-21 16:09:09 +12:00
vendor/turndown-lib fix mobile resume startup and editor targeting 2026-04-25 20:51:37 +12:00
.dockerignore fix mobile resume startup and editor targeting 2026-04-25 20:51:37 +12:00
.gitignore Add vault/notebook encryption: client-side AES-256-GCM E2EE with SVG lock icons, mobile vault support, startup resume gate, and re-entry guard 2026-04-28 22:25:46 +12:00
AGENT_GUIDE.md Add BASIC language syntax highlighting support 2026-05-18 12:17:14 +12:00
docker-compose.example-full-build.yml update Docker and example stacks for Postgres 18 2026-05-20 22:39:59 +12:00
docker-compose.example-full.yml update Docker and example stacks for Postgres 18 2026-05-20 22:39:59 +12:00
docker-compose.yml update mobile login and iOS downloads 2026-05-19 14:13:24 +12:00
Dockerfile update Docker and example stacks for Postgres 18 2026-05-20 22:39:59 +12:00
package-lock.json Replace hand-rolled markdown renderer with markdown-it; fix blank-line round-trip and editor UX 2026-05-01 13:20:22 +12:00
package.json Replace hand-rolled markdown renderer with markdown-it; fix blank-line round-trip and editor UX 2026-05-01 13:20:22 +12:00
playwright.config.js fix mobile shell layout and add display mode setting 2026-04-30 09:13:46 +12:00
README.md Add recovery backups and fix theme/title edge cases 2026-05-18 19:34:06 +12:00
server.js rate-limit login 2026-05-19 12:57:19 +12:00

Joplock

A secure, fast web client for Joplin Server.

Joplock runs as a sidecar alongside an unmodified Joplin Server instance, sharing the same Postgres database, sessions, notes, folders, and resources. It gives you a lightweight browser-based interface to your Joplin notes without modifying Joplin Server itself. Keep using the other Joplin clients too, this won't interfere.

Key Features

  • Full Joplin compatibility -- desktop, mobile, CLI, and Joplock all work with the same account and data simultaneously
  • Low Resource usage -- minimal memory usage on the client, fast and responsive
  • Security-first design -- no private data stored on the client; sessions are cleaned up on logout; per-user settings and admin controls for user management
  • User creation from Joplock UI -- create and modify users directly from Joplock settings page
  • Full database backup and restore -- create and restore complete Postgres backups for both Joplin and Joplock data
  • Multi-factor authentication -- optional TOTP-based MFA on top of standard Joplin sessions
  • Fast search -- searches titles and note bodies directly in Postgres; optional live-as-you-type search
  • Near-instant autosave -- debounced saves with conflict detection, hash-based deduplication, and an undo ring buffer with full note history snapshots
  • PWA support -- installable as a home screen app on mobile and desktop with splash screens, offline indicator, and service worker shell
  • Server-side rendering -- SSR with htmx for minimal client-side JavaScript; CodeMirror editor for markdown, rich preview mode with WYSIWYG editing

Runtime Model

Joplock:

  • reads Joplin data directly from the shared Postgres database
  • validates the same sessionId cookie used by Joplin Server
  • writes notes, folders, and resources through stock Joplin Server APIs

That keeps desktop, mobile, CLI, and Joplock compatible with the same account and data.

Requirements

  • docker
  • an existng Joplin Server instance, or run the fullstack option

Environment

All configuration is done directly in the compose files via inline environment variables with comments. No .env file is needed -- just edit the values in docker-compose.yml or docker-compose.example-full.yml before starting.

Backup and recovery configuration:

  • JOPLOCK_BACKUP_DIR enables server-side full database backups
  • JOPLOCK_BACKUP_COMPRESSION controls the pg_dump compression method, for example zstd:19 or gzip:9
  • JOPLOCK_BACKUP_COMPRESSION_LEVEL=0-9 controls pg_dump compression for backup files
  • JOPLOCK_RECOVERY_ENABLED=true enables the break-glass recovery page at /recovery
  • JOPLOCK_RECOVERY_PASSWORD protects that recovery page

Important:

  • Backups are only durable if JOPLOCK_BACKUP_DIR is mounted to persistent storage.
  • Default backup compression is zstd:19, which is usually smaller than gzip:9.
  • JOPLOCK_BACKUP_COMPRESSION takes precedence over JOPLOCK_BACKUP_COMPRESSION_LEVEL.
  • Higher compression produces smaller backup files but may take longer to create.
  • Recovery mode is for backup and restore only, not regular note usage.
  • Restore replaces the entire shared Postgres database, including Joplock-owned tables.

Docker

Published container image:

  • ghcr.io/abort-retry-ignore/joplock:latest

Sidecar Install

Use this when you already have Joplin Server and Postgres running elsewhere. Edit the environment values in docker-compose.yml to point at your existing setup, or copy into your existing compose. Then:

docker compose up -d

This pulls the pre-built image from GitHub Container Registry. To build from source instead:

docker compose -f docker-compose-build.yml up -d --build

On Linux, the compose files map host.docker.internal to the host gateway so Joplock can reach host services by default.

Backup And Restore

Normal workflow:

  1. Sign in as the configured Joplock admin.
  2. Open Settings -> Admin -> Backup & Restore.
  3. Create a backup or restore an existing server-side backup.

Break-glass workflow when normal Joplin login is unavailable:

  1. Enable JOPLOCK_RECOVERY_ENABLED=true and set JOPLOCK_RECOVERY_PASSWORD.
  2. Open /recovery.
  3. Sign in with the recovery password.
  4. Create or restore full database backups from there.

Before restoring:

  1. Stop or quiesce Joplin Server if possible.
  2. Stop active sync clients.
  3. Expect the entire shared Postgres database to be replaced.

Full Example Stack

Use this as a reference/demo stack with Postgres, Joplin Server, and Joplock together. Edit the values in docker-compose.example-full.yml as needed, then:

docker compose -f docker-compose.example-full.yml up -d

The full example uses the public joplin/server:latest image. Joplock is exposed on http://localhost:5444 by default. Joplin Server is internal-only unless you add a port mapping.

The full example is meant as a working reference compose file. Adjust it for your real deployment.