Post

How To Setup Taskwarrior Server In 2025

Learn how to sync your tasks the right way!

How To Setup Taskwarrior Server In 2025

How To Setup Taskwarrior Server In 2025

Introduction

This is a guide on how to setup a Taskwarrior server for the 2.x.x and 3.x.x versions.

The main differences between the 2.x.x era and the new current 3.x.x versions of taskwarrior is mainly the format where these two are presented and their syncing methods.

  • Taskwarrior V2
    • Uses JSON as its data files, split in four main files: pending.data, completed.data, backlog.data and undo.data
    • Uses taskd for syncing files across devices
  • Taskwarrior V3
    • Uses SQLite as its data file called: taskchampion-sqlite.db
    • Uses cloud services (e.g. Google Cloud and AWS S3) or taskchampion for syncing

In short, the 3.x.x series have a completed revamp on how syncing works and the way data is stored to improve performance at the very, very long term. I’ll be skipping the JSON and SQLite details, but it’s useful to know that SQLite is highly more efficient in dealing with high amounts of data (that happens in the long term).

Since the major taskwarrior upgrade, I found out that many projects associated to taskwarrior are no longer maintained and were created for the 2.x.x versions of it. For new users, taskwarrior 3.x.x is the best good to go, but for the users that were already using 2.x.x versions may have created a workflow around some tools like taskwarrior-flutter and WingTask that allowed taskwarrior to expanded to mobile devices seamlessly without sacrificing any bit of security.

If you never wondered about augmenting your taskwarrior setup, you may want to give at look at Taskwarrior Tools. It’s a very big lists of all available taskwarrior related projects that can do all kinds of stuff.

For this guide, I will be focusing in two amazing tools for running a server:

I’ll not be talking about how to setup Google Cloud or AWS S3 for Takswarrior V3 in this post

Taskwarrior V2

This will be a bare, simple, straight-forward, poor and dry redo of the already existing guide on how to setup a taskserver: Available at: taskserver-setup.

If you get questions on the setup, I do recommend you check the official guide, since it does give better explanations.

Taskserver is only compatible with Taskwarrior 2.x, and is no longer actively developed.

Dependencies

1
2
3
4
5
GnuTLS (ideally version 3.2 or newer)
libuuid
cmake 2.8 or newer
make
gcc 4.7 or clang 3.0 or newer

Setup

Installation

Download the official Github repository

1
2
3
4
git clone --recurse-submodules=yes \
      https://github.com/GothenburgBitFactory/taskserver.git \
      taskserver.git
cd taskserver.git

Change branch to master to get stable version

1
git checkout master

Init submodules

1
git submodule init

Build your taskserver

1
2
3
cmake -DCMAKE_BUILD_TYPE=release .
make
sudo make install

Verify your installation

1
taskd -v

Config

Taskserver data relies on an environment variable: $TASKDDATA (Has two ‘D’s). To set this up, add the following line to your .shellrc or .env and source it.

1
export TASKDDATA=/var/taskd

In the Github repository you just cloned, there will be a directory called pki. Move it to $TASKDDATA.

1
mv pki $TASKDDATA

The following command will do at lot. It will move your location to $TASKDDATA/pki and setup the certificates by running one of many scripts, and copy them to the $TASKDDATA directory.

1
2
3
4
5
6
7
8
cd $TASKDDATA/pki
./generate
cp client.cert.pem $TASKDDATA
cp client.key.pem $TASKDDATA
cp server.cert.pem $TASKDDATA
cp server.key.pem $TASKDDATA
cp server.crl.pem $TASKDDATA
cp ca.cert.pem $TASKDDATA

Now you will have to tell taskserver to read these certificates, by running:

1
2
3
4
5
6
taskd config --force client.cert $TASKDDATA/client.cert.pem
taskd config --force client.key $TASKDDATA/client.key.pem
taskd config --force server.cert $TASKDDATA/server.cert.pem
taskd config --force server.key $TASKDDATA/server.key.pem
taskd config --force server.crl $TASKDDATA/server.crl.pem
taskd config --force ca.cert $TASKDDATA/ca.cert.pem

Next step is to setup some other configurations: Set a log and pid file, and set the address to listen to:

1
2
3
4
cd $TASKDDATA/..
taskd config --force log $PWD/taskd.log
taskd config --force pid.file $PWD/taskd.pid
taskd config --force server address:53589

Launching the server is already possible using the taskdctl start command, but the configuration is not done yet. To let systemd start this automatically for you, you may set a service. This step is optional:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Unit]
Description=Secure server providing multi-user, multi-client access to Taskwarrior data
Requires=network.target
After=network.target
Documentation=http://taskwarrior.org/docs/#taskd

[Service]
ExecStart=/usr/local/bin/taskd server --data $TASKDDATA
Type=simple
User=$TASKDUSER
Group=$TASKDGROUP
WorkingDirectory=$TASKDDATA
PrivateTmp=true
InaccessibleDirectories=/home /root /boot /opt /mnt /media
ReadOnlyDirectories=/etc /usr

[Install]
WantedBy=multi-user.target

After creating this file (e.g. taskd.service), you may start it as follows:

1
2
3
4
cp taskd.service /etc/systemd/system
systemctl daemon-reload
systemctl start taskd.service
systemctl status taskd.service

If you do not get any error, you may now enable the service running systemctl enable taskd.service.

Now, the final part of the configuration comes. We will need to configure an organization and user and set their certificates as well. The following lines can be adjusted to your preferences.

1
2
taskd add org 'Public' # Creates the Public organization
taskd add user 'Public' 'Username' # Creates an user to an organization

Now to setup the user certificates you will have to go back to pki directory and run the generate.client script.

The generate.client requires some of the certificates you generated on the server setup to work. In case you moved it from there, make a copy to the pki directory

1
2
3
4
5
cd ~/$TASKDDATA$/pki
./generate.client Username
cp username.cert.pem ~/.task
cp username.key.pem ~/.task
cp ca.cert.pem ~/.task

And finally, we have to tell taskwarrior to read these files and know where the server is located at.

  • You may switch host.domain to address, where it can be a public or local IP Address
    • If you want to run the server locally, and not inside a VM or Cloud Services, you may set a static IP Address so you configuration won’t break
  • Change the credentials to the one generate.client created for you. If you forgot, it’s the user directory at $TASKDDATA/org/user/
1
2
3
4
5
task config taskd.certificate -- ~/.task/first_last.cert.pem
task config taskd.key -- ~/.task/first_last.key.pem
task config taskd.ca -- ~/.task/ca.cert.pem
task config taskd.server -- host.domain:53589
task config taskd.credentials -- Public/Username/cf31f287-ee9e-43a8-843e-e8bbd5de4294

Usage

You must send all your tasks to the server running:

This is something you should only do once on only one device.

1
task sync init

The command you will be most using is task sync for everytime you want to sync your tasks with the server. Optionally, to spare the necessity to run this every single time, you may add a crontab to run this command every 10 minutes, exemplified as follows:

*/10 * * * * /usr/bin/task sync >/dev/null 2>&1

That’s it for Taskwarrior V2, enjoy you syncing across devices! Just remember to export the same configuration lines from your .taskrc to other devices so they will listen to the same place.

Taskwarrior V3

If you read the Taskwarrior V2 setup, fear not, the V3 series is much easier to setup. The official step-by-step is available at taskchampion-sync-server

Dependencies

1
rustup or cargo

Setup

Installation

Install rustup and set branch to stable

1
2
sudo pacman -S rustup # For Arch Linux Distros
rustup default stable

Clone the official Github repository and build taskchampion-sync-server to the release version

1
2
3
git clone https://github.com/GothenburgBitFactory/taskchampion-sync-server.git
cd taskchampion-sync-server
cargo build --release

The binary will be created at /target/release/taskchampion-sync-server, and you may move it to any directory configured in $PATH environment variable. If you do not have a $PATH setup, you may add the next line to your .shellrc or .env and source it. It will make your ~/local/bin/ to listen to binaries allowing easier execution by the command line.

1
export PATH="$HOME/.local/bin/:$PATH"

You can already run you server with the following command taskchampion-sync-server. But you may set some options to it. We will be using the -C and -d options.

To use -C or --allow-client-id, you may create an UUID running the uuidgen command (mostly available at Linux systems). To use -d or --data-dir, you have to point the path to where taskchampion should save the files. If your server is not pointing to the 8080 port, you must set this, if not it will not work. You may do it using -p=8080.

If you already use taskwarrior, do not point -d to the existing directory, because it will wipe all your data!

To set this up, follow the example:

1
taskchampion-sync-server -C 6b00cabe-4e17-405f-878b-5b61a99cf326 -d /home/user/.taskchampion

Finally, you will have to tell taskwarrior where your server is, and how it should talk to it. So you must provide three configuration details to it.

  • Server URL: Must include the scheme, such as ‘http://’ or ‘https://’.
    • Example: http://localhost:8080 or http://192.168.1.43 (for a static IP address)
  • Client ID: Is the UUID you have generated previously using uuidgen
  • Encryption Secret: This can be any secret string, and must match for all replicas sharing tasks. You may generate it using pwgen
1
2
3
task config sync.server.url               <url>
task config sync.server.client_id         <client_id>
task config sync.encryption_secret        <encryption_secret>

And of course, to ease up the process to run the server, you may configure a service to systemd. You may find the following example useful. You may set the environment variables or replace the lines.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Unit]
Description=TaskChampion is the task database Taskwarrior uses to store and sync tasks
Requires=network.target
After=network.target
Documentation=https://github.com/GothenburgBitFactory/taskchampion-sync-server

[Service]
ExecStart=/usr/local/bin/taskchampion-sync-server -C $TASKCHAMPUUID -d $TASKCHAMPDATA
Type=simple
User=$TASKDUSER
Group=$TASKDGROUP
WorkingDirectory=$TASKCHAMPDATA
PrivateTmp=true
InaccessibleDirectories=/home /root /boot /opt /mnt /media
ReadOnlyDirectories=/etc /usr

[Install]
WantedBy=multi-user.target

Usage

You must send all your tasks to the server running:

This is something you should only do once on only one device.

1
task sync init

The command you will be most using is task sync for everytime you want to sync your tasks with the server. Optionally, to spare the necessity to run this every single time, you may add a crontab to run this command every 10 minutes, exemplified as follows:

1
*/10 * * * * /usr/bin/task sync >/dev/null 2>&1

That’s it for Taskwarrior V3, enjoy you syncing across devices! Just remember to export the same configuration lines from your .taskrc to other devices so they will listen to the same place.

Finals

No matter if you use Taskwarrior V2 and V3 you can now sync your data across different devices as you wish the official way!

Before I could ever knew about it, I used to use Syncthing for syncing my tasks, and they were always having merge conflicts, so I had to try something else. And running a taskwarrior server is definitively a better option.

Note that both Taskwarrior V2 and V3 can export your data in JSON format, which means you can import your data from V2 to V3 or vice-versa, but know that doing it the other way is not officially praised, however it works fine.

This post is licensed under CC BY 4.0 by the author.