Kituwa IT · Self-hosting guides

Install Joplin Server with Docker Compose

Self-hosted Markdown notes with sync

notesmarkdownsync

Joplin Server is the sync backend for Joplin, an open-source note-taking app with Markdown, notebooks, tags, attachments, and a real mobile and desktop client. It's E2EE by default and works offline — the notes are on your disk first and the server is a convenience.

Category
Productivity
License
AGPL-3.0
Needs
Postgres
Image
joplin/server

What it is

Markdown notes with backlinks, tags, search across everything including attachments (if you set up the extraction service), and a sharing feature that publishes notes to read-only web pages. The desktop app is Electron and works with any filesystem folder.

Before you start

  • Nextcloud and Joplin Server are different projects with similar names. This guide is the standalone Joplin Server, not the Nextcloud Joplin app.
  • Newer tags dropped the WEB_PORT/API_PORT split in favour of SERVER_PORT. Check the release notes for the tag you pin.
  • The joplin/worker sidecar is needed for attachment text extraction. Skip it and search only covers note bodies.

1 — Create the directory

Command / configuration
mkdir -p ~/services/joplin/{data,pgdata}
cd ~/services/joplin
openssl rand -hex 32   # DB_PASSWORD and POSTGRES_PASSWORD

2 — Write the compose file

Command / configuration
services:
  db:
    image: postgres:16-alpine
    container_name: joplin-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: joplin
      POSTGRES_PASSWORD: CHANGE_ME
      POSTGRES_DB: joplin
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U joplin"]
      interval: 10s
      timeout: 5s
      retries: 5

  server:
    image: joplin/server:latest
    container_name: joplin-server
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "127.0.0.1:41184:41184"
    volumes:
      - ./data:/data
    environment:
      DB_CLIENT: pg
      DB_HOSTNAME: db
      DB_PORT: 5432
      DB_NAME: joplin
      DB_USER: joplin
      DB_PASSWORD: CHANGE_ME
      SERVER_PORT: 41184
      SERVER_PUBLIC_URL: https://notes.example.com
      CLIENT_ID: CHANGE_ME_client_id
      CLIENT_SECRET: CHANGE_ME_client_secret
      # required for the share/public-page feature
      SHARE_USER_SYSTEM: USE_SYSTEM_ACCOUNT
      SUPERPASS: CHANGE_ME
      TZ: UTC

  worker:
    image: joplin/worker:latest
    container_name: joplin-worker
    restart: unless-stopped
    user: "1000:1000"
    volumes:
      - ./worker-data:/data
    environment:
      DB_CLIENT: pg
      DB_HOSTNAME: db
      DB_PORT: 5432
      DB_NAME: joplin
      DB_USER: joplin
      DB_PASSWORD: CHANGE_ME
      WORKER_CONTENT_API: http://server:41184
      WORKER_CONTENT_TOKEN: CHANGE_ME
      WORKER_LOG_LEVEL: warn

3 — Start it

Command / configuration
docker compose up -d
docker compose logs -f server | grep -i "server started\|error"

4 — First-run setup

  1. Register the first account at https://notes.example.com — the first registered user becomes the admin.
  2. In the Joplin desktop app, go to Tools → Options → Sync target → Joplin Server and enter the URL, email and password. Add a second device and confirm the notes appear on both.
  3. Turn on E2EE encryption in the client with a strong passphrase. The server never sees note contents, and it means a compromise of the server reveals nothing useful.
  4. Test sharing: right-click a note → Share → publish. If the share page doesn't load, the SHARE_USER_SYSTEM setting is wrong.
  5. Confirm the worker is extracting text: create a note, attach a PDF, search for a word inside the PDF. If that fails, the worker token is mismatched.

5 — Maintenance

Command / configuration
docker exec -u postgres joplin-db pg_dump -U joplin joplin | gzip > joplin-$(date +%F).sql.gz
# attachments live in ./data, export in ./data/db.sqlite (older tags)

Help when you need it

Want help getting this running?

We can help with a supported Linux host, application setup, migration or troubleshooting. Contact us to confirm the software, scope and scheduling before ordering.

Related guides

← Browse all 30 guides · Back to top