Replacing Todoist with a Self-Hosted CalDAV Setup
I’ve been gradually replacing various commercial and/or closed source cloud services with self-hosted alternatives. I’ll start posting about more of them in the very near future, but the one I decided to replace this weekend was Todoist.
Don’t get the wrong idea. I actually really like Todoist. It’s clean, it has nice Android widgets, adding tasks is easy, the free tier had just about everything I wanted, etc. It lacked one thing that I wanted, though, integration into Thunderbird tasks on my desktop machine. Whenever I can I prefer to self-host Open Source projects, but will happily pay for a monthly service if it’s something that really helps me be more productive or is the best at solving a particular problem I’ve got. It’s a balancing act, self-hosting comes with a fair amount of tech-debt and resource consumption (mostly time), but paying a monthly or yearly fee to every SaaS platform out there that I would use only casually would get out of control quickly.
Since I’m a very casual user of this type of task list, it makes sense for me to self-host it, provided I can find something that will work. So that’s the goal: find a task management system I could run myself, sync across devices, and keep portable. I ended up settling on Radicale, a CalDAV server, paired with Tasks.org on Android and Thunderbird on the desktop.
Settling is definitely a key word here. It works, but like a lot of self-hosted solutions, it comes with tradeoffs.
Why I Chose Radicale
As primarily solo-developer, I didn’t want or need a full-blown groupware solution like NextCloud. That level of tech-debt is more than I can justify when I have a Synology NAS. By the same token, I didn’t necessarily want to go all-in on Synology’s productivity suite since it falls short in many ways compared to Zoho, Google, or even Office 365, each of those I use for different businesses. I can use the Synology to backup from those services. My goal here was something light, open source, and easy to manage. Radicale fit that requirement pretty well. I also didn’t want to use any of those other services because this is for personal tasks that I need to remind myself to do on the weekends, like “Clean out the Garage” or “Sweep the back patio”. I don’t want to clutter those other services with my personal stuff, considering those are all of my business accounts. I also do work on the iOS and macOS for app development, so having something completely open and cross-platform is always a consideration.
Back to Radicale – it’s a single-purpose CalDAV and CardDAV server that stores everything in plain files. It runs well in Docker, and it doesn’t need a database. That made it easy to run on my Synology NAS using Portainer and to reverse proxy it through Caddy alongside my other self-hosted services.
Setup was mostly straightforward. I mapped storage to /volume1/docker/radicale
, generated a user file using htpasswd in Docker, and configured Caddy to serve it over HTTPS.
Here’s my Dockerfile that I put into Portainer and started up on my Synology NAS:
services:
radicale:
image: tomsquest/docker-radicale:latest
container_name: radicale
restart: unless-stopped
ports:
- 5232:5232
volumes:
- /volume1/docker/radicale/data:/data
- /volume1/docker/radicale/config:/config
environment:
- RADICALE_CONFIG=/config/config
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5232"]
interval: 30s
timeout: 10s
retries: 3
It really doesn’t get much easier than that.
Here is my config file:
[server]
hosts = 0.0.0.0:5232
[auth]
type = htpasswd
htpasswd_filename = /config/users
htpasswd_encryption = bcrypt
[rights]
type = owner_only
[storage]
filesystem_folder = /data/collections
There are quite a few more options, but since I’m putting this together for just me, simple is better.
I also had to setup my htpasswd style users file (replacing USERNAME and PASSWORD with my username and password):
docker run --rm httpd:2.4-alpine htpasswd -Bbn USERNAME PASSWORD > /volume1/config/users
Starting it up and all was well.
Android Task Sync
The biggest issue was finding a mobile app that could sync with Radicale directly.
I tried several calendar and task apps from F-Droid. Most of them either relied on DAVx⁵ or didn’t support CalDAV tasks at all. Etar and Fossify Calendar both looked promising but either didn’t support CalDAV natively or didn’t support tasks at all. DAVx⁵ works, but I’d prefer to avoid adding another sync layer that I have to maintain and that can potentially drain my better if at all possible.
Tasks.org was the only viable open source task app I could find that worked with CalDAV VTODO. It syncs fine, but the user interface is quite dated and inconsistent. The save button is a floppy disk icon, and the overall layout feels like something from early Android. It works, but I wouldn’t recommend it to anyone used to apps like Todoist.
For my calendar on Android, I purchased OneCalendar. It’s not open source, but it’s the only Android calendar app I’ve found that supports Zoho, Teams, Google Calendar, and CalDAV in one place. Since I need to use Zoho, Google, and Teams for work, it makes the most sense for now.
Thunderbird Tasks
Thunderbird’s task integration works, but it’s tied directly to the calendar UI. If I disable a calendar for tasks, it also disappears from the calendar view. That’s not ideal, but it’s functional. Syncing was easy to set up with my Radicale credentials.
One limitation I ran into is that Radicale doesn’t seem to support creating multiple calendars under a single user — or at least not in a way that clients like Thunderbird or Tasks.org can use easily. For now, one shared task list per user is enough, but this could be a problem down the line.
Comparison with Synology Calendar
Before settling on Radicale, I also tested Synology’s built-in Calendar package. It’s much more polished than Radicale, includes a web interface, and integrates nicely with the rest of DSM.
Creating calendars and tasks was easy. I was even able to create a dedicated “Tasks” calendar. Unfortunately, Thunderbird didn’t sync tasks properly with it. It could only create tasks from the “Inbox”, and not any of my custom calendars. That’s probably fixable, but it was one more hurdle I didn’t want to spend time on.
I’m also not convinced that going all-in on Synology’s productivity tools is the right move. They’re well integrated, but also fairly limited. I might revisit them later, but for now, I’d rather stick to open standards and open tools.
Overall Thoughts
This solution works for me, but I wouldn’t recommend it to a non-technical user. It’s reliable and portable, but it’s also a bit clunky and lacks polish. Setting it up required multiple tools, configuration files, and workarounds. The mobile UI is outdated, and there’s no real “dashboard” for managing tasks outside of your chosen client. Apart from that, the whole configuration seems a bit fragile, and a bit too “black-boxish” for me.
Compared to something like Todoist, it’s clearly a pretty significant step down in usability. But if your priorities are self-hosting, data ownership, and portability, it gets the job done. It satisfies my needs well enough.
I’m still evaluating whether to stick with Radicale long term or try something like Nextcloud + Tasks. That might offer a better balance between usability and control, even if it’s heavier.
As of now, I have a self-hosted to-do list that syncs across devices, stores everything locally, and doesn’t depend on any third-party service — and that’s what I was going for.
I'd love to hear about what you've built.