Skip to Content

Setting Up Joplin on FreeBSD 13.1

Motivation

I recently decided to try FreeBSD as my daily driver laptop OS. Most apps that I want to use are available out of the box (I’m loving it so far) but Joplin is a notable exception.

My background reading didn’t yield great documentation on how to install it, so I thought I’d document my experience for anyone else who might want to try it.

I like Joplin because it works pretty well as a note taking app across all my devices, it’s open source, and I can sync across my devices using my own server (in my case, I use a personal AWS S3 bucket). It supports markdown, which is also nice because it’s muscle memory from writing README files and Rmd scripts.

I also wanted to use this as a learning experience for using jails, which are analogous to containers in the linux world. So I’ve gone ahead and installed Joplin in a jail, whic is a nice way of containing all that npm madness.

Something to note is that there is the Joplin UI, and there’s the Joplin terminal app. The Joplin UI is an electron app, so that adds a whole layer of complexity to the install that I didn’t want to get into. So I’ve just installted the Joplin terminal app.

Prior Art

I used these posts to help me install Joplin on my FreeBSD laptop:

https://wiki.freebsd.org/JailingGUIApplications

https://bastillebsd.org/getting-started/

https://joplinapp.org/terminal/

https://genneko.github.io/playing-with-bsd/application/joplin-on-freebsd/

Nitty Gritty

The hardest part about this was getting around little details left out fo documentation. In general I’ve found the culture of documentation to be way more rigorous in the FreeBSD community than the *nix community. That said, there are way less stackoverflow posts detailing ‘my unique edge case’ for FreeBSD so it sort of balances out.

I use bash, because I’ve built up a familiarity with it from Linux. Unless otherwise stated, we run stuff as root.

Step 1: Create a jail for Joplin

I initally tried to create a jail from first principles. This isn’t too hard, but why not use the convenience wrappers available to us? I found bastille to be really slick and well documented, so I’m using that.

To set up bastille, head over to the project docs and follow the steps. There was one gotcha for me when I installed it. When you create the loopback interface bastille0, it doesn’t show up in ifconfig until you reboot. I wasted about an hour trying to figure out why it wasn’t happening. Your jails won’t work if you don’t set up the loopback inteface properly.

Once bastille works, you can go ahead and create jail called joplin.

bastille create joplin 13.1-RELEASE 10.25.25.1

This should return something like this:

[joplin]:
bastille create joplin 13.1-RELEASE 10.25.25.1joplin: create

Now we can create a console in the joplin jail and set it up as if it was a completely fresh OS install.

bastille console joplin

Step 2: Install Joplin

First, bootstrap the freeBSD package manager, then install Joplin’s dependencies. These aren’t documented in the official docs, and libsecret wasn’t documented in the linked blog post above so it’s probably going to be the place you experience ht emost pain.

pkg bootstrap
pkg install node pkgconf vips
pkg install npm
pkg install python
pkg install libsecret
npm install -g node-gyp

Next install joplin. You need to do this in a bash shell, the default sh shell doesn’t export variables in the same way. If your install errors out, read the logs and try figure out why - it’s probably a missing dependency.

bash
NPM_CONFIG_PREFIX=~/.joplin-bin npm install -g joplin

Let the npm madness unfurl itself…

Ok. If your install succeeded, symlink the binary into the (jail) system path.

ln -s ~/.joplin-bin/bin/joplin /usr/local/bin/joplin

And then try launch joplin from the jail console.

joplin

Success! (Hopefully). Ok, now exit joplin. And then exit bash in the jail, and then exit the jail

:exit
exit
exit

Ok, make sure you’ve exited the jail console and that you are root on your system. Then try run the joplin app through bastille.

bastille cmd joplin joplin

This should launch just the same as before.

Step 3: Letting a non-root user use Joplin

Ok, you don’t want to use root to use Joplin all the time. So let’s allow our user (mine is riaz) execute the launch command. You’ll need sudo installed for this.

echo "riaz ALL=(root) /usr/local/bin/bastille cmd joplin joplin" > /usr/local/etc/sudoers.d/riaz

Now, after logging out and back in again, your user can execute:

sudo bastille cmd joplin joplin

Ok, cool, but still a bit too complex. I use bash, so this command might be different if you use a different shell, but in bash you can add an alias in your .bashrc file in your home directory.

alias joplin="sudo bastille cmd joplin joplin"

Remember, this allows the user to run the jail, along sith associated data. If you give multiple users the ability to execute this command, they would all be able to access the same joplin data. If you run a multi-user system and want to give everyone their own joplin, you’d need to create a separate jail for each of them. That’s not my use case, so I’m not doing it.

Step 4: Uninstalling Joplin

If you want to remove Joplin, with all associated data, bastille makes that super simple.

bastille stop joplin
bastille destroy joplin

Bonus: AWS s3 sync

You can find the full documentation for the Joplin terminal app here https://joplinapp.org/terminal/ .

One way to synchronize your various Joplin apps is via s3. The terminal app allows us to configure sync using the :config sync.[] parameters. The relevant parameters are:

    sync.target                    8 [this is the selector for s3 sync]

    sync.8.path                    AWS S3 bucket.
                                   Attention: If you change this location,
                                   make sure you copy all your content to it
                                   before syncing, otherwise all files will be
                                   removed! See the FAQ for more details:
                                   https://joplinapp.org/faq/
                                   Type: string.

    sync.8.url                     AWS S3 URL.
                                   Type: string.
                                   Default: "https://s3.amazonaws.com/"

    sync.8.region                  AWS region.
                                   Type: string.

    sync.8.username                AWS access key.
                                   Type: string.

    sync.8.password                AWS secret key.
                                   Type: string.

    sync.8.forcePathStyle          Force path style.
                                   Type: bool.
                                   Default: false