TIL: Looking up a VM's private IP in Hetzner

I recently had to look up my Hetzner VM's IP in a private network I'd set up from inside a Docker container. My initial set up was a bit clunky passing the host IP addresses during deployment but there's an easy way to look…

Elixir clustering on a Kamal+Hetzner deployment

I've been experimenting with Kamal for deploying an Elixir application. The application was previously deployed on Fly.io and relies on the Erlang VM's clustering capabilities, so I had to get this working on the Hetzner deployment I'd spun up using Kamal. It took…

TIL: Configuring multiple FLAME backends

In OctoCut, I have to perform a few tasks that are CPU or memory intensive. Instead of performing them on the machine serving web requests, I want to perform them on a different machine. FLAME is perfect for this. (If you're not familiar with FLAME, I highly recommend…

TIL: LiveView toast after async work

In a Phoenix Liveview app, I recently had to do some work in an assign_async(export a video). In terms of UI, I wanted to: * show a toast(or flash message) at the beginning indicating the work has started. * show toast once the work is completed, or if it…

Membrane S3 sink

The membrane_s3_plugin(as of version 0.1.2) has gotten outdated with changes in membrane_core. Here's an S3 sink implementation that works with the latest Membrane: defmodule Membrane.S3.Sink do @moduledoc """ Element that uploads incoming buffers to an S3 bucket. Pipeline…

[Video] Testing Google Gemini Audio Capabilities

Gemini with audio Video Code Mix.install([ {:req, "~> 0.4.14"}, {:kino, "~> 0.12.0"} ]) Form form = Kino.Control.form( [ prompt: Kino.Input.textarea("Prompt"), audio: Kino.Input.audio("Audio", format: :wav) ], submit: "Submit" ) frame = Kino.Frame.new(…