Ok so after writing up about todo list management with iCal, I realized that it was still bugging me that I gave up on Taskwarrior prematurely. Not that I'm super unhappy about my current setup, but some things were lacking with iCal tasks, mainly being able to group by topics or projects. Also Taskwarrior has heaps of other features that maybe I don't need, but it made me want to give it a go anyway.
Turns out that it is as powerful as they say, and I'll probably be sticking with it for a while! But my thoughts on that are for another post. So without further ado, here's a tutorial, both to help anyone else setting up taskwarrior with syncing and so I have something to follow if I need to set it up again in the future.
This is aiming to set up Taskwarrior on an Archlinux desktop and an Android device, and Taskserver on a headless Archlinux server. The network looks like:
[desktop] <--> [server] <--> [android]
Where the server is publically facing and is accessible by domain name(s).
The server is the most complex to set up, because it uses it's own sync protocol over top of TLS, and clients authenticate using public certificates.
Because this setup process involves several commands, in different directories, and as various users, commands displayed below will be displayed as in a bash shell, with an example username, machine name, and working directory.
Firstly, you will need to log in to your Archlinux server as a user with sudo privileges.
Now let's install
taskd. This step is more streamlined on Arch than what you will find on other tutorials; there is an aur package! Simply install using your preferred aur helper (or manually with
makepkg, I don't care). :P
taskd is in the official Arch repos now:
pacman -S taskd
[admin@server ~]$ pacaur -y taskd
This will install the taskserver, add a
taskd user, install a systemd service, and init a data directory under
Change to the
[admin@server ~]$ sudo -u taskd /bin/bash
Now this is the part that can get complicated... time to generate the server and client certificates.
[taskd@server /]$ cp -r /usr/share/doc/taskd/pki /var/lib/taskd [taskd@server /]$ cd /var/lib/taskd/pki
vars file for information about the certificates that will be generated.
[taskd@server pki]$ vi vars
The important one is the
CN value, which will default to something like
localhost. This must be changed to the domain through which you will be accessing the taskserver. Other information is up to you. You may want to increase the
EXPIRATION_DAYS to more than the default (1 year) for convenience though. The end result should look something like:
BITS=4096 EXPIRATION_DAYS=365 ORGANIZATION="WHATEVER" CN=your.domain.tld COUNTRY=AU STATE="WHATEVER" LOCALITY="WHATEVER"
Next, generate the certificates. This is automated by:
[taskd@server pki]$ ./generate
This will have generated the CA, server certificates, an a client key pair.
Now configure taskd to use the generated certs:
[taskd@server /]$ export TASKDDATA=/var/lib/taskd [taskd@server /]$ taskd config --force client.cert $TASKDDATA/pki/client.cert.pem [taskd@server /]$ taskd config --force client.key $TASKDDATA/pki/client.key.pem [taskd@server /]$ taskd config --force server.cert $TASKDDATA/pki/server.cert.pem [taskd@server /]$ taskd config --force server.key $TASKDDATA/pki/server.key.pem [taskd@server /]$ taskd config --force server.crl $TASKDDATA/pki/server.crl.pem [taskd@server /]$ taskd config --force ca.cert $TASKDDATA/pki/ca.cert.pem
Some final configuration. If you want persistant logging (the default for me was under
[taskd@server /]$ taskd config --force log $TASKDDATA/taskd.log
Make sure it's going to listen on the interfaces and ports required. In my case this was the usual taskserver port and all interfaces. The official docs has some notes about interface binding.
[taskd@server /]$ taskd config --force server '*:53589'
Log out from the
taskd user so we can do some admin tasks. First, allow incoming connections to this port:
[admin@server ~]$ sudo ufw allow 53589
Don't forget to forward the port if your server is behind a router with nat!
Finally we can start the server! Also don't forget to enable the systemd service so it autostarts on boot.
[admin@server ~]$ sudo systemctl start taskd [admin@server ~]$ sudo systemctl enable taskd
Log back in as the
taskd user so we can add users to the system. Taskserver can group users by organizations, and a user must be part of an organization. Name them as you please. My setup was something like:
[taskd@server /]$ export TASKDDATA=/var/lib/taskd [taskd@server /]$ taskd add org Public [taskd@server /]$ taskd add user 'Public' 'Samuel Walladge' New user key: 00000000-0000-dead-beef-000000000000 Created user 'Samuel Walladge' for organization 'Public'
Take special note of the new user key displayed when adding the user! You will need this, along with the org and user names, when setting up a client.
For each client, you will also need the CA certfication (
ca.cert.pem), and a client key pair. One was generated back when you generated the other certs (
client.key.pem), so you can use that for the first client. Then you can either reuse this keypair for all your clients, or generate a new pair for each client with:
[taskd@server pki]$ ./generate.client certname
certname.cert.pem in the directory.)
For now, we'll just work with the original generated ones and move on to setting up taskwarrior to sync with the server. Up to this point, you should have a working taskserver, but nothing to test it with.
Note on security: clients can only access the server with certificates generated this way. They can also only access your tasks if they know your org, username, and user key (uuid).
Taskwarrior on Linux
First install it:
[user@desktop ~]$ sudo pacman -S task
Done! Taskwarrior doesn't require anything fancy to get started. You can go ahead and start using it now if you like, but let's set up syncing next.
If you previously have been using task, it's probably a good idea to backup the task data directory before continuing (this is stored at
~/.task/ by default). If not, go ahead and add an example task to help with testing sync later:
[user@desktop ~]$ task add finish setting up taskwarrior
Now on to syncing! You will need the following things from setting up the taskserver:
- org name: Public
- username: Samuel Walladge
- user key: 00000000-0000-dead-beef-000000000000
Yes, this means you'll have to copy the cert files from the server to your client. Use whatever secure method suits. I think I managed to get the files on the server to a place where I could then pull them via
rsync, but YMMV1. ¯\_(ツ)_/¯
Once you have everything together, configure
task to use the correct credentials and info:
[user@desktop ~]$ task config taskd.certificate -- ~/.task/client.cert.pem [user@desktop ~]$ task config taskd.key -- ~/.task/client.key.pem [user@desktop ~]$ task config taskd.ca -- ~/.task/ca.cert.pem [user@desktop ~]$ task config taskd.server -- your.domain.tld:53589 [user@desktop ~]$ task config taskd.credentials -- Public/Samuel Walladge/00000000-0000-dead-beef-000000000000
Now we're ready to init syncing! Run the following command once for the first sync:
[user@desktop ~]$ task sync init
THIS STEP IS IMPORTANT: accidentally running
task sync instead of the initial
task sync init will do bad things. (I may have discovered this the hard way...) The
init part seems to set up some important initial data server-side, and if this isn't set up, you may get errors like
ERROR: Could not find common ancestor for ....
If you do forget to do this first, according to Taskwarrior's author, you should find the
tx.data file for your user among the taskserver data files and delete it. Then run run
task sync init from the client side again (once).
Note that this will reset the data saved on the server and force the client to mirror all tasks up to the server. You may lose data.
As a side note, it seems odd that it's possible for the client to make the server state unstable... something to look into.
sync init ran without errors, everything is now working! You can use the
task command to interact with Taskwarrior, and run
task sync any time you wish to sync with the server. It syncs quickly, and I have a crontab entry to auto sync every few minutes.
Taskwarrior on Android
Now let's set up on Android!
It's a bit rough around the edges, but quite functional. It wraps the
task binary, and configuration must be done via a text editor (the app comes with an editor with one click access to the config file).
Once the app is installed, run it and create an account name (this is local - doesn't matter what details you use) and let it create a new data directory.
Now you need the client key pair and CA cert as in setting up the desktop for syncing. Copy these to your device. Best place is
/sdcard/Android/data/kvj.taskw/files/00000-data-dir-name000 so the configuration file can then refer to them easily via relative paths, and they're easy to find again.
[user@desktop ~]$ adb push client.key.pem /sdcard/Android/data/kvj.taskw/files/00000-data-dir-name000/ [user@desktop ~]$ adb push client.cert.pem /sdcard/Android/data/kvj.taskw/files/00000-data-dir-name000/ [user@desktop ~]$ adb push ca.cert.pem /sdcard/Android/data/kvj.taskw/files/00000-data-dir-name000/
(This method may or may not need root access... can't remember. Either way, the files need to be on your device either in the Taskwarrior app data directory or on the main storage where apps can access or request access to.)
Now we can configure the app to sync similarly to desktop. Edit
/sdcard/Android/data/kvj.taskw/files/00000-data-dir-name000/.taskrc.android to add the credentials and cert paths. (Either with a cli editor over adb, in the app by tapping
Settings, or via another text editor.)
Minimal config for syncing should look something like:
taskd.certificate=client.cert.pem taskd.key=client.key.pem taskd.ca=ca.cert.pem taskd.server=your.domain.tld:53589 taskd.credentials=Public\/Samuel Walladge\/00000000-0000-dead-beef-000000000000
See the wiki on the app's Bitbucket for more configuration options specific to the app. Some tweaking may be necessary to get it to connect successfully to the taskserver sync server. On my LineageOS Nougat phone I needed to tweak the ciphers config to get it to connect:
That should be it!
Resources and parting notes
Here are some useful links I found that helped me in setting all this up.
- Page on the always brilliant Arch wiki: https://wiki.archlinux.org/index.php/Taskd
- Taskserver setup guide that seemed to be the most complete 'official' docs for this: https://github.com/GothenburgBitFactory/guides/blob/master/taskserver-setup/taskserver-setup.pdf
- Docs and notes on the official Taskwarrior website: https://taskwarrior.org/docs/#taskd
Shout out to the helpful people on
#taskwarrior on freenode for answering all my newbie questions!
It's probably a good idea to securely backup the server data directory - everything is in plain text files so I'm using restic to make periodic backups.
Have fun using one of the most powerful todo list managers I've ever seen!