Setting up your own Joplin Server note taking solution on Docker with Portainer

Leduccc
5 min readJan 6, 2025

--

Joplin Desktop & Mobile

I’ve been immersing myself in the excellent book by Tiago Forte called Building a Second Brain, and as part of reading this book, the reader is encouraged to set up a note-taking solution. Being a developer and having access to a Docker host, I figured I would host it locally on my home server.

As part of this short tutorial, we will set up a Joplin Synchronization Server with PostgreSQL as its data store and email support.

1 — Prerequisites

- A linux server
- Docker
- Portainer
- A registered domain pointing to your home server
- A reverse proxy appliance (In this guide we will use nginx-proxy-manager)

2 — Create and configure the stack

Use the following docker-compose configuration as the stack configuration. You can paste it as is, and we will customize the configuration using Portainer environment variables.

If you already have a PostgreSQL database, you can omit the “db” service and map the database settings accordingly.

version: '3'

services:
db:
image: postgres:17
volumes:
- ${POSTGRES_DATA_PATH:-./postgres}:/var/lib/postgresql/data
ports:
- "${POSTGRES_HOST_PORT:-5432}:${POSTGRES_CONTAINER_PORT:-5432}"

restart: unless-stopped
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_DB=${POSTGRES_DATABASE:-joplin}
joplin-server:
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_DATABASE=${POSTGRES_DATABASE:-joplin}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_PORT=${POSTGRES_CONTAINER_PORT:-5432}
- POSTGRES_HOST=${POSTGRES_HOST_NAME:-db}
- MAILER_ENABLED=${MAILER_ENABLED:-0}
- MAILER_HOST=${MAILER_HOST}
- MAILER_PORT=${MAILER_PORT:-587}
- MAILER_SECURITY=starttls
- MAILER_AUTH_USER=${MAILER_AUTH_USER}
- MAILER_AUTH_PASSWORD=${MAILER_AUTH_PASSWORD}
- MAILER_NOREPLY_NAME=Joplin
- MAILER_NOREPLY_EMAIL=${MAILER_AUTH_USER}

Environment Variables:

  • POSTGRES_DATA_PATH: [Optional] The path on the host where the database data will be stored. The default location for Portainer stacks can be used, but this is where all of your notes and data will be backed up. You may want to specify a specific path on your host, such as on a backup disk. For example, on my server, I have an NVMe SSD mounted at /fast-data.
  • POSTGRES_USER: The administrator’s username for the PostgreSQL server. You must specify this.
  • POSTGRES_PASSWORD: The administrator’s password for the PostgreSQL server. You must specify this.
  • APP_BASE_URL: The full base URL that you will use for sharing features and server administration. Example: https://notes.example.com OR http://localhost:22300.
  • POSTGRES_HOST_PORT: [Optional] The PostgreSQL port on the host. Leave this empty if you don’t plan to run other PostgreSQL instances on your host, but it is good practice to change this. For example, I used 15432.
  • POSTGRES_CONTAINER_PORT: [Optional] The PostgreSQL port on the container. Leave this empty unless you already have a PostgreSQL server and are not configuring one as part of this stack.
  • POSTGRES_DATABASE: [Optional] The name of the database that the application will use. Leave this empty unless you already have a PostgreSQL server and are not configuring one as part of this stack.
  • POSTGRES_HOST_NAME: [Optional] The hostname of the PostgreSQL server. Leave this empty unless you already have a PostgreSQL server and are not configuring one as part of this stack.
  • MAILER_ENABLED: [Optional] Whether you want to enable sending emails. I recommend enabling this as it will make it easier to validate emails and allow you to reset your password. Example: 1.
  • MAILER_HOST: [Optional] Your email hosting provider, as shown in your provider’s configuration. For example: smtp.gmail.com.
  • MAILER_PORT: [Optional] Your email provider’s SMTP port. Example: 587.
  • MAILER_AUTH_USER: [Optional] Your email address or SMTP username as provided by your email provider.
  • MAILER_AUTH_PASSWORD: [Optional] Your SMTP password as provided by your email provider.
Example stack configuration in Portainer

3 — Configuring your reserve proxy

Log in to your Nginx Proxy Manager administration panel. Navigate to Proxies and click Add Proxy Host. Then fill in the form as shown below:

The filled form for adding the proxy host
  • Make sure that the domain matches your own.
  • Set the scheme to https and the correct port (22300). The scheme being set to https will allow the proxy to serve your upstream with a Let's Encrypt certificate sourced using your account.
  • For the Forward Hostname field, since Joplin is mapped to the host, you can select localhost.
  • Enable asset caching and common exploits blocking because why not.

Next, setup your LetsEncrypt SSL Certificate as shown bellow.

If you do not have a Let’s Encrypt account, you will need to create one and complete the security checks for your domain. Click Save and test your reverse proxy setup.

If there are any issues, such as a 502 error, consult the logs via SSH by navigating to your volume directory. You can find that volume directory in Portainer by going to Containers -> nginx-proxy-manager -> Volumes.

Volume mappings examples

3.1 — Testing your Joplin setup

Navigate to your domain and IP address and confirm that Joplin is not showing any errors in the Portainer logs. Joplin should display a login page if it is configured correctly.

4 — Configuring your server

Navigate to your domain and path as configured in Step 3. A login page should be visible, as shown below:

Joplin’s default login page

By default, Joplin Server will be set up with an admin user using the email admin@localhost and password admin.

Change your password and confirm your email. You are now ready to configure synchronization for all your devices!

5 — Sources

https://discourse.joplinapp.org/t/jopling-server-2-7-4-email-configuration/25326

--

--

Leduccc
Leduccc

Written by Leduccc

I'm writing simple and accessible tutorials for all the aspiring computer scientists out there!

No responses yet