Joplin is a popular open-source note-taking app loved by privacy-minded folks and productivity gurus. It’s easy to sync your notes across devices, but if you want to keep your data totally safe and in your hands, you can set up your own Joplin server.
Let’s walk through how to do this step by step. We’ll start by preparing your server and configuring it to suit your needs. Whether you want to boost security, save money, or make it unique to your needs, self-hosting Joplin is the way to go.
Is Joplin the perfect OneNote alternative? Here's what you need to know before you decide
This open-source OneNote alternative is blowing up
First step: installing Docker on your Raspberry Pi
We’ll start under the assumption you’ve already got your Raspberry Pi installed and running. I’m doing this on a Raspberry Pi 5 running Raspberry Pi OS (64-bit, release date October 22, 2024). First, you must update and upgrade your distribution with the latest packages.
- Open a Terminal session on your Raspberry Pi.
-
Update the apt package manager to be sure its database is current:
sudo apt update
-
Next, upgrade any packages that haven’t already been upgraded:
sudo apt upgrade -y
Next, you’ll need to install and configure Docker if you don’t already have it installed. Docker allows you to run apps and servers in sandboxed containers, so you don’t have to worry about different pieces of software conflicting with one another.
-
First, download and install the latest Docker packages:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
-
Make sure Docker is installed successfully by running this command, which will download a test image and run it in a container:
sudo docker run hello-world
When the container runs, it displays a confirmation message and then exits. -
Next, add your current user to the docker group to avoid having to use root privileges:
sudo user mod -aG docker $USER
- Finally, exit your Terminal session and open a new one to refresh your user permissions.
We’ll install docker-compose to finish and make it easier to create new Docker containers.
-
First, install the needed prerequisites for docker-compose.
sudo apt install -y libffi-dev libssl-dev python3-dev python3-pip
-
Now you can install docker-compose with this command:
sudo pip3 install docker-compose
-
If you get an error that the environment is externally managed, issue this command instead:
sudo apt install docker-compose-plugin
Install a web server and self-signed certificate
Once Docker is installed, you’re almost ready to install your Joplin server. First, we must ensure it has a web server and an SSL certificate to keep it secure.
You might also want to set up your domain name and dynamic DNS to allow remote access to the Joplin server. These steps are beyond the scope of this article since setting up dynamic DNS varies widely from one router to the next. However, without this, you can only sync your notes when you’re on the same network as the Joplin server.
Let’s move on to setting up the web server you’ll use for your Joplin server.
-
First, install the nginx web server:
sudo apt install -y nginx
-
To set up SSL, create your certificate authority (CA) private key. When asked for a passphrase, it’s a good idea to use one to prevent possible security breaches. Just use this command and follow the instructions as they appear:
sudo openssl genrsa -aes256 -out /etc/ssl/private/local_ca.key 4096
-
Next, you need to create a certificate. We’ll create a CA certificate valid for five years (1826 days) with the following command. When asked for a passphrase, use the one you created above in step 2.
sudo openssl req -x509 -new -nodes -key /etc/ssl/private/local_ca.key -sha256 -days 1826 -out /etc/ssl/certs/local_ca.crt
You’ll be asked to provide additional information, but you can skip any of the fields using the period (.).
After creating your CA and self-signed certificates, nginx will need its own certificate for the web server.
First, create a self-signed certificate for the nginx service:
sudo openssl req -new -nodes -out /etc/ssl/certs/nginx.csr -newkey rsa:4096 -keyout /etc/ssl/private/nginx.key -subj '/CN=Nginx Service'
The web server needs an extension file to configure certificate settings, such as hostname and IP address. Copy the following text into the Terminal, changing the values for DNS.1 and IP.1 to your Raspberry Pi’s hostname and IP address:
cat > nginx.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = [Type Raspberry's hostname here]
IP.1 = [Type Raspberry's IP address here]
EOF
Verify the contents are correct using:
cat nginx.ext
Finally, sign the certificate for nginx with this command:
sudo openssl x509 -req -in /etc/ssl/certs/nginx.csr -CA /etc/ssl/certs/local_ca.crt -CAkey /etc/ssl/private/local_ca.key -CAcreateserial -out /etc/ssl/certs/nginx.crt -days 3650 -sha256 -extfile nginx.ext
Okay, we’re almost ready to install the Joplin server. Before we do that, however, we need to create a new nginx configuration for the Joplin server. Create a new configuration file using nano in your Terminal session:
sudo nano /etc/nginx/sites-enabled/joplin
Copy and paste the following information, making sure to edit server_name to match your configuration:
server {
listen 443 ssl http2;
server_name raspberrypi.local;
ssl_certificate /etc/ssl/certs/nginx.crt;
ssl_certificate_key /etc/ssl/private/nginx.key;
location /joplin/ {
proxy_redirect off;
proxy_pass http://127.0.0.1:22300;
rewrite ^/joplin/(.*)$ /$1 break;
proxy_set_header X-Forwarded-Host $host;
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;
}
}
Save and exit using Ctrl+X, [Y], and Enter/Return.
Finally, restart nginx to apply the new server configuration:
sudo systemctl restart nginx.service
Setting up your self-hosted Joplin server
With the preliminaries out of the way, it’s time to install and configure the Joplin server. Docker will do most of the work for us, following recipes in the Docker repositories. To get the ball rolling, you’ll need to create a new docker-compose.yml file. In the Terminal, issue this command:
nano docker-compose.yml
Next, copy and paste the text below into the file, then save the file and exit nano.
version: '3'
services:
db:
restart: unless-stopped
image: postgres:13.1
ports:
- "5432:5432"
volumes:
- /data/joplin-data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=[Enter postgres password here]
- POSTGRES_USER=[Enter postgres username here]
- POSTGRES_DB=[Enter postgres db name here]
app:
environment:
- APP_BASE_URL=https://[raspberry hostname here]/joplin
- APP_PORT=22300
- POSTGRES_PASSWORD=[Enter postgres password here]
- POSTGRES_DATABASE=[Enter postgres db name here]
- POSTGRES_USER=[Enter postgres username here]
- POSTGRES_PORT=5432
- POSTGRES_HOST=db
- DB_CLIENT=pg
restart: unless-stopped
image: etechonomy/joplin-server:latest
ports:
- "127.0.0.1:22300:22300"
depends_on:
- db
Next, you’ll use the configuration file to download and install the required Docker images:
docker compose up -d
Finally, test the server is running by opening a new web browser window and navigating to:
https://[hostname].local/joplin
Replace hostname with the hostname you configured for the Raspberry Pi. You’ll likely get warnings about the certificate, but you can accept them by clicking Advanced -> Accept the Risk and Continue.
You should see the Joplin Server login page. The default username is admin@localhost, and the default password is admin. Be sure to change those immediately to maintain your security.
Connect your devices to the Joplin serverOnce the server config is complete, you can start synchronizing the Joplin app with your self-hosted server on your devices. You may need to import the security certificate you created to the devices you want to connect. Using email, SCP, or any other method, transfer a copy of the CA certificate found on your Raspberry Pi at /etc/ssl/certs/local_ca.crt to those devices.
Joplin Server is ready to go
That's about it. It's a lengthy process, but if you followed the instructions correctly, you should be good to go. Of course, your next step may be to make your Joplin server available online eventually. As previously mentioned, this will require registering your own domain name and using dynamic DNS to expose your Raspberry Pi Joplin server to the outside world, so be sure to fully secure your Pi before doing so.
-
Joplin
