A Personal Task Server
This article will explain how to set up and sync with your own task server.
Why Do I Need A Task Server?
You may want to sync tasks between several machines, or you might anticipate doing that. You may also want to have a backup copy of your tasks.
Why Do I Need A Personal Task Server?
Setting up your own Task Server means having complete control and privacy. There will be secure hosted server accounts soon, but for now you will need to set up your own server.
First Things First
This is new territory for Taskwarrior, which means using beta software, and that means we’re going to make a backup as step 1. Here is a very easy way to backup your data:
$ cd ~/.task $ tar czf task-backup-$(date +'%Y%m%d').tar.gz *
Now put that file somewhere for safe keeping, because beta software contains bugs. The truth is that all software contains bugs, so if you aren’t making a backup of all your data, then, well, why not?
Satisfy the Dependencies
Before building the software, you will need to satisfy the dependencies by installing the following:
- GnuTLS
- libuuid
- libreadline
- cmake
- make
- A C++ Compiler
Note that some OSes (Darwin, FreeBSD …) include libuuid functionality in libc.
Build the Code
The next step is to obtain the code and build it. This means getting the Taskwarrior 2.3.0 and Task Server 1.0.0 beta2 tarballs. Here are the steps, and notice that the code is built in the home directory. Naturally you can build the code anywhere you wish, but the later in this article we will be referring to this location. Adjust accordingly.
$ cd $ curl -O http://taskwarrior.org/download/taskd-1.0.0.beta2.tar.gz $ tar xzf taskd-1.0.0.beta2.tar.gz $ cd taskd-1.0.0.beta2 $ cmake . $ make $ sudo make install $ cd $ curl -O http://taskwarrior.org/download/task-2.3.0.beta2.tar.gz $ tar xzf task-2.3.0.beta2.tar.gz $ cd task-2.3.0.beta2 $ cmake . $ make $ sudo make install
Note that you may choose to run the server on one machine, and the client on another. Bear this in mind as you obtain and build the code.
Server Setup
On the server machine, a location for the data must be chosen and created. The TASKDDATA environment variable will be used to indicate that location, and is also used by the server itself. In fact, most server commands require either that the TASKDDATA variable is set, or the “–data …” option is fully specified. In this example, we are using ~/server_data.
$ export TASKDDATA=~/server_data $ mkdir -p $TASKDDATA
Everything the server does will be confined to that directory. Now we let the server initialize that directory:
$ taskd init You must specify the 'server' variable, for example: taskd config server localhost:53589 Created ~/server_data/config
Next we create an organization (‘Public’) and a user (‘Your Name’ is used here). Substitute your name in the following commands:
$ taskd add org Public Created organization 'Public' $ taskd add user 'Public' 'Your Name' New user key: cf31f287-ee9e-43a8-843e-e8bbd5de4294 Created user 'Your Name' for organization 'Public'
The organization is a grouping of users, and will become essential in later server releases.
Note that you will get a different ‘New user key’, than shown here, and you will need to retain that, to be used later. Note that the key is just a unique id, because your name alone is not necessarily unique.
Now we create certificates and keys. The command below will generate all the certs and keys for the server, but this includes self-signed certificates, and this is not recommended for production use. This is for personal use, and this may be acceptable for you, but if not, you will need to purchase a proper certificate and key, backed by a proper certificate authority.
$ cd ~/taskd-1.0.0.beta2/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 $ taskd config --force client.cert $ROOT/client.cert.pem $ taskd config --force client.key $ROOT/client.key.pem $ taskd config --force server.cert $ROOT/server.cert.pem $ taskd config --force server.key $ROOT/server.key.pem $ taskd config --force server.crl $ROOT/server.crl.pem $ taskd config --force ca.cert $ROOT/ca.cert.pem
Now we configure some basic details for the server. The chosen port is 53589. Note that we allow Taskwarrior clients specifically.
$ cd $TASKDDATA/.. $ taskd config --force log $PWD/taskd.log $ taskd config --force pid.file $PWD/taskd.pid $ taskd config --force server localhost:53589 $ taskd config --force client.allow '^task [2-9]'
You can look at all the configuration settings:
$ taskd config
It is time now to launch the server:
$ taskdctl start
This command launched the server as a daemon process. Note that you use ‘taskdctl stop’ to terminate the server. This command requires the TASKDDATA variable. Your server is now running, and ready for syncing.
Client Setup
On your client machine it is assumed that you are already using Taskwarrior, and already have local tasks to sync. If this is not the case, setup and add one. We need to create a cert and key for you, based on the server cert:
$ cd ~/taskd-1.0.0.beta2/pki $ ./generate.client your_name ...
Copy the cert, key and ca to your ~/.task directory. The reason we are copying the CA cert is because this is a self-signed cert, and we need the CA to validate against. Alternately we could force Taskwarrior to trust all certs, but that is not recommended.
$ cp your_name.cert.pem ~/.task $ cp your_name.key.pem ~/.task $ cp ca.cert.pem ~/.task
Now we need to configure Taskwarrior to be aware of these certs:
$ task config taskd.certificate ~/.task/your_name.cert.pem $ task config taskd.key ~/.task/your_name.key.pem $ task config taskd.ca ~/.task/ca.cert.pem
Now set the server info and provide the credentials, which include the ID key generated when the user was added to the server:
$ task config taskd.server localhost:53589 $ task config taskd.credentials 'Public/Your Name/cf31f287-ee9e-43a8-843e-e8bbd5de4294'
Now your client is ready to sync.
First Time Sync
The first time you sync is special – the client sends all your pending tasks to the server. This is something you should only do once. Run this:
$ task sync init Please confirm that you wish to upload all your pending tasks to the Task Server (yes/no) yes Syncing with localhost:53589 Sync successful. 2 changes uploaded.
You should get an indication that tasks were uploaded, in this case 2 of them.
General Sync
After the first time sync, you switch and just use this command:
$ task sync Syncing with localhost:53589 Sync successful. No changes.
This will give you feedback about what happened. Please note that it is perfectly safe to run this command as often as you wish. Syncing is safe and does not consume great system resources.
But it does require network connectivity, and if there is no connectivity you will be notified. It is not a problem if a sync fails because of this, because the next sync that works will catch up with all the changes, and do the right merging.
The general usage pattern is that after you modify data locally, Taskwarrior will start notifying you that you need to sync, after commands, like this:
$ task project:foo list No matches. There are local changes. Sync required.
This is just a reminder to sync. Respond with a sync, and the reminder goes away:
$ task sync Syncing with <server>:<port> Sync successful. 1 changes uploaded.
Please remember this is beta software, and if you find bugs or have unanswered questions, please contact us at support@taskwarrior.org.
For the latest version of this document, with corrections and added info see: http://taskwarrior.org/projects/taskwarrior/wiki/Server_setup
VF 6:32 pm on 2013-11-11 Permalink |
Good stuff. I sync Task on 2 machines via dropbox+symlinks
brankito 12:16 am on 2014-02-19 Permalink |
i have so many problems installing gnutls on ubuntu on my server, so I didnt even come to the point of installing taskd server 😉
Taskwarrior 1:53 am on 2014-02-27 Permalink |
Was that a binary package you had problems with?
brankito 11:03 pm on 2014-03-02 Permalink |
yes it was the binary one that I had problems with, then i did compile another one properly without errors, but still your build script did not succeed, complainig it cannot find gnutls.. do not know what might be the problem..
adrinux 3:31 pm on 2014-05-16 Permalink |
@brankito For Ubuntu trusty (14.04) I just installed gnutls-bin and libgnutls-dev packages, that was enough gnutls to let taskserver compile…currently working through the config sections of documentation. Slightly slow because I’m trying to do it all with and Ansible role.
brankito 11:23 pm on 2014-03-04 Permalink |
am workin now ok!!!
theuser 12:26 pm on 2014-05-23 Permalink |
Compiling taskd on Solaris 10 ran into several problems:
Dependencies: were resolved by installing opencsw packages where appropriate
File.cpp uses flock(). Posix uses fcntl(). For the sake of portability, the calls to flock() should be rewritten to use fcntl which works on both BSD and SysV heritage (and on Linux as well). (Also, the semantics of flock() are different depending on the OS and Release involved, so fcntl() will avoid weird things in mixed environments) I’m not much of a programmer, so I rehashed http://www.redhat.com/archives/pam-list/1996-August/msg00049.htm into a workaround to get the thing compiled. (Another source would be http://www.perkin.org.uk/posts/solaris-portability-flock.html )
File.cpp usage of memset needs including
TLS{Client,Server}.cpp needed on Solaris, not
for linking, Solaris needs -lnsl and -lsocket. I caled cmake with -DCMAKE_EXE_LINKER_FLAGS=”-lnsl -lsocket”, but it’d be nice if that would be included.
I’m having 2 different versions of gnutls on my system: /usr/include/gnutls with a version stated as “0.9.5” and a newer one in /opt/csw from opencsw with version “3.1.23”. I did not understand enough of cmake
to force it to use the version installed under /opt/csw as opposed to the system-wide installed into /usr wich it stubbornly preferred. (calling cmake with -DCMAKE_INCLUDE_PATH=/opt/csw/include:/usr/include -DCMAKE_LIBRARY_PATH=/opt/csw/lib:/usr/lib had no effect). I do not know why it compiled successfully with Version 0.9.5 since on another system (nevada snv90) with gnutls version “1.6.3” TLSClient.cpp refused to build.
theuser 3:57 pm on 2014-05-23 Permalink |
Addendum:
Issues encounteded filed as TD-54,55,56:
https://bug.tasktools.org/browse/TD-number
TD-54: Usage of flock() prevents compilation on Solaris
TD-55: TLSServer/Client need to include errno.h on Solaris
TD-56: File.cpp needs to include string.h on Solaris
on Solaris10, all but one test went through:
0 2 theuser@sequoia pts/12 taskd.git/test 341% ./run_all
Pass: 2916
Fail: 1
Skipped: 0
Runtime: 1 seconds
The error seems to be in:
Nibbler::getName
ok 325 – ‘a1 one one.two 9’ getName -> ok
ok 326 – ‘ one one.two 9’ getName -> ‘a1’
ok 327 – ‘one one.two 9’ skipWS -> ok
ok 328 – ‘one one.two 9’ getName -> ok
ok 329 – ‘ one.two 9’ getName -> ‘one’
ok 330 – ‘one.two 9’ skipWS -> ok
ok 331 – ‘one.two 9’ getName -> ok
ok 332 – ‘.two 9’ getName -> ‘one’
ok 333 – ‘two 9’ skip . -> ok
ok 334 – ‘two 9’ getName -> ok
ok 335 – ‘ 9’ getName -> ‘two’
ok 336 – ‘9’ skipWS -> ok
ok 337 – ‘9’ getName -> not ok
ok 338 – ” skip 9 -> ok
ok 339 – depleted
ok 340 – ‘entr\303\251e’ -> ok
not ok 341 – ‘entr\303\251e’ -> ‘entr\303\251e’
expected: ‘entr\303\251e’
got: ‘entr’
[…]
401 passed, 1 failed, 0 skipped. 99.8% passed.
bittracker 4:29 pm on 2014-05-27 Permalink |
Great Work – Thanks!
but it would be awesome if the Server Process will runs under a different User, who can be chosen in the Config File.