Deploying Joplin Server on Docker (2024)

Some weeks ago I decided to move my notes from Microsoft OneNote to Joplin. Microsoft OneNote is a great tool for taking notes collaborative, but sometimes it drives me insane and I wanted a more portable form at for my notes.

Markdown is a perfect portable format, and it is widly adopted. I really like the idea behind Markdown, and I even supported a Microsoft User Voice to add native Markdown support into OneNote. So my new note taking tool had to support Markdown. Long story short: Joplin was my tool of choice. It’s running on Windows and there is also an iOS app. Joplin offers a wide range of options to sync the notes, but none of them seemed to fit my use case - Except for the Joplin Server. I’m not afaraid in running my own infrastructure. I have some Azure credits available each months, so running a small VM for a Joplin Server is a good way to use them.

VM of choice was a Azure Standard B2s (2 vcpus, 4 GiB memory), running Ubuntu 22.04 LTS. Make sure that you give your VM a public IP and setup a Network Security Group (NSG) to secure what kind of network traffic can reach your VM. I will not going into the details of deploying a Azure VM. Just reach out on Twitter or Mastodon if you have any questions.

Install Docker on Ubuntu 22.04 LTS

To install Docker on my Ubuntu VM, I followed this article on DigitalOcean closely.

You need some prerequisite package to install Docker.

sudo apt install apt-transport-https ca-certificates curl software-properties-common

Then add the GPG key for the official Docker repository.

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

No you can add the repository to the sources.list directory.

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Update the packages and then install Docker.

sudo apt install docker-ce docker-compose

Build Joplin Server

To deploy Joplin Server using Docker, it all starts with a YAML file. Create the necessary folders and copy the YAML file into it.

sudo mkdir /opt/joplin-server

Create the joplin-docker-compose.yml under /opt/joplin-server. Please change APP_BASE_URL and MAILER_HOST etc. to reflect your environment.

version: '3'services: db: image: postgres:13 volumes: - ./data/postgres:/var/lib/postgresql/data ports: - "5432:5432" restart: always environment: - POSTGRES_PASSWORD=randomString4711 - POSTGRES_USER=joplin-user - POSTGRES_DB=joplindb app: image: joplin/server:latest container_name: joplin-server depends_on: - db ports: - "8080:8080" restart: always environment: - APP_PORT=8080 - APP_BASE_URL=https://notes.blazilla.de/ - DB_CLIENT=pg - POSTGRES_PASSWORD=randomString4711 - POSTGRES_DATABASE=joplindb - POSTGRES_USER=joplin-user - POSTGRES_PORT=5432 - POSTGRES_HOST=db - MAILER_ENABLED=1 - MAILER_HOST=smtp.mailbox.org - MAILER_PORT=587 - MAILER_SECURITY=starttls - MAILER_AUTH_USER=user@domain.tld - MAILER_AUTH_PASSWORD=LalalaSecurePassword4711 - MAILER_NOREPLY_NAME=Joplin Server - MAILER_NOREPLY_EMAIL=joplin-admin@blazilla.de

Start the Joplin Server.

sudo docker-compose -f joplin-docker-compose.yml up -d

When everything went smooth, you should see the running container using sudo docker ps.

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES1dd0cdc5e8af joplin/server:latest "tini -- yarn start-…" 4 weeks ago Up 2 weeks 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp joplin-server1d0be5cf36cc postgres:13 "docker-entrypoint.s…" 4 weeks ago Up 2 weeks 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp joplin-server_db_1

Setting up the reverse proxy

The Joplin Server listens in 8080/tcp, which is a bit unhandy. To connect to the Joplin Server using 443/tcp, we need to setup a reverse proxy with NGINX. First step is to install NGINX.

sudo apt install nginx

Then we need to edit the /etc/nginx/sites-available/default. I’m using Let’s Encrypt for TLS certificates. Make sure that you get some using certbot and modify the ssl_certificate and ssl_certificate_key in the default config.

# Default server configuration#server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { try_files $uri $uri/ =404; }}server { root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name notes.blazilla.de; location / { proxy_pass http://127.0.0.1:8080$request_uri; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; if ($request_method ~* "(GET|POST)") { add_header "Access-Control-Allow-Origin" *; } if ($request_method = OPTIONS ) { add_header "Access-Control-Allow-Origin" *; add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD"; add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept"; return 200; } } listen [::]:443 ssl ipv6only=on; listen 443 ssl; ssl_certificate /etc/letsencrypt/live/notes.blazilla.de/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/notes.blazilla.de/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;}server { if ($host = notes.blazilla.de) { return 301 https://$host$request_uri; } listen 80 ; listen [::]:80 ; server_name notes.blazilla.de; return 404;}

Final test

When everything went well, you should be able to connect to the Joplin Server admin interface by using the APP_BASE_URL. Login with the default credentials (admin user with email admin@localhost and password admin). Make sure to change them! Then you can add new users and setup the sync from your Joplin Desktop or smartphone App.

Deploying Joplin Server on Docker (2024)
Top Articles
Latest Posts
Article information

Author: Jonah Leffler

Last Updated:

Views: 6504

Rating: 4.4 / 5 (45 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Jonah Leffler

Birthday: 1997-10-27

Address: 8987 Kieth Ports, Luettgenland, CT 54657-9808

Phone: +2611128251586

Job: Mining Supervisor

Hobby: Worldbuilding, Electronics, Amateur radio, Skiing, Cycling, Jogging, Taxidermy

Introduction: My name is Jonah Leffler, I am a determined, faithful, outstanding, inexpensive, cheerful, determined, smiling person who loves writing and wants to share my knowledge and understanding with you.