Joplin Server 2.9 LXC Build
Joplin is my current note-taking app of choice because markdown notes are easy to read and I like the cross-platform support. Markdown is supported by many applications so there is no threat of being locked into a specific application.
In order to centrally store and share notes with other users in my home network, I reverse-engineered the docker build file and ran Joplin server in an Debian based LXC. I have included all of the steps to build your own.
- Start by ensuring the apt tree is up-to-date. Apache2 is needed for reverse proxy functionality, however nginx can be used in its place.
1 2 3 4 5 6 7 8
apt update apt upgrade apt install -y git vim curl postgresql make gcc g++ apache2 curl -fsSL https://deb.nodesource.com/setup_16.x | bash - apt update apt upgrade apt install nodejs npm install -g pm2
- Generate a self-signed https certificate, be sure to enter the IP address of the server as the Common Name. You can also use Lets Encrpyt if you so choose.
1
openssl req -x509 -nodes -days 10000 -newkey rsa:4096 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt
- Switch to the postgres user to create a database and user for Joplin to use. Generate a secure password to use here. One method of doing so is using
openssl
1 2 3
openssl rand -base64 32 su postgres psql
1 2 3 4
REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC; CREATE DATABASE joplin; CREATE USER joplin with password 'supers$cret'; GRANT ALL PRIVILEGES ON DATABASE joplin to joplin;
- As root, create joplin directory and joplin user
1 2 3 4 5
mkdir -p /opt/joplin/packages/{fork-sax,lib} useradd --create-home --shell /bin/bash joplin chown -R joplin:joplin /opt/joplin su -l joplin git clone https://github.com/laurent22/joplin.git
- Copy needed files from git repo into the joplin directory
1 2 3 4 5 6 7 8 9 10 11 12 13
cp joplin/packages/fork-sax/package*.json /opt/joplin/packages/fork-sax/ cp joplin/packages/lib/package*.json /opt/joplin/packages/lib/ cp joplin/lerna.json /opt/joplin/ cp joplin/tsconfig.json /opt/joplin/ cp joplin/package*.json /opt/joplin/ cp -r joplin/packages/fork-htmlparser2/ /opt/joplin/packages/ cp -r joplin/packages/turndown-plugin-gfm/ /opt/joplin/packages cp -r joplin/packages/turndown/ /opt/joplin/packages/ cp -r joplin/packages/renderer/ /opt/joplin/packages/ cp -r joplin/packages/server/ /opt/joplin/packages/ cp -r joplin/packages/tools/ /opt/joplin/packages/ cp -r joplin/packages/lib /opt/joplin/packages/ cp -r joplin/packages/htmlpack/ /opt/joplin/packages/
- Build the application using npm
1 2
cd /opt/joplin/ BUILD_SEQUENCIAL=1 yarn install --inline-builds
- Create autostart file for PM2 to use, updating the server IP. This will set the necessary environment variables for Joplin to use.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
$ cat /opt/joplin/packages/server/ecosystem.config.js module.exports = { apps : [ { name: "joplin-server", script: "/opt/joplin/packages/server/dist/app.js", watch: false, env: { "DB_CLIENT": "pg", "POSTGRES_DATABASE": "joplin", "POSTGRES_PASSWORD": "supers$cret", "POSTGRES_USER": "joplin", "APP_BASE_URL": "https://<server IP>/joplin", "NODE_ENV": "development" } } ] }
- Add the following line as a cron to joplin user to autostart server on boot
1
@reboot sh -c 'cd /opt/joplin/packages/server/ && pm2 start /opt/joplin/packages/server/ecosystem.config.js'
- Switch back to root user and enable proxy services in Apache
1 2 3
a2enmod proxy a2enmod proxy_http a2enmod ssl
- Create reverse proxy in Apache using the configuration below, updating the server IP.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
<IfModule mod_ssl.c> <VirtualHost *:443> ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined ProxyPreserveHost On ProxyPass "/joplin" http://localhost:22300 ProxyPassReverse "/joplin" http://localhost:22300 ServerName <serverIP/hostname> SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key SSLEngine on # Intermediate configuration, tweak to your needs SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 SSLHonorCipherOrder off SSLSessionTickets off SSLOptions +StrictRequire # Add vhost name to log entries: LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common </VirtualHost> </IfModule>
- Enable the site with a2ensite.
1
a2ensite 000-default-ssl
- Reboot the server to ensure services will auto-start on their own. Running the command
pm2 logs
as thejoplin
user can be used to diagnose any issues.
With the server running, connect to the UI in a web browser at https://<serverIP>
. The default user is admin@localhost
and the default password is admin. You should change this after logging in successfully. From here, create new users and then set the username, password, and server URL within the Joplin desktop application. If you do not have a signed certificate, check the box to Ignore TLS certificate errors under the Advanced Sync Settings.
Comments powered by Disqus.