Sometimes I write hacks. Here’s a place for them, along with commentary. This is the September 6, 2025 edition.

Why?

I feel like I write a lot of useful but difficult-to-place snippets, and I don’t feel very good about padding out my blog with single snippets. It just doesn’t feel right to me. I know some people make “experimental” repos, but it feels, in some way, Too Formal to put it in Git, rather than just dumping them to my blog.

Real working Quadlets I use in production

There are so few in-the-wild Quadlets out there on the Web, and what few are available are poorly-documented. Let me provide two worked examples.

bgutil Proof-of-Origin Token server (for yt-dlp reasons)

Full details are at yt-dlp’s wiki, but the short of it is that YouTube now sometimes wants PO tokens to make your traffic look less bot-like.

/etc/containers/systemd/bgutil-ytdlp-pot-provider.container
[Unit]
Description=yt-dlp POT provider

[Container]
# Fully-qualified to allow AutoUpdate=registry to work.
Image=docker.io/brainicism/bgutil-ytdlp-pot-provider
AutoUpdate=registry

RunInit=true
# This might not be common knowledge;
# podman-run(1) has the details,
# but you can restrict the IP the container binds to.
# This one means
# "bind only to localhost on port 4416 inside and outside the container".
PublishPort=127.0.0.1:4416:4416

[Install]
WantedBy=default.target

Raspberry Flavoured Minecraft server

While this one is for Raspberry Flavoured, I expect it to be generalizable. Refer to the docs for more env vars.

/etc/containers/systemd/raspberry-flavoured.container
[Unit]
Description=Raspberry Flavoured Minecraft server

# There's a good chance the service will fail on boot without this;
# Java servers don't seem to be able to cope with "oops, no network!".
After=network-online.service

[Container]
# Fully-qualified to allow AutoUpdate=registry to work.
Image=docker.io/itzg/minecraft-server:latest
AutoUpdate=registry

Environment=EULA=TRUE

# I'm told this is a reasonable starting point.
Environment=MEMORY=4096M

Environment=SIMULATION_DISTANCE=16
Environment=VIEW_DISTANCE=16

# You *must* match these to the modpack in use,
# otherwise it'll default to vanilla, latest.
Environment=TYPE=FORGE
Environment=VERSION=1.19.2
Environment=FORGE_VERSION=43.4.12

# CurseForge requires you to have an API key,
# which is annoying.
# I believe PackWiz and Modrinith are easiest to work with.
# See https://docker-minecraft-server.readthedocs.io/en/latest/mods-and-plugins/
# for details.
Environment=PACKWIZ_URL=https://asphodel.cc/packwiz/Ports/Curse/Raspberry-Server/pack.toml

# I admit no knowledge about the quality of these flags...
Environment=USE_MEOWICE_FLAGS=true

# ...but I can reasonably vouch for lz4.
# zlib (the default) is obsolete.
# It was made for systems with
# *far* less memory than the systems of today,
# and is thus limited by that constraint
# in other, more currently relevant aspects,
# such as compression ratio and compression/decompression speed.
Environment=REGION_FILE_COMPRESSION=lz4

# Change this if you want, my setup is exposed over public IPv6,
# so the application itself needs to be secured in some way.
# An auth mod would do you fine here, but this one's built-in.
# Make sure to write an ops.json and whitelist.json,
# or you'll be locked out of your own server!
Environment=ENABLE_WHITELIST=true

# You'll need this to actually make the server accessible.
# Change these if you run on a different port.
PublishPort=25565:25565

# This is more-or-less arbitrary, right, but
# it's preferable to keep it consistent.
# My layout is as follows:
# /srv/minecraft/<packname> is where a specific server's data folder is,
# /var/minecraft-backups is for backups.
#
# You might need to add :z or :Z to the end of this for SELinux systems.
# I didn't do my testing with an SELinux-enabled system.
Volume=/srv/minecraft/raspberry:/data

[Service]
# I'm setting OnFailure here so that a /stop command
# issued from within the server doesn't cause the service to restart.
# I think that's how it works, anyway.
Restart=OnFailure

[Install]
WantedBy=default.target

One possible backup service

I don’t suggest you do this.

I don’t know whether this correctly syncs the state of the server before it does a backup. I’ve placed a sleep 30 in there to be reasonably sure, but any kind of fixed delay for disk sync is sketchy business.

This is a lesser problem, but I’ve been told systemd maintainers would be very displeased with my work. Ah, well, is it good art if it doesn’t make people feel?

/etc/systemd/system/backup-raspberry.service
[Unit]
Description=Back up Raspberry Flavoured MC server

# Conflicts= is used here so that raspberry-flavoured.service
# is brought down when this service starts back up.
Conflicts=raspberry-flavoured.service

[Service]
# chdir here so that the tar command there
# produces an archive with paths starting in
#   raspberry/
# instead of
#   /srv/minecraft/raspberry/
# I know you can do -C on... most tar impls, but this came to mind first.
WorkingDirectory=/srv/minecraft

# Extremely sketchy fixed delay to let the Minecraft server wind down.
# Strongly consider replacing.
ExecStartPre=sleep 30
ExecStartPre=sync

# ! choice of compressor !
#
# It kinda doesn't matter, given that most of
# a data folder's size is incompressible,
# but I think it's worth giving it a light tap;
# 75% of original size isn't *much* but it's *something*.
# I like zstd here because it produces decent ratios while
# also being reasonably fast to decompress.
#
# ! date !
#
# That date format is just date -Iminutes with the
# timezone replaced with the letter "Z" to mean UTC.
# This is ISO 8601 compliant, but GNU date prints "+00:00" instead.
#
# ! templating thoughts !
# I suspect it's possible to template this with a bit more finagling.
ExecStart=/usr/bin/bash -c 'tar -I "zstd -3 -T0" -cf /var/minecraft-backups/raspberry-"$(date --utc +%Y-%m-%dT%H:%MZ)".tar.zst raspberry; sync'

# I'd like the server to be brought back up once the backup is done.
# This is sketchy, but it does work.
# I'd like to see a future Interrupts= key that encodes both
# "stop this service" and "start it back up on exit".
ExecStopPost=systemctl start raspberry-flavoured.service

I don’t use a timer service because I’m the only player on my server, so I trigger backups manually. A timer service should be trivial to get up and running.

Stop a headless laptop-server from sleeping with the lid closed (systemd)

There are some weird answers to this problem floating around.

  • Masking the sleep, suspend, hibernate, and hybrid-sleep services entirely. (makes logind hog a whole CPU core and produce huge amounts of log spam)

  • Disabling ACPI entirely in kernel cmdline by passing acpi=off. (ACPI does other things too!!)

  • Unbinding the lid switch entirely via sysfs. (Huh?!)

So, here, the correct solution.

/etc/systemd/logind.conf
[login]
# (...)
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
HandleLidSwitchDocked=ignore

Getting DuckDNS to do only IPv6

I didn’t want to set up port-forwarding, and UPnP on my router is flaky.

First, clear any existing records. You don’t want a useless A (IPv4) record to confuse your users.

/usr/local/bin/duckdns-clear.sh
#!/usr/bin/env sh
token=FILL_THIS_IN
domain=FILL_THIS_IN
echo url="https://www.duckdns.org/update?domains=${domain}&token=${token}&clear=true" | curl -K -

Then, we need two parts. First is the script that does a single update. This part is general to any init system.

/usr/local/bin/duckdns-update-v6.sh
#!/usr/bin/env sh
# Any number of these v6 IP detection websites is fine.
# I could probably hack together an ip invocation, but I couldn't be assed.
ipv6addr=$(curl -6 https://ifconfig.co)
token=FILL_THIS_IN
domain=FILL_THIS_IN
echo url="https://www.duckdns.org/update?domains=${domain}&token=${token}&ipv6=${ipv6addr}" | curl -K -

And then the systemd service and timer units.

/etc/systemd/system/duckdns.service
[Unit]
Description=Update DuckDNS (v6 only)

[Service]
Type=oneshot
ExecStart=/usr/local/bin/duckdns-update-v6.sh
/etc/systemd/system/duckdns.timer
[Unit]
Description=Update DuckDNS entries periodically
After=network-online.service

[Timer]
OnBootSec=15s

# Adjust this to taste.
# My v6 addresses expire every 5 minutes,
# so I set the refresh interval to 4 minutes.
OnUnitActiveSec=240s
AccuracySec=15s

[Install]
WantedBy=timers.target

As usual, systemctl daemon-reload after installing these files.

A Gentoo env file that got 32-bit x86 FFmpeg building with glibc/Clang/ThinLTO

For reference, this was done on a 64-bit x86_64 Gentoo system that typically uses glibc and GCC. I just wanted FFmpeg built with LTO for funsies, but I also enabled ABI_X86="64 32" system-wide for ease of admin. This meant that I had to build x86 FFmpeg as well.

Credit goes to GitHub project InBetweenNames/gentooLTO issue #354, Build ffmpeg with -ffat-lto-objects for -ffat-lto-objects. I should probably take this up with upstream, but I’m not sure how to approach the question.

The rest of this is ripped from the Gentoo Wiki article for LTO.

/etc/portage/env/clang-ffmpeg.conf
WARNING_FLAGS="-Werror=odr -Werror=strict-aliasing"

# -ffat-lto-objects seems to be the winner here.
COMMON_FLAGS="${COMMON_FLAGS} -flto=thin -ffat-lto-objects ${WARNING_FLAGS}"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"
LDFLAGS="${COMMON_FLAGS} ${LDFLAGS}"

CC="clang"
CXX="clang++"
CPP="clang-cpp"
AR="llvm-ar"
NM="llvm-nm"
RANLIB="llvm-ranlib"

USE="lto"

Manual full → tv levels mapping (in case FFmpeg doesn’t like you)

yuvj420p (and other “j” pixel formats) are full-level pixel formats. Normally FFmpeg can convert them just fine, but in the case of yuvj420pyuv420p10le conversion (as you might do for AV1 encoding), it simply makes no attempt to do level conversions; it assumes that the video is already using tv levels.

Here’s a filtergraph statement that’ll simply force the matter, though I’d imagine there’s probably some precision loss or something.

# to convert [16, 235] to [0, 255]:
# subtract by 16 to get [0, 219]
# multiply by 255/219 to get [0, 255]
# clip values between [0, 255] for good measure.
geq=lum='clip((p(X, Y) - 16) * 1.164383562, 0, 255)':cb='clip((p(X, Y) - 16) * 1.164383562, 0, 255)':cr='clip((p(X, Y) - 16) * 1.164383562, 0, 255)'

You may also want to detect the pixel format before doing this, as it clearly wouldn’t make sense for tv-level content to be subjected to this.

pix_fmt="$(ffprobe -v error -of default=noprint_wrappers=1:nokey=1 -show_entries 'stream=pix_fmt' -select_streams V:0 "${input}")"