"A small and simple self-hosted personal tasks organiser"
ransparent - Open source and openly described. Even the database schema is documented.
ir-gapped - Entirely self-contained. Runs without internet access, external services, or tracking.
imple - Easy to install, easy to understand, and easy to operate.
eep everything - Unlimited tasks and unlimited lists — no artificial limits.
rivate - Your data stays with you. No cloud, no telemetry, no external dependencies.
pen - Export tasks to CSV, PDF, clipboard, or print cleanly.
o clutter - A focused interface that shows only what you actually need.
ours - Free to use and always will be. No commercial edition, no hosted version.
| Desktop View | Mobile View |
|---|---|
![]() |
![]() |
Taskpony supports unlimited Tasks organised within unlimited Lists, repeating tasks and free movement of tasks within Lists. Tasks can be exported to the clipboard, CSV, PDF or cleanly printed.
No phone app required. The interface is responsive and scales well to all devices. There are no trackers and does not require access to the internet to function as all required files are included. The list will automatically reload if another browser has changed the database to ensure it's up to date.
See some more Screenshots
Deploy using Docker Compose and visit port 5000
- Features
- Demo
- Quick Start
- Table of Contents
- Installation
- Security
- FAQ
- Upgrading
- Documentation
- Backups
- Goals
- Screenshots
- Credits
- Licence
Taskpony is intended to be easy to install and maintain. Docker Compose, Docker or as a standalone Linux systemd service
There is an example docker-compose.yml file in the repository which should work for most situations.
Copy this to your chosen directory, inspect and adjust as desired, and run: docker compose up -d
On completion, Taskpony should be available on http://localhost:5000
The default version mounts a persistant volume in ./data where the Sqlite database taskpony.db will be created automatically.
- View output logs with
docker compose logsfrom the directory thedocker-compose.ymlfile is in.
The latest version of Taskpony is on Dockerhub as
digdilem/taskpony:latest
Install docker and run something like the following.
docker run -d -p 5000:5000 digdilem/taskpony:latest
Within a few seconds, Taskpony should be available to your web browser on port 5000
If you want it to run on a different port, change the first 5000 to something else.
- Find the container id with
docker ps(the random string left ofdigdilem/taskpony:latest) - View output logs with
docker logs STRING- replacing STRING with the above.
*It's assumed that Taskpony will be installed to /opt/taskpony but it shouldn't matter. As of 0.4 it will detect its installation dir and as long as it has write privileges there it should be happy. Just remember to change the ExecStart and WorkingDirectory lines in taskpony.service
- Change to
/optand installgitif it isn't already. Then pull the files in from Github
cd /opt
git clone https://github.com/digdilem/taskpony.git
- Install the perl modules that taskpony requires
Debian 13
apt-get install libdbi-perl libdbd-sqlite3-perl libplack-perl perl
RHEL, Rocky, Alma (EL distros)
dnf install perl-Plack perl-DBI perl-DBD-SQLite
For other distros, then cpan or cpanm could be used to install these:
Plack::Request
Plack::Response
Plack::Builder
DBI
- Copy the supplied
taskpony.serviceto/etc/systemd/systemand start and enable it
cp /opt/taskpony/taskpony.service /etc/systemd/system
systemctl daemon-reload
systemctl enable --now taskpony
- Visit port 5000 of that machine with your web browser. Eg, if it's localhost:
http://localhost:5000and you should see Taskpony initial list.
Or if it's on a machine with, say, an IP of 10.0.0.16, then http://10.0.0.16:5000
If you want to use another port instead of 5000, edit taskpony.service and change the plackup line. Eg: ExecStart=/usr/bin/plackup -r -p 5001 /opt/taskpony/taskpony.psgi
Taskpony expects to be installed in /opt/taskpony. If you want it to exist elsewhere, you'll need to:
-
Edit
taskpony.psgiand changemy $db_path = '/opt/taskpony/db/taskpony.db';to point to the intended location of the database file that Taskpony will create. -
Amend
taskpony.serviceand change these lines to match your new path:
ExecStart=/usr/bin/plackup -r -p 5000 /opt/taskpony/taskpony.psgi
WorkingDirectory=/opt/taskpony
See output logs with journalctl -u taskpony or the current status with systemctl status taskpony
Part of Taskpony's design choice is that there are no authentication systems built in. If you require authentication, such as a multi-user LAN or you are accessing Taskpony from the internet, you are strongly encouraged to use a reverse proxy with authentication in front of it. This could be Nginx Proxy Manager, Apache configured to operate with a reverse proxy, or a cloud solution such as Cloudflare Tunnels protected by an Access policy.
Can I tell you about bugs or suggest improvements?
Please do! The best place is to use Github issues and raise a New Issue
How do I back up my tasks?
All tasks, lists and settings are kept within the single file, taskpony.db stored in /opt/taskpony/db (Local if systemd, within ./data if docker). This can be copied somewhere safe to back it up. If you need to restore a backup, just stop Taskpony, copy that file to where Taskpony expects it and restart Taskpony. As of v0.3, Taskpony will make daily backups of this file, named taskpony.db.0 and incrementing by day age to the value defined in /config
Is there an Android or IOS app?
Sorry, no. Taskpony was designed to be a responsive web app and works well on both desktop and smaller devices, so an app is not considered necessary. (If you use a phone for your tasks as I do, create a shortcut on the desktop to Taskpony so it instantly opens in a browser) If anyone wants to create an app for Taskpony, that's great, and if it's good then let me know and I'll reference it here.
When will support for multiple users, groups or teams be added?
Never, sorry. This is a hard design choice to keep Taskpony small and simple. There are a lot of alternative projects with groupware ability if that is important to you.
But I really want to run a copy for more than one person!
One way around this is to run multiple instances, each with their own port.
How do I add HTTPS?
Use a reverse proxy - see #security
How do I protect Taskpony with a username and password?
Use a reverse proxy - see #security
Does Taskpony support Caldav?
No. It may do in the future but there are no initial plans to do so.
Can I use a different database type?
Not presently. SQLite was chosen to keep things small and simple. I think it should suffice for a task application.
When I return to Taskpony, it has changed list.
If another client changes the Active List, then all other clients will load that when they check for database changes. If it's switching between lists, check that you don't have any clients using a bookmark or shortcut that includes?lid=N as a URL argument as that will change the Active List.
Upgrading Taskpony should be easy - overwrite all files but ensure taskpony.db survives.
There is no need to upgrade Taskpony sequentially - any later version should install over the top of an older version and be fine. Just pick the latest version when you wish to upgrade.
Change to the directory you put your docker-compose.yml
Compare the compose file with that of the new version to see if there are any changes required.
Then run from the compose directory:
docker compose down
docker compose pull
docker compose up -d
- Read the Release Notes for any breaking changes
- Make a copy of the old
/opt/taskponydirectory, especially thedb/taskpony.dbdatabase as a backup. - Download the latest files from https://github.com/digdilem/taskpony/ (Code -> Download ZIP)
- Unzip its contents into /opt/taskpony, overwriting the existing files.
Taskpony should restart itself automatically when its own file changes, this will be shown in its log with -- /opt/taskpony/taskpony.psgi updated. If there are any issues, restarting Taskpony with systemctl restart taskpony is advised.
If the upgrade includes any database schema changes, Taskpony should automatically detect and apply any updates when it's first started, see logs; journalctl -u taskpony
Stop the existing container and repeat the installation instructions to pull the new image.
Follow the install guides above, and you should be able to access Taskpony on http port 5000 with your web browser.
-
Clicking on the Taskpony Logo and name will load the current Tasks Page.
-
The default page shows a pulldown menu at the top with an entry for the Default List (change this in the Lists page) followed by "All Lists" followed by an alpha-sorted list of the remaining Lists.
-
Below that is a quick entry form that allows you to add a task to the current list. Because it's autofocused, you can enter multiple tasks by typing, hitting enter, then typing the next one without needing to reselect it with the mouse. This quick form will be missing if "All lists" is selected.
-
Then the main tasks lists is shown.
-
-
Tick the checkbox to mark a task as completed which removes it from the active tasks. If you make a mistake, you can select the "Show completed Tasks" icon at the top and click the undo button to set it as active.
-
To reduce clutter, the dates and list name for tasks can be hidden in the main tasks list be disabling
Show DatesandShow Listsin Settings. -
A Filter or Search box is displayed top right if
Display Filter Boxis selected in Settings that will only display matching strings. -
Hover over the task Title to see a popup of the task's description if one was set. Tasks can be edited, and descriptions added to them, by clicking the title and completing the resulting form.
-
Tasks can be set as Repeating by clicking the Task title to visit the Edit Task form.
-
The tasks list can be sorted by clicking the header values.
-
If there are enough tasks to trigger the
Number of Tasks to show on each pagevalue in Settings, then the list will automatically paginate and show the number of pages together with Next/Previous buttons below it. -
If
Display export buttonsis selected in Settings, then extra "Export" buttons appear under the list. These are:
-
Copy= Copy the contents of the List into the clipboard, allowing you to paste it elsewhere. -
CSV= Triggers a download of the chosen tasks as a CSV file allowing you to import them into a spreadsheet. -
PDF= Generates a PDF of the tasks and downloads it. -
Print= Creates a clean, printable page and triggers the Print dialog, allowing you to make the tasklist physical. (Such as printing out a shopping list) -
To change the view from active to completed tasks, use the curled arrow button above the list. Completed Tasks can be reverted to Active with the curled undo arrow next to them in the list.
Tasks can be set to repeat a set number of days after completing. This is useful for tasks that need to be done every NN days - watering the plants, taking the bins out and so on.
To enable this, create a task as normal and then click on it to Edit the task, then you can check these two fields to enable Repeat behaviour and set the number of days.
When this task is next checked as completed, it will disappear as normal. Once that number of days has passed, it will re-appear in the list as before.
To stop a task for repeating, you can either
- Edit the Task, Untick the
Repeat this Taskbox, or - Edit the Task and click
Delete Taskto permanently remove it.
Each task normally belongs to a Task List allowing you to group multiple types of things together.
In usage, you swap between Task Lists by selecting them from the Pulldown at the top of every page, and navigate back to the Tasks page for that List by clicking the Logo, top left.
In most places, Lists are Alpha-sorted and are case sensitive, so 'A-Z' then 'a-z'
Click on the "Manage Lists" icon at the top right, which takes you to the /lists page. Here's you'll find three cards.
This shows all the currently Active Lists, showing their Name, Description and a count of Active and Completed Tasks belonging to them.
You can click on the Title of each List to edit it, and there's a link at the bottom of each Tasks List which takes you to the same Edit List page, directly from Tasks.
List Editing allows you to change the Name and Description, and also set a Highlight Colour. This Colour will replace the global Default Highlight Colour when displaying pages related to that particular List, and may be useful to remind yourself which list you're in.
If you want to revert to the Default Highlight Colour for that list, just tick the Clear Highlight Colour checkbox and then click Save List.
There's also four Actions you can perform on each List: (Hover over each to get a short description)
Make DefaultOnly one List can be the Default, which means that it's placed at the top of the Pulldown at the top of each page, making it easier to load. This might be for your daily, most used List.Set all Tasks ActiveThis Action will change the status of every Task in this List to "Active". This can be useful if you have something like a regular shopping list which you tick off items as you buy them, but want to start over again next time you go shopping.Set all Tasks CompletedAs above, but marks all tasks as Completed.Delete ListThis actually makes the list Inactive, so it can be made Active again later (see below). When clicked, you'll be prompted with several options about what to do with the tasks within that list.
Simply allows you to create a new list with a description. There are no limit to the number of lists you can create.
Any list set as Inactive from the Active Lists panel will move here.
This is a sort of holding area for Lists. It allows you to recover an accidentally "deleted" List, but also put Lists that aren't in current use. For example, I have a list for my Christmas Dinner process which lives here until December when I make it Active again.
The options here are:
Set this List as ActiveThis will return the List to theActive Listspanel, and it will again appear in the Picklist.Permanently Delete all TasksThis will permanently delete all Tasks belonging to this List.Permanently Delete This ListThis will delete the List, but not its tasks.
Deleting a List without first removing its Tasks will make them Orphans. They will still exist in the State they were previously, and will show up in the "Show all Lists" Tasks List.
Each day, Taskpony will automatically make a backup of its database by copying taskpony.db to taskpony.db.0, and rename any previous backups incrementally (.1 to .2, .0 to .1 etc) You can configure how many backups to keep in Settings -> Number of daily database backups to keep.
Restoring a database is a manual process:
- Stop Taskpony. (Either
systemctl stop taskponyor if Docker, change to the compose location anddocker compose down) - Change to the directory containing taskpony.db (
cd /opt/taskpony/dbor if dockercd data) - Move the existing taskpony.db elsewhere (
mv taskpony.db taskpony.db.old) - Copy the chosen backup to taskpony.db (
cp taskpony.db.3 taskpony.db) - Restart Taskpony and it should now be using the restored database.
Any issues during this process are likely to be file or permission related, and Taskpony should show them in its console. (journalctl -u taskpony or docker compose logs)
Because Taskpony's database is a simple sqlite3 file, it would be possible to automate this process allowing some interesting thoughts about resetting a demo instance or swapping datasets around for some purpose.
- The http endpoint
/api/pingexists for external health checks. It will return 200 and "pong" if it's able to. - The supplied docker-compose.yml file contains an internal healthcheck compatible with Docker's Health monitoring.
- Remain focused on providing single user Tasks and Lists.
- Be a small, fast and responsive web based app that is usable on all devices by a standard browser.
- Be free and open in all senses of the word. No telemetry or tracking, no lock-in, no registration, no monetising.
- Be linux native or docker for easy self-hosting.
- Adhere to the KISS principle It should be easy for any user to pick up and use. Features should be self explaining as much as possible, with in-context help available through tooltips.
- Remain simple to install and update, with automated database upgrades.
- Not become over featured.
- Not spread into Teamware, a Ticketing system or become group-based.
- Not add complex systems like Gantt Charts, Kanbans etc.
- This software was written on Dartmoor in England. There is a Dartmoor Pony grazing outside of my window as I write this. Dartmoor Ponies are compact, tough and hard working. Also, cute.
In terms of helping the project, then filing Bug Reports and Suggestions for improvement via the Issues system is very helpful.
It's not necessary to pay to use Taskpony but but if you wish to show appreciation, then thank you!
Taskpony is built with the help of this great FOSS software:
- Perl 5
- Plack
- SQLite
- Bootstrap 5 (Bundled)
- JQuery (Bundled)
- Datatables (Bundled)
- Tabler Icons (Embedded SVGs)
- Tyna_Janoch for the example background image
Taskpony is released under the MIT Licence.
You may use, copy, modify, and distribute your code for any purpose, as long as they include my original copyright notice and licence text.
# End of file













