Joplin is a wonderful, feature-rich note taking application available for a wide array of platforms. Like other note taking software, Joplin allows users to sync their notes. But where Joplin stands out from the crowd is the number of ways users can sync. These include:

  • Joplin Cloud
  • Dropbox
  • OneDrive
  • File system
  • Nextcloud
  • WebDAV
  • S3
  • Joplin Server

The purpose of this article is to show you how to setup your own Joplin Server instance. Why choose this one? You control the server meaning you control your data. It's fast and reliable. It allows note sharing. Here is this article shared using my own Joplin Server instance.

Hosting

You'll need to host this instance somewhere. You can get virtual private server (VPS) or setup a server at home. How to do this is beyond the scope of this article. I'm going to assume you have access to a server running Docker. In fact this entire article is fairly high level.

Setup

You need only two files .env and docker-compose.yml.

Your .env file should look something like this:

APP_BASE_URL=https://domain.tld/j
APP_PORT=22300
POSTGRES_DATABASE=joplin-server
POSTGRES_PASSWORD=PASSWORD
POSTGRES_PORT=5432
POSTGRES_USER=joplin-server

Whatever URL you wish to assign belongs in the APP_BASE_URL line. Create a super secret password. Easy.

Your docker-compose.yml file should look something like this:

# This is a sample docker-compose file that can be used to run Joplin Server
# along with a PostgreSQL server.
#
# Update the following fields in the stanza below:
#
# POSTGRES_USER
# POSTGRES_PASSWORD
# APP_BASE_URL
#
# APP_BASE_URL: This is the base public URL where the service will be running.
#   - If Joplin Server needs to be accessible over the internet, configure APP_BASE_URL as follows: https://example.com/joplin. 
#   - If Joplin Server does not need to be accessible over the internet, set the the APP_BASE_URL to your server's hostname. 
#     For Example: http://[hostname]:22300. The base URL can include the port.
# APP_PORT: The local port on which the Docker container will listen. 
#   - This would typically be mapped to port to 443 (TLS) with a reverse proxy.
#   - If Joplin Server does not need to be accessible over the internet, the port can be mapped to 22300.

version: '3'

services:
    db:
        image: postgres:15
        volumes:
            - ./data/postgres:/var/lib/postgresql/data
        ports:
            - "5434:5432"
        restart: unless-stopped
        environment:
            - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
            - POSTGRES_USER=${POSTGRES_USER}
            - POSTGRES_DB=${POSTGRES_DATABASE}
    app:
        image: joplin/server:latest
        depends_on:
            - db
        ports:
            - "22300:22300"
        restart: unless-stopped
        environment:
            - APP_PORT=22300
            - APP_BASE_URL=${APP_BASE_URL}
            - DB_CLIENT=pg
            - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
            - POSTGRES_DATABASE=${POSTGRES_DATABASE}
            - POSTGRES_USER=${POSTGRES_USER}
            - POSTGRES_PORT=${POSTGRES_PORT}
            - POSTGRES_HOST=db
            - MAILER_ENABLED=1
            - MAILER_HOST=smtp.gmail.com
            - MAILER_PORT=587
            - MAILER_SECURITY=1
            - MAILER_AUTH_USER=admin@domain.tld
            - MAILER_AUTH_PASSWORD=MAIL_PASSWORD
            - MAILER_NOREPLY_NAME=joplinserver
            - MAILER_NOREPLY_EMAIL=admin@domain.tld

The only setup here is your mail server. Yes, these variables could be, and probably should be, in the .env but this was the example I found and never changed it.

Reverse proxy

You'll need to setup a reverse proxy. I use Apache. This is an exerpt of mine. This entire example assumes I'm using https://domain.tld as my domain. Below shows how to setup a URL if https://domain.tld/j.

ProxyRequests Off
SSLProxyEngine On
ProxyPreserveHost On
ProxyPass /j http://192.168.0.xx:22300
ProxyPassReverse /j http://192.168.0.xx:22300