Zotero + Webdav

Updated on

Zotero is an open source “reference manager”. For students, it’s an effective way to annotate and organize research papers. It also does automatic citation!

By default, Zotero offers 300MB of cloud storage for free. If you’re reading lots of papers and need to backup many pdfs, you’ll need to upgrade to a paid plan… unless you self-host!

In this guide, we’ll setup a webdav server to give us unlimited cloud storage we control. You’ll need:

  • A computer that’s always on (or a cloud vm)

Zotero Setup

Start by installing Zotero on your client device. The client device can also be the server! You can have any number of clients later. The AUR has zotero for archlinux, and brew has it for macos. It’s also available on the ios app store.

Register for a zotero account… we need to do this even if we’re self-hosting the cloud. Go to Edit -> Settings -> Sync -> File Syncing, and sign in there. We will revisit this page shortly.

Webdav

Webdav serves files over http. This is the underlying protocol zotero uses to synchronize your files. There are many options to self-host webdav, but I would recommend rclone. Rclone is a sort of cloud multi-tool, able to interact with almost every type of cloud storage. It can both serve and receive webdav requests!

I assume you’re using caddy as a reverse proxy. Caddy can use a third-party module to serve webdav directly, but rclone feels more closely suited to this task.

Switch into /etc/rclone. Generate a random password. Something like the following will work:

tr -dc A-Za-z0-9 </dev/urandom | head -c 40; echo

Next, touch /etc/rclone/htpasswords. Now you’ll use htpasswd to fill this file. Choose a username and paste the password you generated above into the propmpt.

htpasswd -B /etc/rclone/htpasswords <username>

I’d also recommend putting a plaintext copy of the password into /etc/rclone, as you’ll need it for every single device using your webdav cloud. You should also lock down permissions on both these files. Make them owned by root, and readable by root only.

Next up, we need our rclone script. Choose a directory to store your webdev cloud backup, for example /home/emiliko/mycloud/zotero. It must be a directory with a zotero directory inside it. The zotero directory must be empty. The rclone script will look something like this, and should be at /usr/local/bin/rclone_webdav.sh:

#!/usr/bin/env bash
declare -r serve='/home/emiliko/mycloud'
declare -r port='8080'
 
rclone serve webdav "$serve" --addr ":$port" --htpasswd /etc/rclone/htpasswords

Make sure the port you choose is accessible from the outside internet. You may need to open it up in your firewall and router. You’ll also need to point a domain at your server, which is assumed to be running caddy. For example, my Caddyfile could look like:

webdav.mydomain.com {
    reverse_proxy localhost:8080
}

Please see the “Reaching Yourself Over the Internet” guide for more details about caddy.

Lastly, we need to setup a systemd unit to start our webdav server on boot. For example the file /etc/systemd/system/rclone_webdav.service could contain:

[Unit]
Description=Rclone WebDAV Service for Zotero
After=network.target
 
[Service]
ExecStart=/usr/local/bin/rclone_webdav.sh
Restart=always
 
[Install]
WantedBy=multi-user.target

Run systemctl enable --now rclone_webdav.service and you should be able to visit it at its webpage now (eg webdav.mydomain.com). It should ask you for a username and password the first time, though the browser will cache these for subsequent logins.

Zotero Setup part 2

On each client, go to Edit -> Settings -> Sync -> File Syncing and set Sync attachments files in My Library to WebDAV. Fill in the username and password that you set when making htpasswd.

You should now be synchronizing using webdav! Make sure to update the File Syncing section on all of your devices!