Serving a HLS Webcam Stream With Raspberry Pi Source

We already know how to stream from you Raspberry Pi. But where should we stream to? If you want to distribute the stream or make it available on the internet, serving it from a server is an option that also gives you a lot of flexibility when it comes to post processing. The Raspberry Pi doesn’t have much processing power and if you want to do something fancy, chances are it won’t work on a Pi.

In this article we set up a Raspberry Pi to stream to a server somewhere on the internet which then sharpens the stream, adds a logo on top and makes it available on a minimal webpage.

There is also a demo webcam showing the Turmberg in Karlsruhe, Germany:

Read More

SOGo: Your Mail Server Frontend/Groupware

After setting up a Postfix and Dovecot Server and securing it with Rspamd and ClamAV we are still lacking a nice web interface to send and receive mail with. This is where SOGo comes in.
SOGo is a fully fledged groupware server providing a mail client, calendar, address book, CalDAV, CardDAV, Microsoft ActiveSync and more. There are freely available nightly builds of SOGo which we will use with our SOGo Docker Image to create a groupware server on

In this article we discuss the necessary configuration to set up SOGo and provide Ansible roles for SOGo and some other services not yet covered in other articles.


We assume that you have a host that is accessible via Ansible and that you are running Traefik as well as the internal Docker network described in the Traefik article. We will outsource our user database to an Apache LDAP Server. You can of course use another LDAP server. Make sure to adapt the SOGo LDAP configuration. You also need a SMTP and IMAP server like the Postfix and Dovecot Server from a previous article. Spam and virus filtering is not required for this article, but highly recommended.
We will not target full Unicode compliance with our setup to keep it simple. There is a guide in the SOGo docs on how to make SOGo Unicode compliant. We will mention it a few times where applicable.

Read More

How to Build a SOGo Docker Image

SOGo is a fully fledged groupware server providing a mail client, calendar, address book, CalDAV, CardDAV, Microsoft ActiveSync and more. Despite its feature set there is no official Docker image yet. So let’s create one for ourselves.

SOGo uses Apache to serve the web frontend. We run SOGo and Apache toghther in one Docker container so Apache can easily use the SOGO static files. To start both processes in one Docker container we use supervisord as suggested in the Docker wiki. Both processes run on their own user.

We use the SOGo nightly builds as one needs a paid support contract to get access to the stable releases.

SOGo Dockerfile

SOGo lists several compatible Linux Distributions from which we choose Ubuntu 20.04 as a base for the Docker image. We then roughly follow the SOGo software installation guide and their FAQ entry on how to install nightly SOGo on Ubuntu.

FROM ubuntu:20.04

# Update all packages and install the apt tools to install the rest
RUN apt update && \
apt upgrade -y && \
apt install -y gnupg2 apt-utils ca-certificates apt-transport-https

# Add the PGP Key of SOGo
RUN wget -O- "" | gpg --dearmor | apt-key add -

# Download SOGO from this repo:
COPY SOGo.list /etc/apt/sources.list.d/SOGo.list

# Update apt cache and install SOGo
RUN apt update && \
# Switch to non-interactive install
export DEBIAN_FRONTEND=noninteractive && \
# Do the time zone settings beforehand so we don't get promted for it during install (pick your timezone)
echo "tzdata tzdata/Areas select Europe" | debconf-set-selections && \
echo "tzdata tzdata/Zones/Europe select Berlin" | debconf-set-selections && \
echo "tzdata tzdata/Zones/Etc select UTC" | debconf-set-selections && \
# For some reason SOGo wants this file to be present
mkdir -p /usr/share/doc/sogo/ && touch /usr/share/doc/sogo/ && \
# Install the actual services needed
apt install -y --no-install-recommends apache2 sogo supervisor gosu && \
# Prepare non-privileged file permissions for SOGo
chown sogo /etc/sogo/sogo.conf && \
mkdir -p /var/run/sogo && chown sogo /var/run/sogo && \
# Apache also runs on a non-privileged user
mkdir -p /var/run/apache2 && chown www-data /var/run/apache2 && \
# Activate the necessary Apache mods and disable the default site
a2enmod proxy headers proxy_http rewrite && \
a2dissite 000-default && \
# Verify that gosu works
gosu nobody true

# This file is explained below
COPY supervisord/supervisord.conf /etc/supervisord/supervisord.conf

# Supervisord will start Apache and SOGo
CMD exec /usr/bin/supervisord -c /etc/supervisord/supervisord.conf

Read More

Raspi Camera Module v3 vs HQ Camera

After the positive initial impressions on the Raspi Camera Module 3 the question now is how it stacks up against alternative camera modules. Obviously it will be better than the old camera modules 1 and 2 but what about the HQ Camera module that also got a slight feature bump at the same time as the camera module 3 was released?

Camera Module and Lens Specifications

The Camera Module 3 has a fixed autofocus lens. The HQ Camera Module comes with a C/CS lens mount but no lens. For this comparison we have the 6mm CCTV lens and the Pentax Cosmicar 8.5mm CCTV lens. The MSRP of the Camera Module 3 is $25 and for the HQ Camera Module it’s $50. Prices on the HQ Camera Lenses will vary and we have two cheaper variants for this test.
Unfortunately there are no equal focal lengths for the two sensors. The 28mm equivalent of the Camera Module 3 is common on smartphones while the 33mm equivalent of the 6mm lens the HQ Camera Module is a moderate wide angle and the 47mm equivalent of the Pentax 8.5mm a standard lens.

Camera Module 3 HQ Cam & CCTV HQ Cam & Pentax
Resolution 11.9 MPix 12.3 MPix 12.3 MPix
Pixel Size 1.4 µm x 1.4 µm 1.55 µm x 1.55 µm 1.55 µm x 1.55 µm
Sensor Sony IMX708 Sony IMX477 Sony IMX477
Stills Resolution 4608 x 2592 pixels 4056x3040 pixels 4056x3040 pixels
Video Modes 2304×1296p56,
2304×1296p30 HDR,
2028×1520p40 and
2028×1520p40 and
Sensor Size 1/2.43” 1/2.3” 1/2.3”
Focus Auto Manual Manual
Focal Length 2.75mm 6mm 8.5mm
Focal Length (35mm equiv.) 28mm 33mm 47mm
Max. Apterture f/1.8 f/1.2 f/1.5
Camera Modules and Lenses Used

For the test setup we use libcamera-still with everything on auto for still images and libcamera-vid for videos, also everything on auto except the time to record, which is 10 sec.

Camera Module 3 vs HQ Camera Module

Looking at the Camera Module 3 and HQ Camera Module images sidy by side the first thing we notice is the different aspect ratio between the sensors. The Camera Module 3 has a 16:9 aspect ratio, while the HQ Camera Modules 4:3 aspect ratio is more commonly found in stills photography. Also, the focal lengths are quite different making us “zoom in” on the test frame while going through the pictures.

When it comes to image quality the Camera Module 3 not only seems to have the sharpest but also the most consistent lens in the field. The image is still sharp on the edges of the frame and there is no noticeable barrel distortion. Quite in contrast the 6mm lens. Despite beeing stopped down, the image is only sharp in the very center. Also a pronounced barrel distortion is noticeable. The Pentax 8.5mm is a little better in that regard but is also only really sharp in the center despite beeing stopped down to f/5.6.
The Camera Module 3 on auto takes a warmer approach to the overall colour of the image while the images from the HQ Camera Module have a cooler, bluer tone.

Read More

Dockerized Spam Filtering With Rspamd

If you are running a basic mailserver either from my guide on running a dockerized mailserver or some setup of your own you will soon be bombarded with spam messages.

In this post we explore a solution based on a dockerized instance of the mail filter system Rspamd. Our Postfix (or your MTA of choice) will use a milter, a mail filter, to send all incoming mail to Rspamd. Rspamd then scans the mail for spam and viruses. When Rspamd is confident enough that the mail in question is spam or contains a virus it will signal Postfix to reject the mail before passing it on. If Rspamd is not sure that the mail should be rejected but suspects the mail is spam it will attach a header to the mail indicating that the mail is spam. When the mail storage like the IMAP server Dovecot later receives the mail it can decide based on the spam header to move the mail into the spam folder so it won’t be lost immediately. Actual mail from other persons (ham) is not modified.

Read More

Raspberry Pi Camera Module 3 First Impressions

A few days ago on Jan 9, 2023 the Raspberry Pi Ltd. announced the Raspberry Pi Camera Module 3 and I was fortunate enough to get one of the last available in german online stores. So this is my first impressions review with some images that I captured. I got the standard Camera Module 3 with 66 deg angle of view and IR filter.

Read More

How to Build a Rspamd Docker Image

Rspamd is a powerful and free spam filtering system. Unfortunately, there is no official Docker image available so let’s build one for ourselves.

If you only want rspamd to run in a container the Dockerfile is very simple: Just install the rspamd packages and set the command to /usr/sbin/rspamd -f. But rspamd can also expose a minimal web interface with statistics, logs and the ability to manually submit ham and spam. Of course we want that, too.
We use nginx to serve the necessary style sheets and icons for the rspamd web interface. These are included in the rspamd package. To make things easier we run both rspamd and nginx in the same docker container. We start them both at the same time using supervisord, one of the methods recommended by the Docker docs.

So this is our Dockerfile: it installs the necessary packages, copies the supervisord config and nginx config and starts supervisord.

FROM alpine:3.17

RUN apk update && \
apk add rspamd rspamd-proxy rspamd-utils rspamd-controller supervisor nginx && \
rm -rf /var/cache/apk/*

COPY supervisord/supervisord.conf /etc/supervisord/supervisord.conf
COPY nginx/nginx.conf /etc/nginx/nginx.conf
COPY rspamd/local.d/ /etc/rspamd/local.d/

EXPOSE 11332/tcp
EXPOSE 80/tcp

CMD exec /usr/bin/supervisord -c /etc/supervisord/supervisord.conf

We let nginx pick the static files from the rspamd package location and proxy the http requests to rspamd itself. Output goes to /dev/stdout to populate the Docker logs.

worker_processes  2;
user nginx nginx;

pid /var/run/;

error_log /dev/stdout info;

events {
worker_connections 8192;
use epoll;

http {
include mime.types;
default_type text/plain;

sendfile on;
tcp_nopush on;
tcp_nodelay on;

gzip on;

server {
access_log /dev/stdout;

location / {
alias /usr/share/rspamd/www/;
try_files $uri @proxy;
location @proxy {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
server_tokens off;

We let rspamd also log to the console.

type = console
level = "notice";

Supervisord has the ability to start multiple processes but stay in foreground itself which is very convenient in docker containers as the main command stays alive. We use it to start rspamd and nginx, again, in foreground. Rspamd has a switch for that, nginx needs an additional option string.


command=/usr/sbin/rspamd -f -u rspamd -g rspamd

command=/usr/sbin/nginx -g 'daemon off;'

Build your image like this:

docker build -t dovecot: .

And that’s it. Build your image from the recipe above or just take my prebuilt Rspamd Docker image.

Read More

A Dockerized Self Hosted Mail Server With Postfix And Dovecot

Wether you want to have control over your own mails, not share data with an unknown 3rd party, not pay for several accounts when you could just pay for one server or you just wanna waste some time with another project: there are a lot of reasons to run your own mail server. But actually setting up a mail server that works can be tricky.

In this article we explore how to set up a self hosted mail server that can serve multiple mail domains on the internet. We run all applications like the required mail transfer agent (MTA) and IMAP server on one machine. The users we want to receive mails for and send mails from don’t have an account on that machine. Rather, we store their user data in a database that the other applications can access. We run the mail server processes in docker containers to make the setup more modular and get rid of the dependency to the underlying operating system and its library versions.
I already show how to create a docker image for the mail transfer agent (MTA) Postfix and IMAP Server Dovecot in other posts. We will not go through that information here as it would make this article too long and cluttered. The config settings in this article are geared towards these docker images but you can of course adapt them to fit other installations if you want to. For the sake of brevity there is no section on spam filtering or mail frontends. We will pick up these topics in future posts.
Also: This posts mostly focuses on the configuration aspect and less on the technical details of a mail server and the protocols it uses.

A word of advice: for your mail server to accept mail from other domains you have to expose it TO THE INTERNET. If you now think: well, that sounds like a dumb idea - it probably is. So take running a mail server seriously, do your updates and learn how to secure your server and data. Or to put it another way:

With that said: let’s create our mail server!

Read More

How to Build a Dovecot Docker Image

Another image I build for myself because I don’t want to use 3rd party non-official images from DockerHub. They could do anything with my precious emails. Also, building a docker image for dovecot is pretty straightforward.

The Dockerfile just has to install the Dovecot packages, expose the imap ports and start Dovecot:

FROM alpine:3.16

# You might not need the pigeonhole (sieve) plugin or the rspamd package
RUN apk update && \
apk add dovecot dovecot-ldap dovecot-lmtpd dovecot-pigeonhole-plugin rspamd-client && \
rm -rf /var/cache/apk/*
COPY config/conf.d/10-logging.conf /etc/dovecot/conf.d/10-logging.conf

EXPOSE 24/tcp
EXPOSE 143/tcp
EXPOSE 993/tcp

CMD /usr/sbin/dovecot -F

Dovecot will start in foreground, keeping the container alive. We want to check the logs via docker logs so we redirect all dovecot log output to stderr:

log_path = /dev/stderr

The Dockerfile will copy that config file to the image.

Start the build like this:

docker build -t dovecot: .

Done. Again, you can pick up my Dovecot image on DockerHub. But I guess if you read this article, you want to build your own image?

Also, check out my Postfix image.

Read More

How to Build a Postfix Docker Image

Update 2022-10-16: I added some details on logging and the postmap operations and image link.

Did you ever need a postfix docker image and the found out that there is no official image? Well, a lot of people did, so there are dozens if not hundreds of postfix images on DockerHub. But do you really want to use an image made by a complete stranger? After all, the image could do anything, or send your mails anywhere.

Well, I hat the same problem whilst preparing an upcoming post. I decided to create yet another image, but share the code so you can build one yourself. And actually, it’s super easy. Here is the dockerfile:

FROM alpine:3.16

# I need the ldap package, you might not
RUN apk update && \
apk add postfix postfix-ldap && \
rm -rf /var/cache/apk/*

EXPOSE 25/tcp
EXPOSE 465/tcp
EXPOSE 587/tcp

# You might need more or less map operations before startup
CMD postmap /etc/postfix/aliases && \
postmap /etc/postfix/roleaccount_exceptions && \
postmap /etc/postfix/virtual && \
/usr/sbin/postfix start-fg

I assume that you will also mount your config files into /etc/postfix. For us not to have to mount the compiled map files, I added the postmap commands. When the container starts it will update the maps you want and then start Postfix in foreground.

To redirect all postfix output to the console, add this to

maillog_file = /dev/stdout

That way you can access the output via docker logs. You might need an additional entry in the, but it should be already present. Look it up in the Postfix documentation.

Start the build like this:

docker build -t postfix:3.7.2-r0-1 .

And you are done. Or you can my Postfix docker image if you dare to. Also, check out my Dovecot image.

Read More