Greg Sarjeant e809644b49
Some checks are pending
Run unit tests / run-unit-tests (push) Waiting to run
freal (#83)
Reviewed-on: https://gitea.subcultureofone.org/greg/tkr/pulls/83
Co-authored-by: Greg Sarjeant <greg@subcultureofone.org>
Co-committed-by: Greg Sarjeant <greg@subcultureofone.org>
2025-08-28 22:47:50 +00:00
2025-08-28 22:47:50 +00:00
2025-08-13 12:02:37 +00:00
2025-07-23 22:13:46 -04:00
2025-08-15 01:44:50 +00:00
2025-08-28 22:21:34 +00:00
2025-06-15 20:16:59 -04:00
2025-06-15 20:07:28 -04:00
2025-08-28 12:57:19 +00:00

tkr

Prerequisite tests status Unit tests status

A simple, HTML-only status feed for self-hosted personal websites. Written in PHP. Heavily inspired by status.cafe.

LLM Disclosure

I used Claude for guidance on some portions of tkr. I've adapted any LLM-generated code suggestions, but if you strongly object to LLMs and don't want any LLM-assisted code on your site, then you shouldn't use this.

Requirements

  • A server running Linux
  • A web server, such as apache or nginx
    • Web server configs are in the examples directory
  • PHP 8.2+

Installation

  1. Get the latest package from https://gitea.subcultureofone.org/greg/tkr/packages
  2. Copy it to your web server
  3. Set up the directory permissions:
    • tkr/storage must be writable by the web server account
      • www-data on debian-based systems
      • apache on redhat-based systems
    • All other tkr directories should be readable by the web server account.
    • For example, if you're on debian:
      # Make 'root' the owner of everything under 'tkr'
      chown -R root:root tkr
      
      # Make 'www-data' the owner of everything under 'tkr/storage'
      chown -R www-data:www-data tkr/storage
      
      # Make 'tkr/storage' writable bt 'www-data'
      chmod 0770 tkr/storage
      
  4. Configure your web server for your environment and serving model:
    • There are example web server configs for common scenarios in the examples directory.
    • Expose only the public folder if possible
      • The VPS examples are configured this way.
      • If this isn't possible (e.g. shared hosting), it's okay. There are .htaccess files included to block access to other directories in shared hosting environments.
  5. Run the installation:

If any prerequisites are missing (required PHP extensions, directory permissions)

Features

  • RSS /rss and Atom /atom feeds
  • HTML and CSS implementation. No Javascript.
  • Accessible HTML, with strict accessibility settng to aid tab navigation
  • CSS uploads for custom theming
  • Custom emoji to personalize moods

I'm trying to make sure that the HTML is both semantically valid and accessible, but I have a lot to learn about both. If you see something I should fix, please let me know!

Server configuration notes

The document root should be /PATH/TO/tkr/public. This will ensure that only the files that need to be accessible from the internet are served by your web server.

There is an .htaccess file in the tkr/ root directory. It's designed for the following installation scenario:

  • shared hosting
  • tkr/ is installed to tkr/ under your web root. (e.g. public_html/tkr).
  • tkr/public is the document root
  • The other application directories are blocked both by tkr/.htaccess and by .htaccess files in the directories themselves. These are:
    • tkr/config
    • tkr/examples (not technically an application directory, but distributed with the .zip archive)
    • tkr/src
    • tkr/storage
    • tkr/templates

Docker compose (local development)

The docker directory contains docker-compose.yml files and web server configs for some different server configurations. For simplicity, these do not use SSL.

To run tkr locally on your machine, copy the docker-compose file you're interested in to tkr/ and run docker compose up.

Accessibility Note

The "Strict Accessibility" setting (enabled by default) adds tabindex="0" to all <a> tags to force them to get tab focus. This isn't strictly best practice. The <a> tag should get tab focus by default. But I've learned that some browsers (at least Safari and Vivaldi) disable this in their default configurations, making accessibility an opt-in feature.

If you'd like to revert to the standard behavior, toggle this setting off. But know that people who navigate by keyboard may have to reconfigure their browser settings in order to select hyperlinks.

Storage

tkr stores data at tkr/storage. This directory must be writable by the web server account and so should not be served by the web server. If you made tkr/public your document root, then you're fine. If you can't, then the .htaccess file in that directory will block access if you're running apache.

There are 3 subdirectories:

  • tkr/storage/db:
    • Contains a sqlite database: tkr.sqlite.
    • The database contains site settings, user profile data, ticks, and custom emoji.
  • tkr/storage/logs:
    • Runtime log files.
    • Logs rotate after 1,000 lines.
    • The last 5 log files are retained.
  • tkr/storage/uploads:
    • Stores custom CSS for personalized theming

SQLite Database Note

You don't have to do any database setup. The database is automatically created and initialized on first run.

Backup and restore

tkr is completely self-contained. To back up tkr, just zip up the tkr directory and copy it to your backup location. To restore it, unzip it in the new location.

Technically, you only need back up and restore the tkr/storage directory if you want to minimize the size of the backup, but the app is pretty small (~40 Kb compressed).

Screenshots

Mobile

tkr logged out view - mobile tkr logged in view - mobile

Desktop

tkr logged out view - desktop

tkr logged in view - desktop

Setup validation failure example

tkr setup validation failure

Acknowledgements

It's been a lot of fun to get back to building something. I'm grateful to the people and projects that inspired me to do it:

  • armaina - Armaina's a talented artist (check out the site!) who had the original idea for a self-hosted PHP version of status.cafe. That sounded like a fun project so I thought I'd see if I could manage it. This project doesn't exist without Armaina. Thank you!
  • status.cafe - The technological inspiration. Unless you really want to self-host, you should use status.cafe instead! I took a lot of inspiration from its design and then I made the CSS way heavier and probably lost some of the soul along the way.
  • 32-bit cafe - I started in technology as a hobbyist and idealist. Then I became a professional. The decades since have sucked the joy and the hope out of technology. 32-bit cafe reminded me that they're both still there.
Description
No description provided
Readme MIT 481 KiB
Languages
PHP 94.8%
CSS 5.1%