How to set up Tiny Tiny RSS on OpenBSD

The following article describes on how to install Tiny Tiny RSS on recent versions of OpenBSD using httpd. As of this writing, I am using OpenBSD 6.3.

Install and Configure MariaDB

Start by installing MariaDB on the server:

# pkg_add mariadb-server

Since OpenBSD’s httpd runs in a chroot you have to do some extra steps so that ttrss and the MariaDB command line programs can reach the control socket. Basically, you create a new run/mysql directory within httpd’s chroot add a proper symlink from outside and change the configuration accordingly.

# install -d -m 0755 -o root -g wheel /var/www/var
# install -d -m 0755 -o root -g wheel /var/www/var/run
# install -d -m 0711 -o _mysql -g _mysql /var/www/var/run/mysql
# rmdir /var/run/mysql
# ln -s /var/www/var/run/mysql /var/run/mysql

Set path in /etc/my.cnf accordingly

# grep run/mysql /etc/my.cnf
socket          = /var/www/var/run/mysql/mysql.sock
socket          = /var/www/var/run/mysql/mysql.sock

Make sure that the permissions match the ones of /var/run/mysql for the whole path! Otherwise mysqld won’t start. In the following steps the MariaDB service will be enabled, the initial database setup happens, the daemon will be started and finally, initialized.

# rcctl enable mysqld
# mysql_install_db
Installing MariaDB/MySQL system tables in '/var/mysql' ...
180924 18:23:27 [Note] /usr/local/libexec/mysqld (mysqld 10.0.36-MariaDB) starting as process 1229 ...

# rcctl start mysqld

# mysql_secure_installation
Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n]
Remove anonymous users? [Y/n]
Disallow root login remotely? [Y/n]
Remove test database and access to it? [Y/n]
Reload privilege tables now? [Y/n]
Thanks for using MariaDB!

Remember the root password and check if it works with mysql -u root -p

Create a separate Database for tt-rss

We create a separate user and database for ttrss. Make sure that you remember the password.

$ mysql -p -u root
mysql> CREATE USER 'ttrss'@'localhost' IDENTIFIED BY 'somepassword';
mysql> CREATE DATABASE ttrss;
mysql> GRANT ALL PRIVILEGES ON ttrss.* TO "ttrss"@"localhost" IDENTIFIED BY 'somepassword';

Error logs and Debugging

In case something goes wrong, start mysqld with the following command in case MariaDB fails to start:

# mysqld_safe
180831 10:43:22 mysqld_safe Logging to '/var/mysql/'.
180831 10:43:22 mysqld_safe Starting mysqld daemon with databases from /var/mysql

This shows the log path and probable errors:

# tail -f /var/mysql/
180831 10:42:18 [Note] InnoDB: Waiting for purge to start
180831 10:42:18 [Note] InnoDB:  Percona XtraDB ( 5.6.36-83.0 started; log sequence number 1616817
180831 10:42:18 [Note] Server socket created on IP: ''.
180831 10:42:18 [ERROR] Can't start server : Bind on unix socket: Permission denied
180831 10:42:18 [ERROR] Do you already have another mysqld server running on socket: /var/www/var/run/mysql/mysql.sock ?
180831 10:42:18 [ERROR] Aborting

The error above was caused by wrong permissions of the socket directory. Remember what I said about making sure that the permissions are correct earlier :)

Configure HTTPD

I use the following configuration for httpd. Basically, it instructs httpd to listen on Port 443 via HTTPS. The TLS certificates are from Let’s Encrypt and fetched with acme-client(1) from OpenBSD’s base installation.

# cat /etc/httpd.conf

server "default" {
        listen on $ext_addr tls port 443

        # TLS certificate and key files created with acme-client(1)
        tls certificate "/etc/ssl/host.fullchain.pem"
        tls key "/etc/ssl/private/host.key"

        location "*.php" {
                fastcgi socket "/run/php-fpm.sock"

        location "/tt-rss/*" {
                directory { index "index.php" }

# Include MIME types instead of the built-in ones
types {
        include "/usr/share/misc/mime.types"

Populate the chroot with some more files to enable DNS lookup and certificate validation. Otherwise, ttrss cannot update your feeds and will complain about missing DNS resolution.

# cd /var/www
# mkdir -p etc/ssl
# cp /etc/resolv.conf etc
# cp /etc/ssl/cert.pem etc/ssl

And now we are ready to enable and start httpd.

# rcctl enable httpd
# rcctl start httpd

Install PHP 7

I chose PHP Version 7 and not Version 5:

# pkg_add php php-curl php-gd php-mysqli php-pdo_mysql

Now, enable all needed modules, enable php_fpm and start the service via rcctl.

# cat /etc/php-7.0/php.ini

# rcctl enable php70_fpm
# rcctl start php70_fpm

Install TTRSS

The installation of ttrss is quite simple since you only have to clone the git repository. Usually, I clone a shadow copy since I don’t need the history of the project on my web server. If you haven’t already installed git, do so by fetching the package via pkg_add. You can also download a ZIP file from the latest git mater from Github but that makes updates harder.

# cd /var/www/htdocs
# git clone --depth=1 tt-rss
# chown -R www:www tt-rss/

Go to for configuration. Use the name of the separate database and the corresponding password.

Set up the Feed Updater

Use chsh to set /bin/ksh as shell for www and set up a cronjob to call the update process every 5 minutes (or whatever interval you like.

# su - www
# crontab -e
*/5 * * * * /usr/local/bin/php-7.0 /var/www/htdocs/tt-rss/update.php --feeds --quiet

Install additional Themes

Since I don’t like the default theme, I use the Feedly theme. Installation is quite easy and similar to the one of ttrss.

# ftp
2008441 bytes received in 3.20 seconds (612.35 KB/s)

# unzip
   creating: tt-rss-feedly-theme-master/
  inflating: tt-rss-feedly-theme-master/

# cp feedly.css feedly-night.css /var/www/htdocs/tt-rss/themes
# cp -R feedly /var/www/htdocs/tt-rss/themes

Now select the theme in the preferences menu.

Restore from Backup

Since I had a disk crash on one of my servers, I also have some notes on how to restore a ttrss database from a backup. Basically, my backup consists of a nightly MariaDB dump to a remote location. YMMV but this should give you an idea how it works.

Maybe you have to create the ttrss database before, see above on how to. Then just restore and tt-rss should look as before.

# mysql -u root -p ttrss < /home/xhr/restore2/var/backups/ttrss-20180826.dump

$Id:,v 1.4 2020/05/16 07:44:02 cvs Exp $