March 11, 2021

Taskwarrior With Web Frontend and Daily Emails

Guides taskwarrior workflow self-host

Paul Kelly

For my tasks and workflow I use Taskwarrior, which is a command line task manager. It is simple to learn the basics, but very powerful once you delve into what it can do. I am not going to go into all of that in this post though, maybe another time.

Whilst it is great for when I am sitting at my computer working, I end up not using it for all my other tasks and chores I have to do, as there is no easy way to enter tasks on a mobile device, you also don’t get reminders of tasks either.

In this post I am going to walk through installing Taskwarrior in a container (A Proxmox LXC in this case, but a virtual machine would work, and even a docker container if you know how to do that), and adding a web interface and also a simple script that will email you your tasks in the morning. I haven’t worked out a way to get reminders working, but I am working on it.

Initial Setup of the Container

Whilst this guide covers installing everything in a Proxmox LXC container the actual commands will work on any machine running the same version of Alpine Linux, so if you just want to spin up a VM in your Hypervisor of choice then you can still follow along.

The container I have created has the following specs:

Alpine Linux 3.7 default Proxmox LXC Template 512MB RAM 8GB HDD 1 CPU Core

With the container created login via the console within Proxmox as the base Alpine image doesn’t have SSH installed by default.

setup-alpine

Setup networking, root password, time-zone, mirrors and ssh server.

Add a new user that will run the Taskwarrior processes

adduser taskwarrior

Install sudo and add the new user to the administrator group.

apk add sudo
echo '%wheel ALL=(ALL) ALL' > /etc/sudoers.d/wheel
adduser taskwarrior wheel

We can now ssh into the container using a normal terminal for our taskwarrior user.

Check that sudo works for the new user whilst also updating all the packages:

sudo apk update && sudo apk upgrade

Install Taskwarrior

Now we can install taskwarrior and get it setup for syncing:

apk add task

Running task the first time will create a .taskrc config file that we can modify

task 
A configuration file could not be found in

Would you like a sample /home/taskwarrior/.taskrc created, so Taskwarrior can proceed? (yes/no) yes

Now, if you have other instances of taskwarrior running then you probably already have sync setup so you can reuse the settings and keys you already have.

If you haven’t setup syncing before then, whilst you can install and setup a local taskd server, I would recommend using something like https://freecinc.com which will provide certificates and settings to get everything working without much fuss.

Basically go to https://freecinc.com and follow the instructions. I use scp to copy my keys to the new server.

scp *.pem taskwarror@task.ip.address:~/.task

If everything has gone according to plan then if you already have tasks that have been synced:

task sync

should retrieve all your tasks. Alternatively if this is your first time setting up sync then you will need to initialise sync:

task sync init

With taskwarrior installed and syncing, let’s get the web interface installed.

Install taskwarrior-web

For this to work we will need to install a few packages, and is also the reason we needed to use an older version of Alpine Linux as this app is a bit old and currently won’t run on newer versions of Ruby:

sudo apk add ruby ruby-dev make g++ git

The app itself is a Ruby gem:

sudo gem install taskwarrior-web

NOTE: I wouldn’t normally use sudo when installing a gem, but to add the path to the locally installed gem would mean updating the system wide PATH variable, which seems, at least to me to be kind of the same thing. However, I am not an expert in this kind of stuff, so I could be wrong.

You may get a documentation error at the end of the install which you can safely ignore. If you want to get rid of the errors then you can install:

sudo apk add ruby-rdoc ruby-irb

Run the app to check it works:

task-web

The app should run, tell you the port it is running on and then background itself. You can check it is working correctly by going to http://ip.of.server:5678 and hopefully you are presented with all your tasks.

This is great, but we now need to install the app as a service so it will start after a reboot of the container. To do this we need to create a service file called task-web containing the following:

#!/sbin/openrc-run

name=$RC_SCVNAME
command="task-web"
command_args="-F -L"
command_user="taskwarrior"
command_background="yes"
pidfile="/run/$RC_SVCNAME/$RC_SVCNAME.pid"
start_pre() {
        checkpath --directory --owner $command_user:$command_user --mode 0775 \
                /run/$RC_SVCNAME /var/log/$RC_SVCNAME
}

This contains the command we want to run, the arguments that need to be used when it is run and the user who we want to run it as. It also creates a pid file as the process will be run in the background.

With this created we need to install it and check it works:

sudo mv task-web /etc/init.d/
sudo chmod +x /etc/init.d/task-web
sudo rc-update add task-web default
sudo rc-service task-web start
* Caching service dependencies ...                                                                               [ ok ]
 * /run/task-web: creating directory
 * /run/task-web: correcting owner
 * /var/log/task-web: creating directory
 * /var/log/task-web: correcting owner
 * Starting task-web ...                                                                                          [ ok ]

Browsing back to the taskwarrior-web page should still work. If the initial instance of task-web is still running then the service may not start correctly. You can kill the original instance by getting its PID using the top command and then:

sudo kill PID

Assuming everything is fine the last thing to check is that the service starts on a reboot, so restart the container:

sudo reboot

Check the site comes up after the reboot and then we can move on to getting the daily emails working.

Daily Emails of Outstanding Tasks

Maybe it’s just me, but I quite like to receive an email in the morning with my tasks that are due for that day.

I generally try to give all my tasks a due date if I can, and I also have a lot of recurring tasks, especially one for chores around the house. So it is nice to be reminded of what I have coming up that day.

The original script that I used for this can be found here: https://github.com/ajpierce/taskmailer/

I have forked it for my own needs, as the original script works with projects, whereas I prefer to have tasks that are due in the next couple of days sent out. The fork allows both projects or due dates to be used: https://github.com/pauldavidkelly/taskmailer-ng

It isn’t the prettiest of emails that comes out as it is basically the output from a Taskwarrior minimal report stuck in an email with no formatting. Hopefully I will get around to making it look a bit better in the future.

Anyway, to get it installed on our server:

git clone https://github.com/pauldavidkelly/taskmailer-ng.git

We have already installed ruby but there are a couple of additional dependencies we need to add:

gem install pony
gem install psych

Within the taskmailer-ng folder there is a config folder. The smtp.example.yaml and jobs.example.yaml need to be renamed and edited.

They are pretty self-explanatory, put your SMTP details in smtp.yaml and adjust the due dates and projects you want emailed in jobs.yaml, as well as the recipient and from email addresses.

There has to be something in both the due and projects sections, I haven’t got around to putting in proper error handling for blank sections so the system will error. If you don’t want to have either due dates or projects then put a date or project name in the section that won’t return any results.

Check the script is working:

ruby ./taskmailer.rb

Depending on what the script matched you may get an output that says No Matches, but you will know it worked if you get an email in your inbox:

Screenshot of an email sent out by TaskMailer

As I said, not very pretty, but it gets the job done.The above email has less columns than normal as I added the following to my .taskrc file:

 # Make minimal report more minimal
report.minimal.labels=Due,Project,Description
report.minimal.columns=due,project,description.count

The final thing to get working is to automate the sending of the emails. This can be done via crontab:

crontab -e

In the blank file that comes up enter when you want to have the emails sent:

0 7 * * * ruby ~/taskmailer-ng/send_mail.rb

This sends out the emails every morning at 7. You can add another line if you want the emails to come twice a day or maybe even more! Check out Crontab Guru for editing the crontab schedule.

With the crontab file saved sit back and relax and wait for the mails to start showing up.

Conclusion

OK, I admit, Taskwarrior is not for everyone, I love the way it works and it fits my workflow quite well, but it is missing a web interface (you can use inthe.am if you don’t want to self-host) for when I am on a mobile device and it is nice to get reminders of tasks. By adding in taskwarrior-web and taskmailer I get those things.

Yes, they are basic and for 99.9% of people they can’t be bothered and it won’t work for them, but if you use the command line a lot or already use Taskwarrior but would like it to be a bit more user-friendly then this adds a couple of “nice to have” features.