The Ultimate Guide to Self-Hosting Joplin with Nginx Reverse Proxy

Are you looking for a powerful, open-source note-taking solution that you can fully control by hosting yourself? Look no further than Joplin. With apps for every platform, end-to-end encryption, and a robust set of features, Joplin makes it easy to create, organize, and sync your notes across devices.

While you can use Joplin with cloud storage services like Dropbox or OneDrive, self-hosting Joplin Server gives you ultimate privacy and allows you to customize every aspect of your deployment. In this comprehensive guide, I‘ll walk you through the process of setting up Joplin Server with an Nginx reverse proxy and PostgreSQL database. Whether you‘re a tech enthusiast or just want to keep your data under your own control, by the end you‘ll have your own fully functional Joplin setup that you can access from anywhere. Let‘s dive in!

Why Self-Host Joplin?

There are many benefits to hosting your own Joplin Server instance:

  • Privacy – Your notes and data stay on your own infrastructure and are never shared with any third-parties. Everything is encrypted end-to-end.

  • Control – You have full administrative control over your Joplin setup, from user management to backup schedules. No need to worry about a cloud provider changing terms or shutting down.

  • Customization – Self-hosting allows you to tweak every part of Joplin to your liking, add plugins, modify the UI with custom CSS, and integrate with your other self-hosted apps.

  • Performance – By deploying Joplin on your own optimized server with fast connectivity, you can ensure your notes sync quickly and are always accessible.

Of course, self-hosting does require some technical skills and time to set up and maintain. But hopefully this guide will make the process more approachable. The satisfaction of having your own personal Joplin Server is well worth it!

Components Overview

Here‘s a quick overview of the key pieces we‘ll be deploying:

  • Joplin Server – This is the main sync backend for storing and synchronizing notes across your devices. It includes a web interface for administration.

  • PostgreSQL database – Joplin Server stores all the notes and related data in a Postgres database. This can be deployed in a Docker container or on a separate host.

  • Nginx web server – We‘ll configure Nginx as a reverse proxy in front of Joplin Server. It will handle SSL encryption and serve the web UI.

  • Docker/Podman – To simplify deployment, we‘ll use containers to package and run each component. I‘m using Podman in this guide but Docker works basically the same.

You‘ll also need a Linux server or VM to run everything on. I‘m using Fedora Linux here but any modern distribution will work, as long as it supports containers. Finally, you‘ll need a domain name and SSL certificate for secure access to the web UI.

With that overview out of the way, let‘s start deploying!

Deploying Joplin Server

Preparing Your Environment

First, make sure your Linux server is up-to-date and has Podman (or Docker) installed. Create a dedicated directory to store all the configuration files:

mkdir ~/joplin
mkdir -p ~/joplin/postgres/data  
mkdir -p ~/joplin/nginx/certs

Deploying the PostgreSQL Database

Next we‘ll deploy a PostgreSQL container to use as the Joplin database. Create a docker-compose.yml file in the ~/joplin directory with the following contents:

version: "3.3"
services:

  db:
    image: postgres:13
    volumes:
      - ${HOME}/joplin/postgres/data/:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=yourpassword
    restart: unless-stopped

Replace yourpassword with a strong password for the Postgres database user. Then use Podman to deploy the container:

cd ~/joplin 
podman-compose up -d

Deploying the Joplin Server

With the database running, we can deploy the actual Joplin Server. Extend the docker-compose.yml file with a Joplin Server service:

version: "3.3" 
services:

  db:
    ...

  joplin:
    image: joplin/server:latest
    depends_on:
      - db
    ports:
      - "22300:22300"
    volumes:
      - ${HOME}/joplin/joplin-data:/joplin-data  
    environment:
      - APP_PORT=22300
      - APP_BASE_URL=https://joplin.yourdomain.com
      - DB_CLIENT=pg
      - POSTGRES_PASSWORD=yourpassword
      - POSTGRES_DATABASE=joplin
      - POSTGRES_USER=joplin
      - POSTGRES_PORT=5432
      - POSTGRES_HOST=db
    restart: unless-stopped

This deploys the latest version of Joplin Server from Docker Hub. A few key things to note:

  • We map port 22300 which is used for the Joplin sync protocol. Later we‘ll configure Nginx to proxy this port externally.

  • The APP_BASE_URL should be set to the domain you‘ll access the web UI from.

  • POSTGRES_HOST is set to db which resolves to our Postgres container thanks to Docker networking.

  • POSTGRES_PASSWORD needs to match what you set in the Postgres config.

Again run podman-compose up -d to deploy Joplin Server. You can check the logs with podman-compose logs -f to make sure it started up successfully and connected to the database.

Configuring the Nginx Reverse Proxy

The final piece is the Nginx web server which will act as our reverse proxy. Create a nginx.conf file in ~/joplin/nginx to hold the config:


http {
  server {
    listen 80;
    server_name joplin.yourdomain.com;
    return 301 https://$server_name$request_uri;
  }

  server {
    listen 443 ssl;
    server_name joplin.yourdomain.com;

    ssl_certificate /etc/nginx/certs/fullchain.pem;
    ssl_certificate_key /etc/nginx/certs/privkey.pem;

    location / {
      proxy_pass http://joplin:22300;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
    }
  }
}

events {
  worker_connections 1024;
}

This config listens on standard HTTP ports 80 and 443. Port 80 just redirects to HTTPS for security. The SSL certificate and private key are loaded from /etc/nginx/certs in the container – we‘ll add these in a minute.

The location / block is what proxies traffic through to the Joplin Server container. We set some important headers like X-Real-IP so Joplin Server knows the true client IP address.

To add the SSL certificate, first get a certificate from Let‘s Encrypt or another reputable provider. If this is just for testing, you can also create a self-signed certificate:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ~/joplin/nginx/certs/privkey.pem -out ~/joplin/nginx/certs/fullchain.pem

Finally, extend the docker-compose.yml file again to add the Nginx service:

version: "3.3"
services:

  db: 
    ...

  joplin:
    ...

  nginx:
    image: nginx:mainline
    depends_on:
      - joplin
    ports:
      - "80:80"  
      - "443:443"
    volumes:
      - ${HOME}/joplin/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ${HOME}/joplin/nginx/certs:/etc/nginx/certs
    restart: unless-stopped

We map ports 80 and 443 from the container to the host, so these need to be open in your firewall. The SSL certificate and Nginx config are bind-mounted into the container.

Run a final podman-compose up -d to bring up the Nginx proxy. At this point, you should be able to access the Joplin web UI at https://joplin.yourdomain.com and see the login screen.

If it doesn‘t load, review the container logs for any errors. Some common issues:

  • Joplin Server isn‘t able to connect to the Postgres DB. Double check the POSTGRES_ env vars and password.
  • Nginx is showing a bad gateway error. Make sure the proxy_pass URL matches the Joplin container name and port.
  • SSL error or warning. Ensure your SSL certificate is valid for your domain name and properly mounted into Nginx.

Connecting Joplin Apps

Now that Joplin Server is up and running, you can connect the various Joplin apps to sync your notes. The process is similar for the desktop, mobile, and CLI apps:

  1. Go to the Configuration screen and select Joplin Server as the Synchronization Target
  2. Enter https://joplin.yourdomain.com as the Server URL (using your real domain name)
  3. Enter your username and password to log into the server

The first sync may take a while if you have a lot of existing notes. But after that, syncing should be smooth and nearly instantaneous when you make changes on any device.

If you‘re migrating from another note-taking tool like Evernote or OneNote, Joplin makes the process fairly painless. It can import notes in a variety of formats, including Evernote‘s ENEX exports. Just go to File > Import in the desktop app and select the file to bring your old notes into Joplin.

Further Optimizations

With the core Joplin infrastructure in place, there are lots of ways you can optimize and extend your setup. Here are a few ideas:

Use a CDN for Better Performance

If you have users accessing Joplin from all over the world, consider putting a content delivery network (CDN) like Cloudflare in front of your Nginx server. This will cache content in data centers closer to your users and significantly reduce latency.

Optimize Postgres Database

By default, Postgres uses conservative settings that may not be ideal for Joplin‘s workload. Tweaking parameters like shared_buffers, effective_cache_size, and work_mem can improve performance. Use a tool like PGTune to generate an optimized config.

Enable Full-Text Search

Joplin has plugins for both Postgres and Elasticsearch that allow you to set up full-text search on your notes. This is handy when you have a large number of notes and want to quickly find something by content. The setup is a bit involved but instructions can be found on the Joplin Server GitHub page.

Keep Joplin Updated

The Joplin developers frequently release updates with bug fixes, performance improvements, and new features. Keep an eye out for new releases and update your setup as needed. The easiest way is to just edit the version tag in docker-compose.yml and re-deploy the containers.

Conclusion

Self-hosting Joplin is a great way to have full control over your notes and data. With a bit of work up front, you can deploy a setup that rivals anything else out there in terms of performance, security, and flexibility. Following this guide, you should have a solid foundation to build on and customize to your needs.

Joplin‘s vibrant community is also a great resource if you get stuck or want to explore further. The Joplin Forum is a friendly place to ask questions and share your experiences self-hosting. And if you want to really dive deep, check out the project on GitHub where you can report bugs, contribute code, and learn more about Joplin‘s internals.

I hope this guide has been helpful in your Joplin self-hosting journey. Enjoy your powerful new open source note-taking setup and all the benefits it provides. Happy writing!

Similar Posts