Discover how to self-host Joplin Server using Docker Compose to maintain complete control over your notes, syncing, and data privacy.

This guide explores the Joplin project’s architecture, modules, and dependencies, providing a step-by-step overview of deploying a robust, scalable, secure, and open source flexible note-taking solution on your own infrastructure.

Project Overview: Joplin

Joplin is a powerful, open source note-taking and to-do application that supports Markdown formatting, end-to-end encryption, and synchronization across desktop, mobile, and web platforms.

  • With rich plugin support and a self-hostable server component, Joplin offers a flexible solution for users seeking full data ownership.

Why This Is Important

  • 🔒 Data privacy and security at your fingertips
  • 🌐 Cross-platform synchronization without third-party clouds
  • ⚙️ Highly customizable via plugins and themes
  • 🏠 True self-hosting for full control over infrastructure
  • 🚀 Scalable architecture for personal or team use
The Joplin Official Source Code

Tech Overview: Joplin

At its core, Joplin leverages a monorepo structure with TypeScript and JavaScript-driven modules.

It uses Electron for desktop apps, React Native for mobile clients, and Node.js/Express for the server.

  • Static analysis and testing are enforced via ESLint and Jest.
  • Configuration is managed through .env files and JSON schemas.
  • Configurable via docker container

Modules Descriptions

  • packages/server: Backend API for synchronization and storage, supporting SQLite and PostgreSQL, with optional filesystem or S3 storage drivers.
  • packages/app-desktop: Electron-based desktop client delivering a rich Markdown editor and E2EE sync.
  • packages/app-mobile: React Native applications for iOS and Android.
  • packages/app-cli: Command-line tooling for note import/export and automated tasks.
  • packages/plugins: Ecosystem for user-created extensions and themes.
  • packages/utils & lib: Shared utilities and core libraries used across modules.

Key Concepts and Algorithms

Joplin’s synchronization model implements a delta-based sync algorithm, minimizing data transfer by tracking changesets.

End-to-end encryption utilizes AES-256 and secure key derivation to protect content.

The server maintains versioned items, enabling conflict resolution and fallback storage drivers for seamless migrations.

Dependencies

  • Node.js & npm/yarn
  • Electron
  • React & React Native
  • SQLite3 & PostgreSQL
  • Express
  • Knex.js (SQL query builder)
  • Webpack & Babel
  • ESLint & Jest

Deployment Self-Hosting: Joplin

Selfhosting Joplin Server empowers you to run your own synchronization backend, ensuring no third-party holds your data.

The official Joplin Docker image simplify deployment and maintenance.

Deploying Joplin Server with Docker Compose

  1. Clone the repository and navigate to its root:
git clone https://github.com/laurent22/joplin.git
cd joplin
  1. Copy the environment sample .env-sample and configure variables:
cp .env-sample .env
# Edit .env to set POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DATABASE, APP_BASE_URL, etc.
  1. Launch services:
docker-compose -f docker-compose.server.yml up -d

Example docker-compose.server.yml to SelfHost Joplin:

We need two services:

  1. The Joplin Container
  2. An additional SQL DB (postgres)

Just use the following docker stack:

#version: '3.3'
services:
    app: #https://joplinapp.org/
        image: joplin/server:latest #https://github.com/laurent22/joplin
        depends_on:
            - db
        ports:
            - "3097:22300" #http://192.168.1.11:3097/login
        restart: unless-stopped     
        #env_file: .env   
        environment:
            - APP_PORT=22300
            - APP_BASE_URL= 192.168.1.11 #${APP_BASE_URL}  #  IP/URL
            - DB_CLIENT=pg
            - POSTGRES_PASSWORD=password
            - POSTGRES_DATABASE=joplin
            - POSTGRES_USER=user
            - POSTGRES_PORT=5432
            - POSTGRES_HOST=db    
    db:
        image: postgres:13
        volumes:
            - /home/Docker/joplin/data/postgres:/var/lib/postgresql/data
        ports:
            - "5432:5432"
        restart: unless-stopped
        environment:
            - POSTGRES_PASSWORD=password
            - POSTGRES_USER=user
            - POSTGRES_DB=joplin

Go to http://192.168.1.11:3097/login to enter Joplin UI:

Joplin Login Page

The out-of-the-box Joplin Server ships with a single admin account:

• Email: admin@localhost • Password: admin

After which you see:

Joplin UI

Service Breakdown:

  • db: PostgreSQL database for storing note metadata and content (default port 5432).
  • app: Joplin Server API, handling sync requests on port 22300.

Configuration: Modify .env entries to change database settings, base URL, storage driver, and fallback options.


Conclusion

We’ve explored how to deploy and customize Joplin, an open source self-hosted note-taking solution, using Docker Compose.

Whether you prioritize privacy, customization, or extensibility, Joplin delivers a robust platform.

Alternatives include Trilium Notes, Standard Notes, Wiki.js, and Nextcloud Notes for different self-hosting needs.

Latest Releases

  • server-v3.3.13: Improved performance for note syncing and database queries.
  • server-v3.3.12: Fixed storage migration and database fallback issues.
  • server-v3.3.11: Enhanced logging and error messages.
  • server-v3.3.10: Added support for AWS S3 storage integration.
  • server-v3.3.9: Security patches and updated dependencies.