Emmanuel Kasper: back to blogging and running a feed reader as a containerized systemd service
After reading about Jonathan McDowell feed reader install and the back to blogging initiative, I decided to install a feed reader to follow all those nice blog posts. With a feed reader you can compose your own feed of news based on blog posts, websites, mastodon toots. And then you are independant from ad oriented ranking algorithms of social networks.
Since Jonathan used FreshRSS as a feed reader, I started with the same software. On a quick glance on its github page, it sounded like a good project:
- active contributions
- different channels for stable and latest version of the software
- container images pointing to the stable release
- support multiple databases for storage, including PostgreSQL
- correct documentation mentioning security caveats
- upgrades from FreshRSS are easy to do and can be done separately from operating system upgrades
- I do not mess my based operating system with php (subjective) and in case of a compromized freshrss, the freshrss/apache install would be still restrained to its own Linux namespaces, separated from the rest of the system.
- start a container image based on the start command provided by the FreshRSS project. The
podmancommand line is nearly identical to thedockercommand line, excepts thatpodmanexpects the fully qualified domain name associated with the container image, and I chose to run the freshrss container on the localhost interface only. I also use a defined version tag, because using thelatesttag makes it complicated to track which exact ersion I have installed.
# podman pull docker.io/freshrss/freshrss:1.20.1
# podman run --detach --restart unless-stopped --log-opt max-size=10m \
--publish 127.0.0.1:8081:80 \
--env TZ=Europe/Paris \
--env 'CRON_MIN=1,31' \
--volume freshrss_data:/var/www/FreshRSS/data \
--volume freshrss_extensions:/var/www/FreshRSS/extensions \
--name freshrss \
docker.io/freshrss/freshrss:1.20.1
- verify where the podman volumes have been created. This is where the user data of freshrss will be stored.
# podman volume ls
# podman volume inspect freshrss_data
- now that freshrss is installed, you can start its configuration wizard at localhost:8081. You should keep the default sqlite choice
- finally after running the wizard, you can login again and add some feeds
- verify that your config has been stored outside the container, and inside the volume (so that it will not be erased in case of upgrages)
# ls -l /var/lib/containers/storage/volumes/freshrss_data/_data/users/
- verify the state of sqlite database
echo '.tables' sqlite3 /var/lib/containers/storage/volumes/freshrss_data/_data/users/<your freshrss user>/db.sqlite
category entry entrytag entrytmp feed tag
Going with FreshRSS in Production
Podman has this very nice feature that it can generate a systemd unit from a running container, and use systemd to start a container on boot. This is in contrary to docker where the docker daemon does the stop/start of containers on boot.
I prefer the systemd approach as it treats containers the same way as other system services.
Once the freshrss container is running we can generate a systemd unit of it with:
# podman generate systemd --new --name freshrss tee /etc/systemd/system/container-freshrss.service
Let s stop the container we started previously, and use systemd to manage it:
# podman stop freshrss
# systemctl enable --now container-freshrss.service
We can verify that we have a listening socket on the localhost interface, on the source port 8081
# systemctl status container-freshrss.service
...
# ss --listening --numeric --process '( sport = 8081 )'
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 4096 127.0.0.1:8081 0.0.0.0:* users:(("conmon",pid=4464,fd=5))
Nota Bene: conmon (8) is the process managing the network namespace in which fresh-rss is running, hence it is displayed as the process owning the listening socket
Exposing FreshRSS to the external world
We have now a running service, but we need to make it reachable from the internet.
The simplest, classical way, is to create a subdomain and a VirtualHost configured as a reverse proxy to access the service at 127.0.0.1:8081. Fortunately the FreshRSS authors have documented this setup in https://github.com/FreshRSS/FreshRSS/tree/edge/Docker#alternative-reverse-proxy-using-apache
and those steps are no different from a standard application behind a web reverse proxy.
Upgrading freshrss container to a newer version
A documentation showing how to install a piece of software is nothing when
it does not show how to upgrade that said software. Installing is easy, upgrading is where the challenge is. Fortunately to the good stateless design of freshrss (everything is in the sqlite database, which is backed by a non-epheremal volume in our setup), switchting versions is a peace of cake.
# podman pull docker.io/freshrss/freshrss:1.20.2
# systemctl stop container-freshrss.service
# sed -i 's,docker.io/freshrss/freshrss:1.20.1,docker.io/freshrss/freshrss:1.20.2,' /etc/systemd/system/container-freshrss.service
# systemctl daemon-reload
# systemctl start container-freshrss.service
If you need to rollback, you just need to revert version numbers in the instruction above.
Enjoy your own reader feed !
I will add the following feeds of blogs I like, let us see if I follow them better with a feed reader !
During COVID companies suddenly found themselves able to offer remote working where it hadn t previously been on offer. That s changed over the past 2 or so years, with most places I m aware of moving back from a fully remote situation to either some sort of hybrid, or even full time office attendance. For example last week Amazon
(There s a handy
This is disappointing, but if it turns out to be a problem I can look at mounting it externally. I also assume as 5G is gradually rolled out further things will naturally improve, but that might be wishful thinking on my part.
Rather than wait until my main link had a problem I decided to try a day working over the 5G connection. I spend a lot of my time either in browser based apps or accessing remote systems via SSH, so I m reasonably sensitive to a jittery or otherwise flaky connection. I picked a day that I did not have any meetings planned, but as it happened I ended up with an adhoc video call arranged. I m pleased to say that it all worked just fine; definitely noticeable as slower than the FTTP connection (to be expected), but all workable and even the video call was fine (at least from my end). Looking at the traffic graph shows the expected ~ 10Mb/s peak (actually a little higher, and looking at the FTTP stats for previous days not out of keeping with what we see there), and you can just about see the ~ 3Mb/s symmetric use by the video call at 2pm:
The test run also helped iron out the fact that the content filter was still enabled on the SIM, but that was easily resolved.
Up next, vaguely automatic failover.
(I wrote this up for an internal work post, but I figure it s worth sharing more publicly too.)
I spent last week at
As is traditional for the UK August Bank Holiday weekend I made my way to Cambridge for the Debian UK BBQ. As was pointed out we ve been doing this for more than 20 years now, and it s always good to catch up with old friends and meet new folk.
Thanks to