GoAccess for Caddy

My current web server setup kinda grew based on my WordPress setup years back. Due to Ansible, I can redeploy it quickly but, in reality, it’s just a bunch of stuff thrown together because I needed it at one time or other. Add to that me running multiple websites on the same server and you have a bit of a mess. First step to cut through all that mess was placing it all behind load balancer running behind docker.

I won’t go too deep into why exactly I opted for Caddy. I suspect nginx would do nicely. Even Apache might have worked as well. But, after a bit of testing and playing with CertBot integration, I decided Caddy was best match for me.

The next step was to ensure I have some visibility into what was going on and there I found GoAccess. But guides I found didn’t really work. Some had issues with log format, some had issues with web sockets, some even had issues with syntax.

After a bit of twiddling, I ended up with the following compose.yaml.

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
    ports:
      - 80:80
      - 443:443
      - 443:443/udp
    volumes:
      - ./config/:/etc/caddy/
      - ./logs/:/var/log/caddy/
      - ./stats/:/var/www/goaccess/:ro

  stats:
    image: allinurl/goaccess:latest
    container_name: stats
    volumes:
      - ./logs/:/var/log/caddy/:ro
      - ./stats/:/var/www/goaccess/
    ports:
      - 7890:7890
    command: "/var/log/caddy/access.log --log-format=CADDY -o /var/www/goaccess/index.html --real-time-html --ws-url=wss://stats.example.com:443/ws --port=7890"

Caddy setup is quite straight-forward. It will use three volumes: one for config, one for output logs, and the last one for viewing stats (read-only).

Stats themselves are setup similarly too, this time with only two volumes needed. Logs are read from logs (read-only) and the web pages are written into stats. Command being ran is one allowing for real-time monitoring. And that requires websocket support.

Caddy configuration would look something like this:

example.com {
    log {
        output file /var/log/caddy/access.log
        format json
    }
    respond "Hello World!"
}

stats.example.com {
    root * /var/www/goaccess
    file_server
    reverse_proxy /ws stats:7890
}

And this setup will allow you to see stats as they come.

In-Wall Doorbell Transformer

Illustration

One really puzzling thing to me is how undefined location and mounting of doorbell transformer is in US dwellings. Not only that it has no specificed location but they also have no real mounting specification. Yes, it is specified in NEC they must be separated from high-voltage wires, but other than that is a free-for-all. I’ve seen 1/2" hole, wall box edge screw, and free-style two-screw mounting as most common examples, but you really cannot know for sure until you open it.

For example, my transformer has a nice plate mounting for a square edge mount but the transformer itself is not mounted in. Assuming it was ever mounted properly, by the virtue of sticking out, it was eventually dislodged. And don’t let me even start about low-voltage wires just entering drywall willy-nilly.

Since I wanted to upgrade transformer anyhow, I decided to clean this up. But surprisingly, there are still no real solutions for this. Almost everything I found assumes this transformer is either hanging of the wall or hanging in the wall. It took me a while but I think I found reasonable solution for my use case.

First of all, I wanted it all enclosed in the box. Since NEC forbids high-voltage (110V in this case) wires next to low-voltage ones, I needed one box with multiple compartments. Southwire MSBMMT3G 3-gang box is a rare one that fits my needs. AC side was not actually the problem but most of other dual voltage boxes had 1-gang for high-voltage and 1-gang for low-voltage side. This wouldn’t do in my case since my transformer was bigger than a single “gang” width and I really wanted it fully enclosed as to avoid “fell into the wall” accidents. It’s not ideal mind you since wire-clamps get in the way but it was best I’ve found.

Next task was selection of transformer. My existing one was 16 V so I opted to go with the same. Due to doorbell, I needed a rating of at least 30VA and that finally drove me toward Maxdot 16V 30VA. It has 1/2" hole mounting and it fits into my selected box with a bit of space to spare.

Since I had a 3D printer and voltage monitor display, my thoughts immediately went toward making a custom cover. One of more annoying steps needed to troubleshoot failing transformer is measuring voltage and with a voltage monitor, that would be trivial. And it would look cool.

I went as far as designing the cover and printing it out before remembering the NEC rules. Any cover must also be UL listed and certified for purpose. PLA, being both easily malleable with increasing temperature and fairly flamable is definitely not fit for the purpose. Thus, I ended up with shattered dreams and a plain 3-gang cover.

Fixing MPV Playback from Samba Share

Running KDE is usually quite troublefree. However, on my new install I faced unusual problem. My photos and media on samba share simply would not open. I could see text files just fine. But no movie for me.

Interestingly, this behavior seemed limited to MPV and Haruna. Other media players seemed unaffected by whatever afflicted them. It took a bit of investigation but I traced the issue to the following line in their .desktop file:

X-KDE-Protocols=ftp,http,https,mms,rtmp,rtsp,sftp,smb,srt,rist,webdav,webdavs

While they both claim to understand samba protocol (smb), removing it from supported protocols actually solved the issue. It seems that my samba server was simply not to their liking. After doing a bit of investigation, I am still puzzled why exactly - especially since it works just fine on another computer. Some dependency is missing and, while finding it would be possible, it would also waste my time when I already have solution.

Just removing smb works like a charm:

sudo sed -i 's/,smb,/,/g' /usr/share/applications/mpv.desktop
sudo sed -i 's/,smb,/,/g' /usr/share/applications/org.kde.haruna.desktop

It’s a temporary fix but Kubuntu 26.04 is just around the corner anyhow.

ChSrt

Similar to the last year, this year I also took a bit of break from writing here. A bit of family time here and there is not a bad thing. :)

But that doesn’t mean I stopped playing with computers altogether. In addition to updates to applications I already maintain, I also had some time for personal projects. And I decided to share one of those personal projects here - just in case somebody finds it useful.

As somebody who edits subtitles from time to time, I really love Subtitle Editor. It’s a really powerful tool and it literally covers everything one might need around subtitles. However, while it works on Linux, it simply isn’t that nice to use from command line. Especially when one has simple subtitle needs.

So, I went to reinvent the wheel and called it ChSrt.

This is a really simple subtitle editor with a fraction of features that I most comonly needed. In general, I just call it with two arguments that perform all fixes in-place.

chsrt -ia *.srt

If interested, you can check it out. I will expand it as I need new features but it will always be driven by what I need.

Trace Console Output

One common behavior for Linux GUI applications when ran from console is to write log text directly there. It’s not really a mandatory feature but a lot of frameworks do it so it became de-facto standard. However, C# applications often don’t follow this principle. I will take Avalonia for example. While Avalonia itself will write log to console, user code will not.

If you are using some logging framework (e.g. Serilog), this is trivial to configure. But, what about simple applications? Can we do something there?

Well, you can always add a console listener.

#if DEBUG
  if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) {
    Trace.Listeners.Add(new ConsoleTraceListener());
  }
#endif

With this, any Trace.WriteLine will write its output to console in addition to other trace listeners.

Why only on Linux? Well, under Windows there is a nice DebugView utility that can capture this information without going through console listener.