Misc Tech Notes

sön 27 mars 2016

Tiny Tiny RSS in Docker

Posted by Peter Reuterås in Tips   

Since Google Reader was discontinued I've been a happy user of Tiny Tiny RSS (tt-rss). It's written in PHP which makes me a little bit nervous but that is probably due to all the problems with Wordpress plugins. There are many sites that use PHP and Facebook is only one so it can be secure. TT-rss ignores invalid RSS feeds and unfortunately there are many of those on the internet. To solve this I thought of using the plugin ff_xmllint to clean up the feeds before tt-rss processes them.

Adding another code base on the web server didn't make me feel any better. Especially since it requires the use of proc_open which I had blocked in the PHP configuration file. The plugin uses proc_open to call the binaries xmllint or tidy. Even though it's not a strict security barrier I opted to put tt-rss in a Docker container and run php and the plugin in it. There I would allow proc_open. There are some security enhancements in this setup. First it's an extra layer to break out of. Secondly the container runs in its own SELinux context:

[root@dmz-vhost-01 ~]# ps -efZ | egrep "apache|ttrss|php" | grep -v httpd_t | grep -v grep
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 1014 8719  0 13:46 ? 00:00:03 /usr/sbin/apache2 -DFOREGROUND
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 1193 8719  0 13:50 ? 00:00:02 /usr/sbin/apache2 -DFOREGROUND
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 1236 8719  0 13:52 ? 00:00:02 /usr/sbin/apache2 -DFOREGROUND
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 3317 8719  0 14:06 ? 00:00:01 /usr/sbin/apache2 -DFOREGROUND
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 3372 8719  0 14:08 ? 00:00:00 /usr/sbin/apache2 -DFOREGROUND
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 3489 8719  0 14:11 ? 00:00:00 /usr/sbin/apache2 -DFOREGROUND
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 3844 8719  0 14:16 ? 00:00:00 /usr/sbin/apache2 -DFOREGROUND
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 3845 8718  0 14:16 ? 00:00:00 /usr/bin/php /var/www/html/ttrss/update_daemon2.php
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 3847 3845  0 14:16 ? 00:00:00 sh -c /usr/bin/php update.php --daemon-loop   --task 0 --pidlock 24617
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 3849 3847  0 14:16 ? 00:00:00 /usr/bin/php update.php --daemon-loop --task 0 --pidlock 24617
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 8718 8520  0 Mar26 ? 00:00:04 /usr/bin/php /var/www/html/ttrss/update_daemon2.php
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 root 8719 8520  0 Mar26 ? 00:00:05 /usr/sbin/apache2 -DFOREGROUND
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 31758 8719  0 13:15 ? 00:00:16 /usr/sbin/apache2 -DFOREGROUND
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 31762 8719  0 13:15 ? 00:00:09 /usr/sbin/apache2 -DFOREGROUND
system_u:system_r:svirt_lxc_net_t:s0:c172,c685 33 32169 8719  0 13:21 ? 00:00:04 /usr/sbin/apache2 -DFOREGROUND

To see why this is a good security feature you can watch this presentation at Youtube.

I looked at Docker Hub to find containers and clue/ttrss looked good but I wanted some extra plugins. A new repository on my Github page and a new container on my Docker Hub page. The container is built on Debian and is automatically rebuilt in case that image is updated. The image is also updated if I commit to my Github repository but I also needed a way to build it if the tt-rss repository is updated.

To trigger a new build of the image based on updates to the repository I checked out a copy to my "cron server" where I have my scheduled cron jobs running. At regular intervals a script does a git pull in my cloned repository and checks for new code. If there is a new version it calls a build trigger at Docker Hub and a new container is built. The trigger is a simple call to curl (my token removed).

curl -H "Content-Type: application/json" --data '{"build": true}' -X POST https://registry.hub.docker.com/u/reuteras/docker-ttrss/trigger/<Trigger token>/

Now the container must be updated and that is handled the same way as I did in an earlier post about RT so I want repeat that here.

To automate the installation I updated my Ansible configuration. The cron job was added to my cron-server role. Installation and configuration of Docker with the container is handled by:

# Install ttrss server in Docker                                                                                          
  - hosts: ttrss
  - docker
  - docker-ttrss
  - docker

The role docker installs Docker, starts the daemon and also adds the Spotify image cleanup script and a crontab entry for it. The role docker-ttrss pulls and start the container named reuteras/docker-ttrss from Docker Hub. It also installs a custom script to check for new builds and if one exists pulls it down and then restarts the container with the new code.