<?xml version="1.0" encoding="utf-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Roman Zipp</title>
<link href="https://romanzipp.com"></link>
<link href="https://romanzipp.com/rss" rel="self" type="application/atom+xml"></link>
<subtitle>Software Engineer &amp; Photographer</subtitle>
<logo>https://romanzipp.com/images/social/social-cover-01.jpg</logo>
<language>en_US</language>
<updated>2026-04-13T03:01:04+00:00</updated>
<pubDate>Mon, 01 Jan 2018 00:00:00 +0000</pubDate>
<id>urn:uuid:fb7bbc14-a1a3-c1c1-12ae-4dc1769d5e0a</id>
<entry>
<title>Fix Final Cut imported Titles and Transitions not available</title>
<link href="https://romanzipp.com/blog/fix-final-cut-imported-titles-and-transitions-not-available"></link>
<id>https://romanzipp.com/blog/fix-final-cut-imported-titles-and-transitions-not-available</id>
<summary type="html"><![CDATA[<p>Final Cut Pro allows you to import third party &quot;Templates&quot; like Titles, Generators and Transitions. I wanted to do exactly that and followed the Guide to put these files in <code>/Users/&lt;user&gt;/Movies/Motion Templates</code>  → <code>Titles</code>, <code>Transitions</code> and so on.</p><p>Little did I know and long did I debug: The folders are actually suffixed with <code>.localized</code> - but this is not visible in the finder as demonstrated in this example where the supposed same folder exists twice, but one actually ends in <code>.localized</code></p><h3>Solution</h3><p>Make sure the <code>Motion Templates</code> folder and all next subfolders end in <code>.localized</code></p><ul><li><p><code>/Users/&lt;user&gt;/Movies/Motion Templates.localized/Composting Elements.localized</code></p></li><li><p><code>/Users/&lt;user&gt;/Movies/Motion Templates.localized/Effects.localized</code></p></li><li><p><code>/Users/&lt;user&gt;/Movies/Motion Templates.localized/Generators.localized</code></p></li><li><p><code>/Users/&lt;user&gt;/Movies/Motion Templates.localized/Titles.localized</code></p></li><li><p><code>/Users/&lt;user&gt;/Movies/Motion Templates.localized/Transitions.localized</code></p></li></ul><p>Apple, why...</p>]]></summary>
<updated>2026-02-13T12:48:00+00:00</updated>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Fix macOS screens flickering/disconnecting with external Dock</title>
<link href="https://romanzipp.com/blog/fix-macos-screens-flickeringdisconnecting-with-external-dock"></link>
<id>https://romanzipp.com/blog/fix-macos-screens-flickeringdisconnecting-with-external-dock</id>
<summary type="html"><![CDATA[<p>Another day another macOS bug. This time on macOS Sequoia 15.7.4.</p><p>I just updated and found out that my external displays (1440p, 165hz) connected to my iVanky FusionDock Pro were constantly disconnecting and re-connecting again. But not long enough to debug within the System Settings what was going on. The whole UI froze.</p><p>I was digging around and remembered that my dock can only drive 3x 1440p 120hz - not 165hz. In previous macOS versions, this was no problem - I just went into the display settings, changed resolution and/or refresh rate and everything was fine.</p><p>In this update, the screens will get re-connected around every second.</p><h3>Solution</h3><p>Since the system settings UI is unusable and CLI is always more reliable: There is a tool called <a target="_blank" href="https://github.com/jakehilborn/displayplacer">displayreplacer</a> which allows you to define the layout, resolutions and more via a command.</p><p>Install via Homebrew: <code>brew install displayplacer</code></p><p>First, run <code>displayreplacer list</code> and you will be presented with a command that applies the currently configured state to your display config.</p><p>Such as:</p><p>In my case, all displays had <code>hz:165</code> configured which I could not change through the System Settings ui. So simply change it to <code>hz:120</code>, save the command in a shell file (e.g. <code>displays.sh</code>) and run it <code>sh displays.sh</code></p><p>The IDs are persistent and won&#039;t change, so you can even make multiple presets and apply them wherever you got a different set of external displays. At home vs. at work.</p>]]></summary>
<updated>2026-02-09T16:46:00+00:00</updated>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Forgejo Workflow: Checkout Action &quot;invalid reference&quot;</title>
<link href="https://romanzipp.com/blog/forgejo-checkout-issue"></link>
<id>https://romanzipp.com/blog/forgejo-checkout-issue</id>
<summary type="html"><![CDATA[<p>Again I&#039;ve encountered an issue with Forgejo runners: Pushing a commit for a workflow that uses re-usable workflows results in the following error:</p><h3>Solution!</h3><p>Update Forgejo Runner to <code>v12.5.3</code>, where <a target="_blank" href="https://code.forgejo.org/forgejo/runner/pulls/1293">this PR is included</a>.</p><h3>Temporary Workaround</h3><p>The only possible solution fixing this bug is deleting the runners cache.</p><h3>Steps taken</h3><ul><li><p>Using every single version and variations of <code>actions/checkout@v6</code>  / <code>https://github.com/actions/checkout@v6</code> </p></li><li><p>Using <code>with.clean = true</code> or <code>with.fetch-depth = 0</code></p></li><li><p>Passing current <code>ref</code> to checkout action</p></li></ul>]]></summary>
<updated>2026-01-20T05:15:00+00:00</updated>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Fix Forgejo Workflow stuck on &quot;Waiting&quot;</title>
<link href="https://romanzipp.com/blog/fix-forgejo-workflow-stuck-on-waiting"></link>
<id>https://romanzipp.com/blog/fix-forgejo-workflow-stuck-on-waiting</id>
<summary type="html"><![CDATA[<p>When using Forgejo with <a target="_blank" href="https://forgejo.org/docs/next/user/actions/reference/#jobsjob_iduses">reusable jobs</a>, it happened to me that a job is stuck on &quot;Waiting&quot; without being picked up by a runner.</p><p>The docs state:</p><blockquote><p>It is recommended that <code>jobs.&lt;job_id&gt;.runs-on</code> is omitted when using <code>uses</code>, as this will allow Forgejo to perform workflow expansion. Workflow expansion results in the target workflow’s jobs appearing in the UI as separate jobs. This provides an easier to understand experience for accessing the logs of each job, and permits the jobs to run on separate runners with their own <code>runs-on</code> fields.</p></blockquote><p><strong>Well, this doesn&#039;t work at all</strong>. Just add the <code>runs-on</code> field to the workflow reference. <a target="_blank" href="https://code.forgejo.org/forgejo/runner/issues/1316">I have reported this bug</a>.</p><h3>Before</h3><h3>After</h3>]]></summary>
<updated>2026-01-20T04:47:00+00:00</updated>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>MotoGP 2026: Generate iCal Calendar</title>
<link href="https://romanzipp.com/blog/motogp-2026-generate-ical-calendar"></link>
<id>https://romanzipp.com/blog/motogp-2026-generate-ical-calendar</id>
<summary type="html"><![CDATA[<p>As every year I&#039;m providing an iCal calendar which you can subscribe to with your Calendar app so you won&#039;t ever miss a race!</p><p>This year, it looks like MotoGP is also <a target="_blank" href="https://www.motogp.com/en/calendar?view=grid">providing their own calendar</a> (red button &quot;Sync calendar&quot;) through &quot;ECAL&quot; but you will have to give them your email address and agree to their ToS so I haven&#039;t tried it.</p><h2>MotoGP Season 2026</h2><p>This is a configurator where you can decide yourself, to which leagues or events you want to subscribe. The default choices are <strong>Qualifying and Races</strong> events for the <strong>MotoGP</strong> league.</p><p>Missing anything or have questions? Leave a <a href="#comments">comment</a>! </p><p><strong>Note</strong>: As of January 2nd only a couple of dates have been announced. New ones should appear automatically once they are published.</p><p><em>If you&#039;re reading this in your RSS reader, that&#039;s a good time to <a href="/blog/motogp-2026-generate-ical-calendar">head over to the website</a>.</em></p><h2>Import to Calendar App</h2><p>When you&#039;ve finished tinkering with the parameters above, copy the URL above and paste it to your favorite calendar client. You have the option to just download a .ics file and import it once or subscribe to the URL. I&#039;d recommend the second option since changed in the schedule will automatically update.</p><h3>iOS Calendar</h3><ol start="1"><li><p>Select from the bottom &quot;<strong>Calendars</strong>&quot;</p></li><li><p>In the bottom left corner select &quot;<strong>Add Calendar</strong>&quot;</p></li><li><p>Select &quot;<strong>Add Subscription Calendar</strong>&quot;</p></li><li><p>Paste the URL and hit &quot;<strong>Subscribe</strong>&quot;</p></li><li><p>Set a Title and select &quot;<strong>Add</strong>&quot;</p></li></ol><h3>macOS Calendar</h3><ol start="1"><li><p>In your Calendar app, select from the top menu &quot;<strong>File</strong>&quot; → &quot;<strong>New Calendar Subscription</strong>&quot;</p></li><li><p>Paste the URL and hit &quot;<strong>Subscribe</strong>&quot;</p></li><li><p>Choose a name, like &quot;<strong>MotoGP</strong>&quot; </p></li><li><p>Set &quot;<strong>Auto-refresh</strong>&quot; to &quot;<strong>Every day</strong>&quot;</p></li><li><p>Select &quot;<strong>OK</strong>&quot;</p></li></ol><h3>Google</h3><ol start="1"><li><p>Go to <a target="_blank" href="https://calendar.google.com">calendar.google.com</a> (in browser)</p></li><li><p>On the left sidebar, click the &quot;<strong>+</strong>&quot; next to &quot;<strong>Other calendars</strong>&quot;</p></li><li><p>Select &quot;<strong>Subscribe to calendar</strong>&quot;</p></li><li><p>On the left select &quot;<strong>From URL</strong>&quot;</p></li><li><p>Paste the iCal URL and git &quot;<strong>Add calendar</strong>&quot;</p></li></ol><p>Image source: motogp.com</p>]]></summary>
<updated>2026-01-02T08:55:00+00:00</updated>
<link length="499971" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/motogp-2026-generate-ical-calendar-1/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>What&#039;s in my HomeLab: 2026</title>
<link href="https://romanzipp.com/blog/whats-in-my-homelab-2026"></link>
<id>https://romanzipp.com/blog/whats-in-my-homelab-2026</id>
<summary type="html"><![CDATA[<p>This is a complete – and <strong>long</strong> – list of all services and tools that are running on my HomeLab going into 2026.</p><h3>Tips</h3><p>Before you start deploying this list in your cluster, <strong>some tips upfront</strong> on how to manage your services. More about that in detail in another blog post soon (subscribe to the <a target="_blank" href="https://romanzipp.com/rss">RSS feed</a>)</p><ul><li><p><strong>Use a real domain</strong> for your services (like <code>service.yourname.net</code>, point DNS to your server/cluster IP) which will allow you to run a cert-manager and issue valid Let&#039;s Encrypt SSL certificates. This will save you a lot of headaches.</p></li><li><p>If you want to <strong>access services remotely</strong> or share links to users without a VPN connection, setup a remote server that is only acting as a reverse proxy (like <a target="_blank" href="https://caddyserver.com/docs/quick-starts/reverse-proxy">Caddy</a>, with automated SSL certs) and only allow this specific IP to connect to your routers public IP via firewall rules.</p></li><li><p>Make your server/cluster deployment reproducable. Don&#039;t rely on fancy web UIs but rather configuration files. <strong>Document</strong> all changes and keep a <strong>single-source-of-truth</strong> configuration repository which can be instantly deployed.</p></li><li><p>Always deploy the docker images with a <strong>fixed version</strong> (eg. <code>henrygd/beszel-agent:0.17.0</code>) and manually update. You can monitor new image versions in <a target="_blank" href="https://github.com/glanceapp/glance/blob/main/docs/configuration.md#releases">Glance</a> or subscribe to Github releases with your RSS reader.</p></li><li><p>If you&#039;re using Kubernetes, apply <a target="_blank" href="https://kubernetes.io/docs/concepts/services-networking/network-policies/">Network Policies</a> to all deployments so than can only communicate to allow-listed IP spaces and services.</p></li></ul><h3>Outlook</h3><p>There&#039;s <strong>a lot</strong> I want to add in the coming year. Some of that includes:</p><ul><li><p><a target="_blank" href="https://smartgateways.nl/en/make-your-gas-meter-smart/">Smart meters</a> for my gas heating</p></li><li><p>Monitoring birds in my backyard via <a target="_blank" href="https://github.com/tphakala/birdnet-go">BirdNET</a></p></li><li><p>Self-hosting images via <a target="_blank" href="https://github.com/immich-app/immich">Immich</a> (thank&#039;s AI for those SSD prices)</p></li><li><p>Tracking flights with own receiver</p></li><li><p>Backup more things locally</p></li><li><p>Looking into making <a target="_blank" href="https://github.com/anyproto/anytype-ts">AnyType</a> and <a target="_blank" href="https://github.com/Someone0nEarth/excalidraw-self-hosted">Excalidraw</a> self-hostable</p></li><li><p>Add SSO via <a target="_blank" href="https://goauthentik.io/">authentik</a> or <a target="_blank" href="https://www.authelia.com/">Authelia</a></p></li></ul><p>The following list is separated into <strong>1. Tools</strong>, <strong>2. Monitoring</strong>, <strong>3. Media</strong> and <strong>4. Internal</strong>.</p><h2>1. Tools</h2><h3>Baikal: CalDAV / CardDAV</h3><p>I&#039;m self-hosting my calendar and contact data and found that <a target="_blank" href="https://github.com/sabre-io/Baikal">Baikal</a> works best for me</p><h3>BentoPDF</h3><p>If you have tummy aches when uploading somewhat sensitive document into a &quot;free online pdf tool converter&quot;, you should run your own instance of <a target="_blank" href="https://github.com/alam00000/bentopdf">BentoPDF</a> which provides many many features for editing PDFs.</p><p>Tip: Use the <code>bentopdf-simple</code> image so that the marking section, similar to the landing page, is hidden.</p><h3>ConvertX</h3><p>Pretty ugly but insanely powerfull. Convert anything to anything with <a target="_blank" href="https://github.com/C4illin/ConvertX">ConvertX</a>.</p><h3>FreshRSS</h3><p>You should start reading more news and blog posts. Great time to setup your own instance of <a target="_blank" href="https://github.com/FreshRSS/FreshRSS">FreshRSS</a> - an RSS aggregator with nice integration to NetNewsWire and many other clients.</p><h3>Gitea</h3><p>Maybe you don&#039;t need to upload anything to GitHub just so Microsoft can train their shit AI on it, so start hosting your own <a target="_blank" href="https://github.com/go-gitea/gitea">Gitea</a> instance, Helm chart included.</p><h3>Glance</h3><p>In my opinion the best HomeLab dashboard, customizable, pretty and feature-rich. Get <a target="_blank" href="https://github.com/glanceapp/glance">Glance</a>.</p><h3>Home Assistant</h3><p>This text only exists so I can link to <a target="_blank" href="https://github.com/home-assistant/core">Home Assistant</a> on GitHub - no introduction needed.</p><h3>iSponsorBlockTV</h3><p><a target="_blank" href="https://github.com/dmunozv04/iSponsorBlockTV">iSponsorBlockTV</a> integrates SponsorBlock with your smart TV - like Apple TV.</p><h3>Mermaid</h3><p>You can host your own <a target="_blank" href="https://github.com/mermaid-js/mermaid-live-editor">Mermaid Live editor</a>, no platform with saving, sharing and such but helpful if you&#039;re using Mermaid charts.</p><h3>MeTube</h3><p><a target="_blank" href="https://github.com/alexta69/metube">MeTube</a> is just a frontend for <code>yt-dlp</code> so I don&#039;t have to fight with annoying ads when sicherheitsspeichern YouTube videos.</p><h3>NocoDB</h3><p>A neat GUI database / spreadsheet-like web application, also good for collaboration: <a target="_blank" href="https://github.com/nocodb/nocodb">NocoDB</a>.</p><p><strong>Tip</strong>: Set env vars <code>NC_DISABLE_SUPPORT_CHAT</code> and <code>NC_DISABLE_TELE</code> to &quot;<code>false</code>&quot;.</p><h3>Owntracks</h3><p>Stop pumping your geolocation into your Google account and start using self-hosted <a target="_blank" href="https://github.com/owntracks/owntracks">Owntracks</a> with the <a target="_blank" href="https://github.com/owntracks/frontend">Owntracks frontend</a>.</p><p><strong>Tip</strong>: Take a look at the Owntracks frontend <a target="_blank" href="https://github.com/owntracks/frontend/blob/main/docs/config.md">configuration options</a> which can really enhance the look.</p><h3>Roundcube</h3><p>If you also have a lot of mailboxes, it&#039;s a great idea to host <a target="_blank" href="https://github.com/roundcube/roundcubemail">Roundcube</a> instead of syncing every single one of them with your mail client.</p><p><strong>Tip</strong>: Enable the included managesieve plugin with <code>$config[&#039;plugins&#039;] = [&#039;managesieve&#039;];</code> to allow editing mail rules directly in Roundcube.</p><h3>Slink</h3><p>A self-hosted image sharing platform for quickly sharing images: <a target="_blank" href="https://github.com/andrii-kryvoviaz/slink">Slink</a>.</p><h3>Traccar</h3><p>Similar to Owntracks but <a target="_blank" href="https://github.com/traccar/traccar">Traccar</a> more optimized for tracking vehicles and collaborating with multiple users and clients.</p><h2>2. Monitoring</h2><h3>Beszel</h3><p><a target="_blank" href="https://github.com/henrygd/beszel">Beszel</a> is great for getting an overview about CPU and memory with multiples machines.</p><h3>Grafana</h3><p>You should already know <a target="_blank" href="https://github.com/grafana/grafana">Grafana</a>, a data visualization tool.</p><h3>Kuvasz</h3><p>You can monitoring many many websites for uptime &amp; SSL validity with <a target="_blank" href="https://github.com/kuvasz-uptime/kuvasz">Kuvasz</a>.</p><h3>Prometheus</h3><p>Can&#039;t use Grafana without <a target="_blank" href="https://github.com/prometheus/prometheus">Prometheus</a> - can you?</p><h3>Speedtest Tracker</h3><p>Pretty okay-ish Speedtest monitoring with <a target="_blank" href="https://github.com/alexjustesen/speedtest-tracker">Speedtest Tracker</a>. It&#039;s running Ookla so be aware that all results are being logged by them.</p><h2>3. Media</h2><h3>Jellyfin</h3><p><a href="https://github.com/jellyfin/jellyfin">Jellyfin</a> provides media management and video players for your movies and TV shows.</p><h3>Prowlarr</h3><p>If you know you know, &quot;RSS aggregator&quot; for Linux ISOs with <a target="_blank" href="https://github.com/Prowlarr/Prowlarr">Prowlarr</a>.</p><h3>qBittorrent</h3><p>Can&#039;t boot Linux without an ISO, so share and care with <a target="_blank" href="https://github.com/qbittorrent/qBittorrent">qBittorrent</a>.</p><h3>Radarr</h3><p><a target="_blank" href="https://github.com/Radarr/Radarr">Radarr</a> is a movie organizer/manager for usenet and torrent users.</p><h3>Sonarr</h3><p><a target="_blank" href="https://github.com/Sonarr/Sonarr">Sonarr</a> is a smart PVR for newsgroup and bittorrent users.</p><h3>Seerr</h3><p>If you have multiple normie users watching movies on your Jellyfin, they can also request new media via <a target="_blank" href="https://github.com/seerr-team/seerr">Seer</a> (formerly Jellyseer)</p><h2>4. Internal</h2><h3>DDNS Updater</h3><p>A lightweight universal <a target="_blank" href="https://github.com/qdm12/ddns-updater">DDNS Updater</a> written in Go with a small but helpful web UI.</p><h3>Gitea Mirror</h3><p>In case GitHub get&#039;s flöten or Microsoft or their rogue AI deletes your GitHub account, setup a mirroring for your repositories with <a target="_blank" href="https://github.com/RayLabsHQ/gitea-mirror">Gitea mirror</a>.</p><h2>5. Backup</h2><h3>Biochon</h3><p><a target="_blank" href="https://github.com/rustmailer/bichon">Biochon</a> can pull your mails via IMAP - but has no restore/export functionality yet. Looks really good and is in active development.</p>]]></summary>
<updated>2025-12-29T00:39:00+00:00</updated>
<link length="543187" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/whats-in-my-homelab-2026/cover-2.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Stalwart: Import Mails</title>
<link href="https://romanzipp.com/blog/stalwart-migrate-mailboxes"></link>
<id>https://romanzipp.com/blog/stalwart-migrate-mailboxes</id>
<summary type="html"><![CDATA[<p>So you want to move your existing mailboxes from a previous mail provider to Stalwart. You have two options:</p><ol start="1"><li><p>Create a backup and upload it to Stalwart → Use <code>imap-backup</code> then the <code>stalwart-cli</code> to import it</p></li><li><p>Migrate your mails directly from server to server via <code>imapsync</code></p></li></ol><p><strong>My recommendation</strong>: Create a backup - leave it as it is - and then use <code>imapsync</code></p><h2>1. Create a Backup</h2><p>We want to make sure that all changes can be reverted in case anything fails catastrophically.</p><h3>macOS Apple Mail</h3><p>If you&#039;re using macOS, you can simply select your Mailbox in Apple Mail, click &quot;Mailbox&quot; → &quot;Export Mailbox...&quot;</p><p>⚠️ <strong>Important</strong>: Check if the folder size is realistic. Sometimes Apple Mail won&#039;t export all mails.</p><h3>imap-backup</h3><p>If this doesn&#039;t work for you or if you&#039;re running Linux, use <a target="_blank" href="https://github.com/joeyates/imap-backup">imap-backup</a> </p><p>The setup will take you through a wizard.</p><ul><li><p>Press <code>1</code> to add an account</p></li><li><p>Press <code>2</code> to set your existing password</p></li><li><p>Press <code>3</code> to set your previous IMAP server</p></li><li><p>(<em>optional)</em> Press <code>7</code> to change the backup directory</p></li><li><p>Press <code>q</code> to return to main menu</p></li><li><p>Press <code>4</code> to save and exit</p></li></ul><p>This will now create a backup of your mailbox.</p><p><strong>⚠️ Be careful</strong>: imap-backup will create a config file in <code>~/.imap-backup/config.json</code> with all of your accounts + passwords in plain text. Make sure to delete this after creating the backup.</p><h2>2. Migrate</h2><p>I have chosen to not import the previously created backup but rather use a dedicated migration tool. If you wish to restore or use the backup for the migration, consider <a target="_blank" href="https://github.com/Ahmed-Sabri/mbox2imap">mbox2imap</a> or </p><h3>Stalwart Importer</h3><p>Stalwart comes <a target="_blank" href="https://stalw.art/docs/management/cli/import/maildir">with it&#039;s own CLI</a> that allows you to import archives in <strong>mbox</strong> or <strong>Maildir</strong> format.</p><p>In order to run only the CLI on your local machine (so you don&#039;t have to upload your backup to your server and mount it to the Docker container)...</p><ul><li><p><a target="_blank" href="https://github.com/stalwartlabs/stalwart/releases/tag/v0.12.5">download the latest compatible build</a>  (<code>stalwart-cli-aarch64-apple-darwin.tar.gz</code> for me)</p></li><li><p>extract the <code>stalwart-cli</code> executable to any folder</p></li><li><p>make it executable <code>sudo chmod +x ./stalwart-cli</code></p></li><li><p>it can happen that macOS prompts you to allow the execution. Go to System Settings → Privacy &amp; Security → &quot;Allow Anyway&quot;</p></li><li><p>execute the import command:</p></li></ul><p><strong>Troubleshooting</strong></p><ul><li><p><em>Aborting redirect request to unknown host</em>: Make sure your HTTP hostname is the same as your public facing URL (<a target="_blank" href="https://github.com/stalwartlabs/stalwart/issues/1229#issuecomment-2673541144">GitHub Issue</a>)</p></li></ul><h3>imapsync</h3><p>Alternatively, you can use <a target="_blank" href="https://github.com/imapsync/imapsync">imapsync</a> to instantly copy all mails directly from my previous provider to Stallwart.</p><p>imapsync is an &quot;<em>Email IMAP tool for syncing, copying, migrating and archiving email mailboxes between two imap servers, one way, and without duplicates.</em>&quot;</p><p>On macOS, simply install via Brew.</p><p>Then execute imapsync with your previous mail provider (<code>--1</code> arguments) and your new Stalwart account credentials (<code>--2</code> arguments).</p><p></p><p></p>]]></summary>
<updated>2025-12-21T10:45:00+00:00</updated>
<link length="248102" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/stalwart-migrate-mailboxes/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Self-hosted Services you haven&#039;t heard of</title>
<link href="https://romanzipp.com/blog/self-hosted-services-you-did-not-know-yet"></link>
<id>https://romanzipp.com/blog/self-hosted-services-you-did-not-know-yet</id>
<summary type="html"><![CDATA[<p>I&#039;ve recently written an article about the benefits of self-hosting which was <a target="_blank" href="https://news.ycombinator.com/item?id=45528342">well received</a>. Read more here:</p><p>This motivated me to write about services I&#039;m hosting that you might have never considered.</p><h2>Boring stuff</h2><p>I will not write about stuff you probably already run on your home lab such das <a target="_blank" href="https://www.home-assistant.io/">Home Assistant</a>, <a target="_blank" href="https://docs.speedtest-tracker.dev/">Speedtest Tracker</a> or Monitoring like <a target="_blank" href="https://beszel.dev/">Beszel</a> or <a target="_blank" href="https://grafana.com/">Grafana</a>.</p><h2>Services</h2><p>I&#039;m running all services in a <strong>Kubernetes</strong> cluster on Talos OS. I currently don&#039;t plan on publishing my Kubernetes configs because much of it is straight forward but maybe hit me up, write a mail or leave a comment if you&#039;re interested in this and I&#039;ll get in touch.</p><h3>Location Tracking</h3><p>I&#039;ve explored many projects that allow me to self-host a server &amp; frontend to record my own location history. Currently I&#039;m only ingesting geo data via my phone but I plan on installing a GPS tracker in my car because <a target="_blank" href="https://consumerrights.wiki/w/BMW_API_restrictions">BMW recently shut down third party access to their API</a>. I will definitely write an article about that in the future. <br><small>psst, there&#039;s a <a target="_blank" href="https://romanzipp.com/rss">RSS feed</a></small>.</p><h4>OwnTracks</h4><p>My favorite self-hostable project for GPS tracking yet is <a target="_blank" href="https://owntracks.org/">OwnTracks</a>. It offers the best app experience - at least on iOS - and was very easy to deploy. OwnTracks comes with a barebones web UI but also offers a separate <a target="_blank" href="https://github.com/owntracks/frontend">frontend</a> which you can easily spin up in a container.</p><p>OwnTracks allows you to see your current location and history including a heatmap. Any map tile provider with a standard API can be used.</p><p>The single downside for me is, that there are no user accounts or authentication. Every user can see all devices and their location. Not that important to me yet, but a fact to consider.</p><h4>Traccar</h4><p>Within the car / GPS device tracker community, Traccar is very popular. As the name suggests this service is optimized towards tracking cars and offers huge compability with <a href="https://www.traccar.org/devices/">many GPS trackers</a>.</p><p>One major downside for me is, that the web UI does not offer a location history other than the recorded position changes since you&#039;ve opened the page. Not sure if there&#039;s any way to enable that but I haven&#039;t found it yet.</p><p>Positive to note, Traccar offers separate user accounts with their own devices and trackers.</p><h4>dawarich</h4><p><a target="_blank" href="https://dawarich.app/">dawarich</a> was my first choice because I liked the look of the web UI and the project seemed more modern. But looking more into it and using the service, I found many things that annoyed me. For one, it requires multiple containers of the app to process geodata which all operate on the same volume. That caused some difficulties for me.</p><p>Also the documentation and sample Docker Compose files did not line up. Possibly because much of it is <a target="_blank" href="https://github.com/Freika/dawarich/blob/master/CLAUDE.md">vibe coded</a>.</p><h3>iSponsorBlockTV</h3><p>I am already subscribed to YouTube Premium on my YouTube account - this removed display and in-video first party advertisement but not <strong>sponsors</strong>. You can start a discussion about the ethics of this - I will not.</p><p>Similar to the <a target="_blank" href="https://sponsor.ajay.app/">Sponsorblock Browser Extension</a>, there is a hostable application called <a target="_blank" href="https://github.com/dmunozv04/iSponsorBlockTV">iSponsorBlockTV</a> which will block sponsorings on any TV that runs the YouTube app (also includes Apple TV). As far as I&#039;ve inspected, this also works for devices that are not on the same network.</p><ol start="1"><li><p>You will need to create a config - this is independent from the platform you&#039;ll deploy the app on. Simply execute the <code>docker run</code> command to create the config file (<a target="_blank" href="https://github.com/dmunozv04/iSponsorBlockTV/wiki/Installation#step-1-create-a-config-file">Instructions</a>)</p></li><li><p>Now you can deploy the service on Docker, Kubernetes, UNRAID or whereever you whish</p></li></ol><p>To verify everything works, inspect the container logs while starting to watch a video with a known sponsor segment.</p><h3>Image Hosting</h3><p>Occasionally I need to send an image over a conferencing system or chat which does not support attachments. Before I&#039;ve sometimes used imgur who now block requests from certrain IP ranges which they identify as VPN traffic. I don&#039;t want to be at the mercy of a random company.</p><p>This is where <a target="_blank" href="https://docs.slinkapp.io/">Slink</a> comes to the rescue. It has <em>nearly too many features</em> for my taste but you can configure it to your liking. Those are some of mine environment variables:</p><p>Pair this with DDNS and Cloudflare as reverse proxy and you can share locally hosted images anywhere!</p><h3>Calendar &amp; Contacts</h3><p>I&#039;ve <a href="https://romanzipp.com/blog/why-a-homelab-why-self-host">already written about</a> why you should host your own CalDAV / CardDAV server.</p><p>There are many different projects from which to chose, here are some of the most popular I&#039;ve tried so far:</p><table><tbody><tr><th rowspan="1" colspan="1"><p><strong>Project</strong></p></th><th rowspan="1" colspan="1"><p><strong>Language</strong></p></th><th rowspan="1" colspan="1"><p><strong>State</strong></p></th><th rowspan="1" colspan="1"><p>Multi-User</p></th><th rowspan="1" colspan="1"><p>Authentication</p></th></tr><tr><td rowspan="1" colspan="1"><p><a target="_blank" href="https://github.com/sabre-io/Baikal">Baïkal</a></p></td><td rowspan="1" colspan="1"><p>PHP</p></td><td rowspan="1" colspan="1"><p>active development</p></td><td rowspan="1" colspan="1"><p><strong>yes</strong></p></td><td rowspan="1" colspan="1"><p><strong>yes</strong></p></td></tr><tr><td rowspan="1" colspan="1"><p><a target="_blank" href="https://radicale.org/v3.html#getting-started">Radicale</a></p></td><td rowspan="1" colspan="1"><p>Python</p></td><td rowspan="1" colspan="1"><p>active development</p></td><td rowspan="1" colspan="1"><p>no</p></td><td rowspan="1" colspan="1"><p><strong>yes</strong></p></td></tr><tr><td rowspan="1" colspan="1"><p><a target="_blank" href="https://gitlab.com/davical-project/davical">DAViCal</a></p></td><td rowspan="1" colspan="1"><p>PHP</p></td><td rowspan="1" colspan="1"><p>maintenance</p></td><td rowspan="1" colspan="1"><p><strong>yes</strong></p></td><td rowspan="1" colspan="1"><p><em>plugin</em></p></td></tr><tr><td rowspan="1" colspan="1"><p><a target="_blank" href="https://www.xandikos.org/">Xandikos</a></p></td><td rowspan="1" colspan="1"><p>Python</p></td><td rowspan="1" colspan="1"><p>active development</p></td><td rowspan="1" colspan="1"><p>no</p></td><td rowspan="1" colspan="1"><p>no</p></td></tr><tr><td rowspan="1" colspan="1"><p><a target="_blank" href="https://nextcloud.com/groupware/">Nextcloud</a></p></td><td rowspan="1" colspan="1"><p>PHP</p></td><td rowspan="1" colspan="1"><p>active development</p></td><td rowspan="1" colspan="1"><p><strong>yes</strong></p></td><td rowspan="1" colspan="1"><p><strong>yes</strong></p></td></tr></tbody></table><p>The reason why many projects don&#039;t ship with built-in authentication is that the CalDAV / CardDAV standard works with Basic Auth that can be realized with any web server that operates before the DAV server.</p><p>I went with <a target="_blank" href="https://github.com/sabre-io/Baikal">Baïkal</a> becuase it is fairly light-weight and matched all of my criterias. If I had already deployed a Nextcloud instance that would probalby be my choice.</p>]]></summary>
<updated>2025-10-13T15:44:00+00:00</updated>
<link length="467334" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/self-hosted-services-you-did-not-know-yet/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Why Self-host?</title>
<link href="https://romanzipp.com/blog/why-a-homelab-why-self-host"></link>
<id>https://romanzipp.com/blog/why-a-homelab-why-self-host</id>
<summary type="html"><![CDATA[<p>I recently shared my current Homelab setup with a colleague and was asked a pretty simple question I just took for granted... <strong><em>why</em></strong>? </p><p>Why go through the hassle of configuring servers, installing applications, setting up containers and spending quite a substantial amount of money on hardware that will not even run under optimal data center conditions (consumer-grade internet connection, no failover, no auto migrations)?</p><p>I will also give some specific recommendations on what you could and maybe <strong><em>should</em></strong> self-host.</p><h2>Privacy</h2><p>You saw that coming.</p><p>Privacy is not a god-given right but has to be fought for. Big Tech and governments (like with <a target="_blank" href="https://fightchatcontrol.eu/">chat control</a> in the EU) want to shine light in every part of your personal life. Self-hosting services can reduce or even completely mitigate the risk of being surveilled. But it also requires a lot of technical knowledge so you can make a difference and educate your family or friends and even host some services for those who don&#039;t have the capabilities.</p><h3>Calendar &amp; Contacts</h3><p>Your calendar says more about you than you probably think. Apart from your full identity it can also give away information about regular contacts, family, coworkers, confidential business meetings, your health information such as medical appointments, sleep and workout routine, legal obligations, financial information like scheduled loans, subscriptions, political beliefs through scheduling to visit a protest and even let&#039;s other profile your behavior for identity theft to find out when you&#039;re available and when not.</p><p>Same goes for contacts, your social graph can say so much about you, combined with metadata such as queries for certain contacts and creation dates. Did you recently add an unusual amount of new contacts with the same sex, first name only and phone number? You must be dating. Just created a contact for a doctor? Looks like you&#039;re visiting a therapist.</p><p>Most people don&#039;t even think about where their social graph data is stored and probably assume it comes with their phone when in reality that data is being processed by Google, Apple, Samsung or whoever knows.</p><p>I don&#039;t want a single company holding all that sensitive information and possibly deriving data points from that. Even with Apple&#039;s <a target="_blank" href="https://support.apple.com/guide/security/advanced-data-protection-for-icloud-sec973254c5f/web">Advanced Data Protection</a> your calendars and contacts are not end-to-end encrypted.</p><h3>Location</h3><p>Many many years ago I was running an Android phone with Google services like Google Maps. One day I was looking for a feature in my Google account and saw that GMaps recorded my location history for years with detailed geocoordinates about every trip and every visit.</p><p>I was fascinated but also <strong>scared about that</strong> since I&#039;ve never actually enabled it myself. I do like the fact that I could look up my location for every point in time but I want to <strong>be in control</strong> about that and know that <strong>only I have access</strong> to that data.</p><h3>So much more</h3><p>It&#039;s beyond the scope of this post to list every possible way, your data can be traced back to you and argument why you should be conscious about that. I want to motivate you to start a new journey!</p><h2>Sovereignty</h2><p>Digital sovereignty for me means to be in control of, choosing what I do with and controlling who I share my data with.</p><p>You constantly <a target="_blank" href="https://www.reddit.com/r/googleworkspace/comments/1kes3ab/locked_out_of_google_workspace_for_3_days_support/">hear about cases</a> of tech companies locking down accounts with no apparent reason and it even happened to me in the past with Google. I do not want to be at the mercy of a giant tech firm which you can not even contact or if - get annoyed by a <a target="_blank" href="https://pivot-to-ai.com/2025/10/08/salesforce-replaces-help-with-agentforce-ai-customers-outraged/">garbage AI chat bot</a> (see my <a target="_blank" href="https://romanzipp.com/blog/rant-microsoft-edge-api">Microsoft rant</a> for more fun). <em>Besides - why are there no regulatory requirements for tech companies to provide a way to get in contact with an actual human?</em></p><p>I like protocols and file standards, no &quot;Gmail&quot; API - we call that thing SMTP and IMAP (yes, they are dated but the best we currently have. Thus I still welcome the new <a target="_blank" href="https://jmap.io/">JMAP initiative</a>). Another paragraph without bashing Microsoft? Hell no, Big Tech like Microsoft really wants you to use their AI-Copoilit-enabled-365-Office-Live-Outlook <em><strike>spyware</strike></em> software - that&#039;s why they have recently <a target="_blank" href="https://www.reddit.com/r/Outlook/comments/1g56ejp/did_microsoft_recently_discontinued_smtp_support/">disabled SMTP access</a> for Office 365 accounts.</p><h2>What to self-host</h2><p>Let&#039;s get to the bread and butter of this article and give some straightforward examples on what to self-host.</p><p>Some of those applications need to be available outside of your local network if you don&#039;t want to be constantly connected to a VPN. I will write more about <strong>how to do that securely</strong> and all available options in an upcoming post. If you want to read that, <a target="_blank" href="https://romanzipp.com/rss">subscribe to the RSS feed</a>.</p><h3>Hardware</h3><p>I&#039;m fortunate enough to work at a company (<a target="_blank" href="https://enum.co">enum.co</a>) where digital sovereignty is not just a phrase. That&#039;s why I got provided with three mini servers where I&#039;m running a highly available <strong>Kubernetes cluster</strong> (which my boss also helped me set up, thanks <a target="_blank" href="https://www.linkedin.com/in/maxheyer/">Max</a>!). Also... more on that in a later blog post.</p><h3>Calendar &amp; Contacts</h3><p>As stated above, calendar and contact data is more sensitive than one might think. This is why I am hosting my own CalDAV / CardDAV server.</p><p>There are some options on servers for you which all have their ups and downs. Here are just a few:</p><ul><li><p><a target="_blank" href="https://radicale.org/v3.html#getting-started">Radicale</a> (Python, basic web ui, only single user, does not work with apple devices from my experience)</p></li><li><p>⭐ <a target="_blank" href="https://github.com/sabre-io/Baikal">Baïkal</a> (PHP, active development, advanced web ui, multi-user)</p></li><li><p><a target="_blank" href="https://gitlab.com/davical-project/davical">DAViCal</a> (PHP, haven&#039;t tried)</p></li><li><p><a target="_blank" href="https://www.xandikos.org/">Xandikos</a> (Python, No built-in authentication, no web ui)</p></li><li><p><a target="_blank" href="https://nextcloud.com/groupware/">Nextcloud</a> (PHP, If you&#039;re already using it go for it - too bloated for me)</p></li></ul><p>Being conscious about what other can do with your calendar and contact data also mean to review, which apps have access to your contact book and calendar.</p><h3>Mail</h3><p>Oh no, I said the forbidden phrase: Self-hosted mail server. I was always told to never under any circumstances do that. But it&#039;s really not that deep.</p><p>&quot;Recent&quot; developments like <a target="_blank" href="https://stalw.art/">Stalwart</a> or <a target="_blank" href="https://mailcow.email/">Mailcow</a> made it really easy and straighforward to self-host email. Beware I&#039;m not talking about marketing mails but rather personal inboxes.</p><p>Of course, you don&#039;t want to self-host your mail server at home since it requires a static IP and needs to be reachable from the whole internet. Going into that, you want to start with a clean IP address. Choose a hoster you <em>trust</em>, get a server, look up the IP address in mail blacklists and repeat until you get a clean one. After setting up the server, you want to make sure you can receive mail and every required protocol has been correctly configured. I found the <a target="_blank" href="https://internet.nl/">internet.nl online test tool</a> to be super usefull to ensure everything works. Start by sending mails to Google, Microsoft and Yahoo addresses to check if your mails are getting redirected to SPAM. Iterate on that, check DNS, DMARC, SPF, TLS etc.</p><p>I will probably write a detailed blog post on that in the future.</p><h3>Smart Home</h3><p>When I started hosting my own <a target="_blank" href="https://www.home-assistant.io/">Home Assistant</a> instance a couple of years ago it was just an experiment to see what I can do since I wasn&#039;t really missing anything with Apple Homekit. Since then more and more smart home companies went bankrupt, sunsetted their cloud services, jacked up prices or put free services behind a paywall.</p><p>For me, Home Assistant paid off a couple of weeks ago when I heard that <a target="_blank" href="https://consumerrights.wiki/w/Philips_Hue_starts_requiring_an_account_for_the_hue_app">Philips Hue will force users to create an account</a> just to use <strong>any feature</strong> for their lights, they already paid real money for. I&#039;ve always configured Firewall rules to disallow any outgoing network traffic for smart home appliances but it seems like I cannot use any Philips Hue app specific features (like animated light patterns imitating candles etc.) even on my local network. I haven&#039;t looked into this but I hope there&#039;s some community plugin which emulates this functionality.</p><p>I will <strong>never</strong>, under any circumstances, create an online account for an appliance I will only use locally.</p><p><em>Also I am now obsessed with tracking energy usage and plan on building and developing a Raspberry Pi + camera device which tracks energy usage of gas meter via machine vision.</em></p><h3>RSS Aggregator</h3><p>I am subscribed to many news sites and blogs over RSS which is by itself already decentralized and sovereign. This is why self-hosting an RSS aggregator is kind of optional and only the last mile to go.</p><p>On my iPhone and Mac I&#039;m running <a target="_blank" href="https://netnewswire.com/">NetNewsWire</a>, in my opinion the best RSS reader, even open source and backed by <a target="_blank" href="https://inessential.com/">incredible people</a>. NetNewsWire comes with a native integration for <a target="_blank" href="https://freshrss.org/index.html">FreshRSS</a> - a feed aggregator that also provides many more features like filtering and lets you subscribe to sources which don&#039;t natively provide an RSS feed.</p><h3>Location Tracker</h3><p>I&#039;ve deployed an instance of <a target="_blank" href="https://dawarich.app/">dawarich</a> (German for &quot;<em>I was there</em>&quot;) which is a server for ingesting and viewing geolocation data. It also allows you to choose from many available mobile apps which can track send your current location to the server. At the time of writing this includes:</p><ul><li><p><a target="_blank" href="https://apps.apple.com/de/app/dawarich/id6739544999?itscg=30200&amp;itsct=apps_box_badge&amp;mttnsubad=6739544999">official dawarich app</a> (always shows a navigation icon in the iOS notch)</p></li><li><p><a target="_blank" href="https://overland.p3k.app/">Overland</a> (high battery drain for me)</p></li><li><p>⭐ <a target="_blank" href="https://owntracks.org/">Owntracks</a> (works best for me on iOS, only app settings are crazy confusing)</p></li><li><p><a target="_blank" href="https://f-droid.org/packages/net.eneiluj.nextcloud.phonetrack/">PhoneTrack</a> </p></li></ul><h3>Ideas &amp; Outlook</h3><p>I recently re-worked my homelab and went from a single big server to a 3 node Kubernetes cluster. This gives me much more flexibility in the kind of applications I can host.</p><p>This is a list of apps and tools I want to have a look at:</p><ul><li><p><a target="_blank" href="https://www.etesync.com/">EteSync</a>: End-to-end encrypted CalDAV &amp; CardDAV</p></li><li><p><a target="_blank" href="https://doc.anytype.io/anytype-docs/advanced/data-and-security/self-hosting/self-hosted">AnyType</a>: Self-hosting my own AnyType server instance</p></li><li><p><a target="_blank" href="https://immich.app/">Iimmich</a> or <a target="_blank" href="https://ente.io/">ente</a>: Moving from iCloud photos to self-hosting</p></li><li><p><a target="_blank" href="https://www.passbolt.com/">Passbolt</a>: Password manager (no I really don&#039;t like Bitwarden)</p></li><li><p><a target="_blank" href="https://github.com/tphakala/birdnet-go">BirdNET</a>: Monitoring bird species outside with a microphone</p></li><li><p><a target="_blank" href="https://penpot.app/">penpot</a>: Like Figma but free &amp; open source</p></li><li><p><a target="_blank" href="https://habitica.com/static/home">Habitica</a>: Habit manager</p></li><li><p><a target="_blank" href="https://vert.sh/">vert</a>: File converter</p></li><li><p><a target="_blank" href="https://github.com/InvoiceShelf/InvoiceShelf">InvoiceShelf</a>: Invoice manager</p></li></ul><p>There&#039;s also <a target="_blank" href="https://selfh.st/">selfh.st</a> - a great resource where can spend hours finding self-hostable applications.</p><p><strong>My new article on some more ideas: 👀</strong></p>]]></summary>
<updated>2025-10-09T09:49:00+00:00</updated>
<link length="392412" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/why-a-homelab-why-self-host/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Shut The Fuck Up</title>
<link href="https://romanzipp.com/blog/shut-the-fuck-up"></link>
<id>https://romanzipp.com/blog/shut-the-fuck-up</id>
<summary type="html"><![CDATA[<p>The internet is getting messier by the hour in an unstopple wave of enshittification. This is my way to let off some steam by outlining dogshit company behavior. Beware, rough language.</p><p><strong><small>EDIT</small></strong><small>: <a target="_blank" href="https://www.youtube.com/@TheAdamConover">Adam Conover</a> recently released a video podcast &quot;<a target="_blank" href="https://youtu.be/P1EKQidRooc">The Ensh*ttification of Everything</a>&quot; with <a target="_blank" href="https://pluralistic.net/">Cory Doctorow</a>, the man who invented the word &quot;<strong>enshittification</strong>&quot;. Great watch!</small></p><h2>Fuck your newsletter</h2><p>If your website annoys me with a „subscribe to my newsletter“ popup the first time I visit the page and the information presented is not unique in any way, I will leave. </p><p><strong>Shut the fuck up</strong>.</p><h2>Fuck your marketing</h2><p>I was supporting a fundraiser on gofundme, now they sent me an update mail. Not to be cold hearted but I never subscribed to that and in most cases I&#039;m not interested. </p><p><strong>Shut the fuck up</strong>.</p><p>Clicking on the „update notification preferences“ link in the mail, they want me to create an account - the donation was done through Apple Pay without creating an account. </p><p><strong>Fuck you</strong>.</p><h2>Fuck your magic links</h2><p>When I&#039;ve previously signed up on a website with my email address and password but I&#039;m now forced to click a magic link in some fucking email when signing in, you deserve to go to hell. </p><p><strong>Shut the fuck up</strong>.</p><h2>Fuck your &quot;auto quality&quot;</h2><p>I am a subscriber to YouTube Premium because ads are fucking annoying and I get &quot;better&quot; 1080p video quality (YouTube says the original 1080p quality wasn&#039;t scrambled to push people to &quot;1080p Premium&quot; but that&#039;s a fucking lie).</p><p>I always set the video quality to the highest value my monitor or TV supports. Which is fucking meaningless since after a couple of videos, YouTube reverts the video quality to &quot;Auto&quot; which is mostly 1080p on 1440p and above and defaults to &quot;free 1080p&quot; instead of &quot;1080p Premium&quot;. I had to write <a target="_blank" href="https://romanzipp.com/blog/tampermonkey-always-select-highes-video-quatlity-for-youtube">a Tampermonkey script</a> for that.</p><p>YouTube, let me pick my custom quality I want to consum content in - and don&#039;t say &quot;<em>you won&#039;t even notice the difference</em>&quot;. I do. This is why I&#039;m writing this paragraph.</p><p>Same for every fucking movie streaming service. Let me pick the quality and fuck off with your auto bandwidth quality. My internet speed is sufficient to stream a 4k Blu-ray so don&#039;t further mangle the quality of your shamelessly compressed shit movies.</p><p><strong>Fuck you.</strong></p><h2>Fuck your broken apps</h2><p>My phone contract is expiring and there&#039;s no where I will pay 70,00 € for 80 GB of mobile data. This is why I wanted to switch to a prepaid provider which I&#039;ve already used in the past. Getting greeted in their customer web interface, a messages pops up &quot;<em>we will no longer support the web interface, please use our app to make the following changes...</em>&quot;. Oh wow, I can not imagine what will go wrong here.</p><p>Okay, downloading the app...</p><ul><li><p>Trying to log in with the random sequence of characters they gave me as a username</p></li><li><p>1Password can not fill the web form of the in app browser</p></li><li><p>Copying over username &amp; password manually like a fucking monkey</p></li><li><p>Oh cool, there&#039;s just the button I looked for (Bumping the process of transferring my phone number over to the new provider)</p></li><li><p>Pressing the button</p></li><li><p>An in-app-browser opens</p></li><li><p>I need to login again with username &amp; password (WHICH - REMEMBER - CAN NOT AUTOFILL FROM PASSWORD MANAGER)</p></li><li><p>Copying username &amp; password manually like a fucking monkey AGAIN</p></li><li><p>Waiting for a &quot;second factor&quot; by SMS (Seriously? What if I loose my phone and want to block my number so it can not be used? (Nope, they don&#039;t provide TOTP or passkeys))</p></li><li><p>Hey, wow. It worked.</p></li></ul><p>Forcing me to download a shitty app just to interact with an in app browser and saying they will deprecate the customer web interface.</p><p><strong>Fuck you.</strong></p>]]></summary>
<updated>2025-10-02T09:21:00+00:00</updated>
<link length="36215" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/shut-the-fuck-up/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>List or Delete Calendars and Contacts via cli (CalDAV / CardDAV)</title>
<link href="https://romanzipp.com/blog/list-or-delete-caldav-carddav-calendar-and-contacts-via-cli"></link>
<id>https://romanzipp.com/blog/list-or-delete-caldav-carddav-calendar-and-contacts-via-cli</id>
<summary type="html"><![CDATA[<h2>Installing</h2><p><a target="_blank" href="https://whynothugo.nl/">Hugo Osvaldo Barrera</a> <a target="_blank" href="https://whynothugo.nl/journal/2023/05/01/introducing-davcli/">made an</a> awesome cli tool for interacting with CalDAV &amp; CardDAV servers: <a target="_blank" href="https://git.sr.ht/~whynothugo/davcli">davcli</a>.</p><p>You will need the <a target="_blank" href="https://www.rust-lang.org/tools/install">Rust toolchain</a> to be available on your device. To install <code>davcli</code>, build it from source and make it available to your shell.</p><h2>Usage</h2><p><code>davcli</code> works with pre-emptively defined environment variables for authentication. Those are the same values you used to sync the calendars/contacts on your end devices.</p><h3>Structure</h3><p>The structure of Dav servers consists of collections and items. A collection can be understood as a single calendar (CalDAV) or an address book (CardDAV). Items would be single events or people in your address book.</p><p>Calendar events are in the <code>ics</code> format, address book entries in <code>vcf</code>.</p><h3>Discover</h3><p>The <code>discover</code> command gives you an overview of the Dav servers URIs, context path and resolved principal.</p><h3>List collections</h3><p>With the <code>list-collections</code> command, you can discover all calendars / address books present on the server.</p><h3>Delete all items recursively</h3><p>I recently moved from iCloud to another self-hosted Dav server. For this I&#039;ve tried out many servers which won&#039;t have a user interface and I&#039;ve found myself wanting to delete all previously imported items.</p><p>The following script will iterate through all collections, within that through every item and delete it. After deleting every item, the script attempts to also delete the collection which will not always work since Dav servers often require that a minimum of one collection persists.</p><p>I feel like I shouldn&#039;t say that but <strong>BE AWARE THIS DELETES ALL CALENDARS AND CONTACTS</strong>.</p>]]></summary>
<updated>2025-09-26T06:36:00+00:00</updated>
<link length="200414" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/list-or-delete-caldav-carddav-calendar-and-contacts-via-cli/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Unique Job Processing in Laravel</title>
<link href="https://romanzipp.com/blog/unique-job-processing-in-laravel"></link>
<id>https://romanzipp.com/blog/unique-job-processing-in-laravel</id>
<summary type="html"><![CDATA[<h2><code>ShouldBeUnique</code> Interface</h2><p><strong>Goal</strong>: Prevent multiple jobs from being <u>dispatched</u> at the same time.</p><p><strong>Behavior</strong>: A job will not be dispatched if another instance of the job is already on the queue and has not finished processing. Jobs are &quot;unlocked&quot; after a job completes processing or fails all of its retry attempts.</p><p><strong>On failure</strong>: ...</p><p><strong>Unique Id</strong>: You can define a <code>uniqueId</code>  method on the job class to return a certain unique Id.</p><p><strong>Timeout</strong>: You can define a <code>uniqueFor</code> property after which the job&#039;s unique lock will be released</p><p><a target="_blank" href="https://laravel.com/docs/12.x/queues#unique-jobs"><em>See Laravel Docs: Unique Jobs</em></a></p><h2><code>ShouldBeUniqueUntilProcessing</code>  Interface</h2><p><strong>Goal</strong>: Prevent multiple jobs from being <u>dispatched</u> at the same time.</p><p><strong>Behavior</strong>: Unlock the job when it starts processing.</p><p><strong>On failure</strong>: ...</p><p><strong>Unique Id</strong>: You can define a <code>uniqueId</code>  method on the job class to return a certain unique Id.</p><p><strong>Timeout</strong>: You can define a <code>uniqueFor</code> property after which the job&#039;s unique lock will be released</p><p><a target="_blank" href="https://laravel.com/docs/12.x/queues#unique-jobs"><em>See Laravel Docs: Unique Jobs</em></a></p><h2><code>WithoutOverlapping</code>  Middleware</h2><p><strong>Goal</strong>: Prevent jobs from <u>running in parallel</u>.</p><p><strong>Behavior</strong>: Any overlapping jobs of the same type will be released back to the queue</p><p><strong>On failure</strong>: ...</p><p><strong>Unique Id</strong>: Provide the WithoutOverlapping with a contructor string argument to define a unique id: <code>new WithoutOverlapping(&#039;some-job&#039;)</code></p><p><strong>Timeout</strong>: You may also specify the number of seconds that must elapse before the released job will be attempted again by calling <code>-&gt;releaseAfter()</code> . Jobs may unexpectedly fail, in this case the lock won&#039;t be released. Call <code>-&gt;expireAfter()</code>  to let the lock automatically expire.</p><p><a target="_blank" href="https://laravel.com/docs/12.x/queues#preventing-job-overlaps">See Laravel Docs: Preventing Job Overlaps</a></p>]]></summary>
<updated>2025-09-09T05:55:00+00:00</updated>
<link length="125535" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/unique-job-processing-in-laravel/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Disable Form &amp; E-Mail Suggestions in Firefox</title>
<link href="https://romanzipp.com/blog/disable-form-e-mail-suggestions-in-firefox"></link>
<id>https://romanzipp.com/blog/disable-form-e-mail-suggestions-in-firefox</id>
<summary type="html"><![CDATA[<p>If you clicked on this article, you&#039;re possibly as <strong>annoyed</strong> as me. No matter what I change, Firefox will suggest previous submissions in form fields, such as e-mail addresses.</p><h2>Browser Settings</h2><p>There are some related browser settings, <strong>but those will not work</strong>. Nonetheless, you should rather disabled those.</p><p>A setting that will fully stop Firefox from suggestion form data but also disable <strong>search history</strong> in the following. If this works for you - here you go.</p><h2>Solution</h2><p>The best solution is to alter a config key which is not accessible from the settings UI.</p><ul><li><p>In the address bar, type <code>about:config</code> and press Enter</p></li><li><p>search for <em>formfill</em></p></li><li><p>Double click <code>browser.formfill.enable</code> so the new value is <code>false</code></p></li><li><p>Reload all tabs</p></li></ul><p><strong>FINALLY</strong>, no form suggestions!</p><p></p>]]></summary>
<updated>2025-07-28T06:25:00+00:00</updated>
<link length="510217" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/disable-form-e-mail-suggestions-in-firefox/cover-2.jpeg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Convert 2FAS Backup to Plain Text Links</title>
<link href="https://romanzipp.com/blog/convert-2fas-backup-to-plain-text-links"></link>
<id>https://romanzipp.com/blog/convert-2fas-backup-to-plain-text-links</id>
<summary type="html"><![CDATA[<p>Recently I was evaluating new two-factor authentication apps. My previous TOTP app was <a target="_blank" href="https://cooperrs.de/otpauth.html">OTP Auth</a>, which worked great and had a great compact UI.</p><p>One of my top priorities in a TOTP app is the ability to decrypto a backup file locally on my computer. <a target="_blank" href="https://github.com/CooperRS/decrypt-otpauth-files">There is a Python decryptor</a> for OTP Auth but the repository hasn&#039;t been touched in at least 6 years which leads to a whole lot of problems with Python dependencies.</p><h3>Why plain text links?</h3><p>Last week I&#039;ve discovered the <a target="_blank" href="https://github.com/tjblackheart/andcli">andcli</a> project by <a target="_blank" href="https://github.com/tjblackheart">Thomas Gensicke</a>. This is a terminal app that takes in encrypted backup files from all common TOTP apps (except OTP Auth) and lists entries them in a nice terminal interface - only in memory so no decrypted data is vulnerable.</p><h3>Sample JSON</h3><h3>Step 1: Export from 2FAS</h3><p>Export a <strong>non-encrypted</strong> backup file from 2FAS and save it as <code>otp.json</code>.</p><h3>Step 2: Run <code>jq</code></h3><p>You will need the CLI tool <a target="_blank" href="https://formulae.brew.sh/formula/jq">jq</a> installed.</p><p>The command output will be a list of TOTP links with inserted secrets.</p>]]></summary>
<updated>2025-06-23T06:18:00+00:00</updated>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Fix OBS &quot;Could not find the virtual camera system process&quot; on macOS</title>
<link href="https://romanzipp.com/blog/fix-obs-could-not-find-the-virtual-camera-system-process-on-macos"></link>
<id>https://romanzipp.com/blog/fix-obs-could-not-find-the-virtual-camera-system-process-on-macos</id>
<summary type="html"><![CDATA[<p>I&#039;m using OBS to capture my camera feed, make some color adjustments and output it to meeting softwares and my browser.</p><p>This is where - after an update - I was just greeted with this error message.</p><blockquote><p>Could not find the virtual camera system process.</p><p>This may be resolved by logging out of and back into your macOS user account, or by restarting your computer.</p></blockquote><p>Of course, neither re-logging or restarting helped.</p><h2>Solution</h2><p>Go to your <strong>System Preferences</strong> → <strong>General</strong> → <strong>Login items &amp; Extensions</strong></p><p>Scroll down to <strong>Camera Extensions</strong></p><p><strong>Now, this is important:</strong></p><ul><li><p>Quit OBS</p></li><li><p><strong>Uncheck</strong> the Toggle Button</p></li><li><p>Open OBS &amp; quit it again</p></li><li><p><strong>Check</strong> the Toggle Button</p></li><li><p>Open OBS - <u>the issue should be resolved</u></p></li></ul><p>If you had any applications running which access the camera and &quot;OBS Virtual Camera&quot; is not showing up anymore, restart those.</p><p>This always worked for me. Let me know if you have any different suggestions or problems this way in the comments below.</p>]]></summary>
<updated>2025-04-11T11:40:00+00:00</updated>
<link length="143924" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/fix-obs-could-not-find-the-virtual-camera-system-process-on-macos/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>How to enable PHP-FPM Slowlog in Docker (with Nomad)</title>
<link href="https://romanzipp.com/blog/how-to-enable-php-fpm-slowlog-in-docker-with-nomad"></link>
<id>https://romanzipp.com/blog/how-to-enable-php-fpm-slowlog-in-docker-with-nomad</id>
<summary type="html"><![CDATA[<p>In your PHP-FPM config (<strong><u>not the php.ini</u></strong>), add the following lines to enable logging slow requests with a threshold of 5 seconds to the specified file.</p><h3>📄 <code>php-fpm.conf</code></h3><h2>Dockerfile</h2><p>In your Dockerfile, make sure to allow your PHP user (<code>www-data</code> by default) to write to the slow log file.</p><p>Also make sure, the <code>php-fpm.conf</code> is getting copied or mounted in the Docker container.</p><h2>Capability <code>ptrace</code></h2><p>The PHP-FPM slow log needs additional security capabilities to use <code>strace</code> / <code>ptrace</code>. Those must be allowed in order for PHP-FPM to capture traces.</p><h3>Docker CLI</h3><p>If you&#039;re running Docker in the CLI or with Docker Compose, add the following argument to the Docker run command.</p><h3>Docker in Nomad</h3><p>If you&#039;re using HashiCorp Nomad, you will need to firstly allow the ptrace capability globally for the Docker plugin,</p><h4>📄 <code>nomad.hcl</code></h4><p>The following line add the <code>sys_ptrace</code> capability onto the Nomad default value. <a target="_blank" href="https://developer.hashicorp.com/nomad/docs/drivers/docker#allow_caps">Check the docs</a> on that to ensure you&#039;re just appending the required cap.</p><p>Now, in your job spec, <strong>add</strong> the previously allow capability.</p><h4>📄 <code>job.hcl</code></h4>]]></summary>
<updated>2025-03-27T06:41:00+00:00</updated>
<link length="103583" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/how-to-enable-php-fpm-slowlog-in-docker-with-nomad/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Get TTS with natural Voices on macOS without external Tools</title>
<link href="https://romanzipp.com/blog/get-tts-with-natural-voices-on-macos-without-external-tools"></link>
<id>https://romanzipp.com/blog/get-tts-with-natural-voices-on-macos-without-external-tools</id>
<summary type="html"><![CDATA[<p>People will happily sell you subscription for Text-to-Speech tools which would read articles aloud. What if I tell you, you&#039;ve already paid for that if you have a Mac.</p><p><strong>Next, I&#039;ll show the following:</strong></p><ul><li><p>How to <u>download</u> higher quality voices in macOS</p></li><li><p>Use the new voices within <u>Firefox</u>&#039; Reader View</p></li><li><p>Read content from a text file aloud with a <u>CLI tool</u></p></li></ul><h2>Siri Voices</h2><p>You will be surprised about how many Siri and TTS voices are actually available on macOS which generally sound natural and are sufficient for Text-to-Speech.</p><p>I&#039;ve found that 🇺🇸 <strong>Zoe (Premium)</strong> and 🇩🇪 <strong>Anna (Premium)</strong> sound the most natural.</p><h3>Install new Voices</h3><p>To download new Voices, you will need to head over to the macOS System Settings.</p><p>Go to <strong>Accessibility → Spoken Content</strong>.</p><p>Press the <strong>(Info) icon</strong> next to System voice.</p><p>Select your preferred language on the left and hit &quot;<strong>Voice</strong>&quot;.</p><p>Now download the voices via the blue download Icon. I found to like 🇺🇸 <strong>Zoe (Premium)</strong> and 🇩🇪 <strong>Anna (Premium)</strong>.</p><p></p><h2>Firefox</h2><p>Once you&#039;ve downloaded new Voices via your System Settings, you can restart Firefox and see those voices being available in the Firefox Reader View!</p><p>If the TTS sounds weird to you, try reducing the speed.</p><h2>CLI Tool</h2><p>I&#039;ve put together a <a target="_blank" href="https://fishshell.com/">Fish Shell</a> script which just reads content from a specified text file and simultaneously shows the current transcription.</p><p>Once put inside your Fish functions folder, you can use the CLI tool by calling</p><h3>Script <code>tts.fish</code></h3><p>I&#039;m using <a target="_blank" href="https://fishshell.com/">Fish</a> as my shell but I&#039;m sure you can convert it to bash by throwing it in a LLM.</p><p></p>]]></summary>
<updated>2025-02-17T12:19:00+00:00</updated>
<link length="762625" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/get-tts-with-natural-voices-on-macos-without-external-tools/cover-2.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Stop all Adobe &amp; Creative Cloud Processes on macOS via Script</title>
<link href="https://romanzipp.com/blog/stop-all-adobe-processes-on-macos-via-script"></link>
<id>https://romanzipp.com/blog/stop-all-adobe-processes-on-macos-via-script</id>
<summary type="html"><![CDATA[<p>If you&#039;ve installed any Adobe software that is distributed via their Creative Cloud launcher, you&#039;ve probably seen that Adobe will run a huge load of processes in the background.</p><p>I don&#039;t think that anyone in Adobe&#039;s development department is talking to people beyond their team. How else would you land in such a huge mess?</p><p>Well, let&#039;s fix that and <strong>stop any Adobe related process</strong> with a simple script that you can even <strong>execute via Raycast</strong>.</p><h2>Raycast</h2><p>To execute the script, we need to move it to the scripts folder configured in Raycast. For that...</p><ol start="1"><li><p>in Raycast, type &quot;<strong>Extensions</strong>&quot; and open the Raycast Extensions Settings</p></li><li><p>in the list, scroll down to &quot;<strong>Script Commands</strong>&quot;</p></li><li><p>on the right side, hit &quot;<strong>Add Directories</strong>&quot; and select the folder, your F*ck Adobe script lives in</p></li><li><p>you should see the script being available when typing &quot;<strong>F*ck Adobe</strong>&quot; in Raycast</p></li></ol><p>You can also configure the script output to show in Raycast with <code>@raycast.mode fullOutput</code></p><h2>The Script</h2><p>This is a the Shell script responsible for collecting &amp; stopping all Adobe related processes. Please note that the script is optimize for macOS!</p><p><strong>If you&#039;ve found any other process names, please leave a comment so I can include those!</strong></p><p>If you want to also improve the experience of getting rid of Adobe stuff, you can add a preview icon to the script folder, referenced in <code>@raycast.icon</code></p>]]></summary>
<updated>2025-02-17T06:20:00+00:00</updated>
<link length="483192" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/stop-all-adobe-processes-on-macos-via-script/cover-2.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>How to add a Custom Validator in Laravel</title>
<link href="https://romanzipp.com/blog/how-to-add-a-custom-validator-in-laravel"></link>
<id>https://romanzipp.com/blog/how-to-add-a-custom-validator-in-laravel</id>
<summary type="html"><![CDATA[<p>You can split up your validation logic into custom, reusable Validators in Laravel. This is how:</p><h3>Custom Validator</h3><p>Add a custom Validator class extending the default Validator.</p><h3>Extend Validator in Container</h3><p>Return your custom Validator in the <code>extend()</code> Closure.</p>]]></summary>
<updated>2025-02-14T08:36:00+00:00</updated>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>MotoGP 2025: Generate iCal Calendar (NEW 2026 Season)</title>
<link href="https://romanzipp.com/blog/motogp-2025-generate-ical-calendar"></link>
<id>https://romanzipp.com/blog/motogp-2025-generate-ical-calendar</id>
<summary type="html"><![CDATA[<h2>NEW: Season 2026</h2><p>You&#039;re on the 2025 edition calendar, click below for <strong>season 2026</strong>!</p><hr><p>I was always a fan of seeing all important events directly in my calendar. And the MotoGP races were no exception to that. Starting in 2021 I&#039;ve started generating iCal Feeds for MotoGP seasons so I won&#039;t miss a race.</p><h2>MotoGP Season 2025</h2><p>For the 2025 season, I&#039;ve added a configurator where you can decide yourself, to which leagues or events you want to subscribe. The default choices are <strong>Qualifying and Races</strong> events for the <strong>MotoGP</strong> league.</p><p>Missing anything or have questions? Leave a <a href="#comments">comment</a>!</p><p><em>If you&#039;re reading this in your RSS reader, that&#039;s a good time to <a href="/blog/motogp-2025-generate-ical-calendar">head over to the website</a>.</em></p><p>MotoGP also has an <a target="_blank" href="https://www.motogp.com/en/calendar">official</a> iCal calendar but this just provides each race day as a multi-day timestamp event which looks terrible and doesn&#039;t provide concrete race times.</p><h2>Import to Calendar App</h2><p>When you&#039;ve finished tinkering with the paramters above, copy the URL above and paste it to your favorite calendar client. You have the option to just download a .ics file and import it once or subscribe to the URL. I&#039;d recommend the second option since changed in the schedule will automatically update.</p><h3>macOS Calendar</h3><ol start="1"><li><p>In your Calendar app, select from the top menu &quot;<strong>File</strong>&quot; → &quot;<strong>New Calendar Subscription</strong>&quot;</p></li><li><p>Paste the URL and hit &quot;<strong>Subscribe</strong>&quot;</p></li><li><p>Choose a name, like &quot;<strong>MotoGP</strong>&quot; </p></li><li><p>Set &quot;<strong>Auto-refresh</strong>&quot; to &quot;<strong>Every day</strong>&quot;</p></li><li><p>Select &quot;<strong>OK</strong>&quot;</p></li></ol><h3>iOS Calendar</h3><ol start="1"><li><p>Select from the bottom &quot;<strong>Calendars</strong>&quot;</p></li><li><p>In the bottom left corner select &quot;<strong>Add Calendar</strong>&quot;</p></li><li><p>Select &quot;<strong>Add Subscription Calendar</strong>&quot;</p></li><li><p>Paste the URL and hit &quot;<strong>Subscribe</strong>&quot;</p></li><li><p>Set a Title and select &quot;<strong>Add</strong>&quot;</p></li></ol><h3>Google</h3><ol start="1"><li><p>Go to <a target="_blank" href="https://calendar.google.com">calendar.google.com</a></p></li><li><p>On the left sidebar, click the &quot;<strong>+</strong>&quot; next to &quot;<strong>Other calendars</strong>&quot;</p></li><li><p>Select &quot;<strong>Subscribe to calendar</strong>&quot;</p></li><li><p>On the left select &quot;<strong>From URL</strong>&quot;</p></li><li><p>Paste the iCal URL and git &quot;<strong>Add calendar</strong>&quot;</p></li></ol>]]></summary>
<updated>2025-02-08T20:55:00+00:00</updated>
<link length="2532964" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/motogp-2025-generate-ical-calendar/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Tampermonkey: Always select best Video Quality for YouTube</title>
<link href="https://romanzipp.com/blog/tampermonkey-always-select-highes-video-quatlity-for-youtube"></link>
<id>https://romanzipp.com/blog/tampermonkey-always-select-highes-video-quatlity-for-youtube</id>
<summary type="html"><![CDATA[<p>This is my <a target="_blank" href="https://www.tampermonkey.net/">Tampermonkey</a> Script to always select the highest Quality available* on YouTube.com.</p><p>There are some rules:</p><ul><li><p>Don&#039;t go beyond 1440p, since I only have 1440p displays</p></li><li><p>Select 1080p Premium, if available. This will required YouTube Premium ofc</p></li></ul><h3>How to use</h3><ul><li><p><strong>Install</strong> the Tampermonkey Extension for <a target="_blank" href="https://www.tampermonkey.net/index.php?browser=firefox">Firefox</a>, <a target="_blank" href="https://www.tampermonkey.net/index.php?browser=chrome">Chrome</a>, <a target="_blank" href="https://www.tampermonkey.net/index.php?browser=edge">Edge</a> or <a target="_blank" href="https://www.tampermonkey.net/index.php?browser=safari">Safari</a></p></li><li><p>Go to the Tampermonkey <strong>Dashboard</strong></p></li><li><p>Click the <strong>&quot;+&quot; Button</strong> to create a new script</p></li><li><p><strong>Copy &amp; Paste</strong> the Scripts below</p></li></ul><h3>Update</h3><p>If you don&#039;t want to enable auto updates or you want to modify your script, remove the <code>updateURL</code> and <code>downloadURL</code> lines.</p><h3>The Script</h3><p></p>]]></summary>
<updated>2025-02-07T10:27:00+00:00</updated>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Rant: Microsoft is a f*cking mess</title>
<link href="https://romanzipp.com/blog/rant-microsoft-edge-api"></link>
<id>https://romanzipp.com/blog/rant-microsoft-edge-api</id>
<summary type="html"><![CDATA[<p>At <a target="_blank" href="https://streamfinity.tv/en">Streamfinity</a>, we have built a browser extension that interacts with our API and presents useful actions and data on YouTube. The browser extension is fully <a target="_blank" href="https://github.com/Streamfinity/Extension">open-source on GitHub</a> and we are automatically uploading each release to the Firefox, Chrome and MS Edge extension stores.</p><p>This is done through a GitHub Action workflow.</p><p>Notice anything? The Microsoft Edge workflow has failed.</p><h3>v1 API Deprecation</h3><p>Recently, Microsoft <a target="_blank" href="https://blogs.windows.com/msedgedev/2025/01/08/enhanced-security-for-extensions-with-publish-api-next-steps/">deprecated their v1 API</a> endpoint to publish new extension packages and disabled it on January 10th.</p><p>Cool, so we&#039;ve implemented the v1.1 API endpoint. They changed around some authentication parameters but everything else was the same.</p><p><strong>BESIDES THE FACT THAT IT DOES NOT WORK</strong>.</p><p>Every single API request fails with a HTTP 500.</p><h3>Microsoft is a fucking mess</h3><p>When debugging this, I wanted to login to our company account and try to reach the support.</p><p>So let&#039;s log in</p><ul><li><p>open partner.microsoft.com</p></li><li><p>get redirected to login.microsoftonline.com</p></li><li><p><em>wait a minute for &quot;Trying to sign you in&quot;</em></p></li><li><p>get redirected to login.live.com</p></li><li><p>enter your email address</p></li><li><p><em>wait a couple of seconds for the UI to shift around</em></p></li><li><p>enter your password</p></li><li><p>get asked if you want to stay logged in</p></li><li><p>get redirected to a blank page on partner.microsoft.com</p></li></ul><h3>✨ AI Support ✨</h3><p>So let&#039;s open a support ticket.</p><p>Oh cool there&#039;s only a fucking AI support Assistant which can&#039;t even respond to questions regarding <strong>Edge workspace</strong>. What&#039;s Edge workspace? No fucking clue.</p><p>Outstanding, so I&#039;ll just select some random topic and ask it about my issue.</p><p>Awesome, the AI Assistant recommended to contact the AI Assistant. <strong>What a time to be alive</strong>.</p><p>At least, there&#039;s now a &quot;Contact Support&quot; button.</p><p><strong>PERFECT</strong>, Microsoft won&#039;t even talk to you if you have any issues with their Edge workspace.</p><p><strong>Microsoft is a fucking mess.</strong></p>]]></summary>
<updated>2025-02-05T09:18:00+00:00</updated>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>How to style &lt;progress&gt; Element with Tailwind</title>
<link href="https://romanzipp.com/blog/how-to-style-progress-element-with-tailwind"></link>
<id>https://romanzipp.com/blog/how-to-style-progress-element-with-tailwind</id>
<summary type="html"><![CDATA[<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress">&lt;progress&gt;</a> element is a lesser known but broadly available HTML element.</p><p>We can easily visualize progress with a <code>value</code> and max <code>property</code>:</p><h3>Default style</h3><p>All browsers ship a default style which can be overridden by settings the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/accent-color">accent-color</a> CSS property on the element itself or any parent.</p><p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/accent-color">accent-color</a> only alters the active portion of the element (blue above) and adding any other CSS property like <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/background-color">background-color</a> will reset the default styling like height and border-radius.</p><h2>Pseudo Elements</h2><p>The Progress Element is made of various pseudo elements which can be styled individually. The following HTML structure is the representation of Safaris and Firefox&#039; DOM structure.</p><p>To add more confusion to the topic, Chrome &amp; Safari&#039;s <code>-webkit-progress-value</code> is equivalent to Firefox&#039; <code>-moz-progress-bar</code> .</p><h3>Background Color</h3><p>To style the <strong>background</strong> part...</p><ul><li><p>Target the element itself <code>&amp;</code> (for Firefox)</p></li><li><p>Target <code>-webkit-progress-bar</code> (for Chrome &amp; Safari)</p></li></ul><p>To style the bar that represents the amount of <strong>progress that has been made</strong>...</p><ul><li><p>Target <code>-moz-progress-bar</code> (for Firefox)</p></li><li><p>Target <code>-webkit-progress-value</code> (for Chrome &amp; Safari)</p></li></ul><h3>Rounding</h3><p>Adding <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius">border-radius</a> also has some caviats. Firefox will easily round the whole progress element if a border-radius is applied to the element itself.</p><p>Chrome &amp; Safari will not add rounding unless the progress element itself has an <code>overflow: hidden</code> property set.</p><h3>Text Color</h3><p>You can also add text to progress elements by simply creating elements inside it.</p><p>Altering the text color of those elements isn&#039;t as straight forward as adding a color CSS property to the progress element. In fact that&#039;s the only variant that won&#039;t work.</p><p>For styling text inside progress elements, target the <strong>child</strong> element or the progress&#039; <strong>parent element</strong>.</p><h2>Tailwind</h2><p>Translating our knowledge to Tailwind classes using CSS self &amp; pseudo selectors we get the following element. Using a <code>bg-green-300</code> for the <strong>background</strong> and <code>bg-red-500</code> for the <strong>progress made</strong>.</p><p></p>]]></summary>
<updated>2025-01-31T00:00:00+00:00</updated>
<link length="245095" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/how-to-style-progress-element-with-tailwind/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Laravel dd() not showing Dump as HTML</title>
<link href="https://romanzipp.com/blog/laravel-dd-not-showing-dump-as-html"></link>
<id>https://romanzipp.com/blog/laravel-dd-not-showing-dump-as-html</id>
<summary type="html"><![CDATA[<p>I recently ran into an issue where the Laravel <code>dd()</code>  helper function did not display anything to my browser when calling it in any place and simply responded with a HTTP 500 and literally 0 bytes of body.</p><p>I was digging around and found out that <a target="_blank" href="https://github.com/spatie/ignition">spatie/ignition</a> - the pretty error pages you&#039;ll see on unhandled Exceptions - will replace the <a target="_blank" href="https://symfony.com/doc/current/components/var_dumper.html">Synfony VarDumper</a> Handler with a kind of middleware that collects all dumps (and displays them when another Exception is thrown? idk).</p><p>Well, how to get it working again?</p><p>Define a new environment variable <code>VAR_DUMPER_FORMAT</code> inside your project.</p><p>The value <code>any</code> isn&#039;t actually defined an can be replaced by any gibberish text. There are some special cases:</p><ul><li><p><code>html</code>: Always display the dump as HTML - also in CLI applications</p></li><li><p><code>cli</code>: Always display the dump in CLI format</p></li><li><p><code>server</code>: Dumps via a remote connection, only <code>server</code> actually just dumps to HTML or CLI based on the runtime</p></li><li><p><code>tcp://...</code>: Dumps to a remote server via TCP</p></li></ul><h2>Details</h2><p>Inside the <a target="_blank" href="https://github.com/symfony/var-dumper/blob/7.2/VarDumper.php">VarDumper</a> class, a <code>setHandler</code> method used by Laravel-Ignition will check if the previously mentioned environment variable is set and prevents overriding the existing handler.</p>]]></summary>
<updated>2025-01-29T00:00:00+00:00</updated>
<link length="98026" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/laravel-dd-not-showing-dump-as-html/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>How to use a Custom Domain for Local Development on macOS</title>
<link href="https://romanzipp.com/blog/fix-lando-not-using-custom-domain-on-macos"></link>
<id>https://romanzipp.com/blog/fix-lando-not-using-custom-domain-on-macos</id>
<summary type="html"><![CDATA[<p>I&#039;m using <a target="_blank" href="https://lando.dev/">Lando</a> for local development which is like Docker Compose, just a bit more DX focused.</p><p>Lando offers a streamlined experience but I didn&#039;t like the <code>.lnd.site</code>  domains for my projects. So I want to use another one - in this case <code>.code</code> domains. The Lando docs on using a custom domain are not that great and it didn&#039;t work for me out of the box.</p><p>This post will provide step-by-step instructions on how to setup a custom domain for local development projects using <a target="_blank" href="https://wiki.ubuntuusers.de/Dnsmasq/">dnsmasq</a> - <strong>this will also work besides Lando</strong>.</p><h3>Install &amp; configure <code>dnsmasq</code></h3><p>I will use Homebrew for convenience since the DNS service is automatically booted on system startup.</p><h3>Lando config</h3><p>I&#039;ve modified the Lando config to use a custom domain name and also enable the Traefik dashboard on <a target="_blank" href="http://127.0.0.1:50572/dashboard/">http://127.0.0.1:50572/dashboard/</a></p><h2>Option 1: Local DNS only for .code</h2><p>This option will make your local DNS server only handle local domains.</p><ul><li><p><strong>Good</strong>: Makes your local DNS server kinda secondary</p></li><li><p><strong>Good</strong>: Most other things work if you f*ck up</p></li><li><p><strong>Bad</strong>: Cached responses from external DNS providers can confuse</p></li></ul><h3>Create resolver</h3><p>This will instruct macOS to resolve <code>code</code> TLDs with our local nameserver. Other domain names will be forwarded to our systems default DNS servers.</p><h3>Configure <code>dnsmasq</code> config for the .code domain</h3><p>This will instruct <code>dnsmasq</code> to resolve and <code>*.code</code> DNS queries to localhost 127.0.0.1</p><p><code>/opt/homebrew/etc/dnsmasq.d/code.conf</code></p><hr><h2>Option 2: Local DNS as single-source-of-truth</h2><p>This guide will make your local DNS server the only DNS server your system relies on. DNS calls to unknown domains will be forwarded by your local DNS server to third party providers.</p><ul><li><p><strong>Good</strong>: Single source of truth for configuration</p></li><li><p><strong>Bad</strong>: No DNS if your setup breaks</p></li><li><p><strong>Bad</strong>: doesn&#039;t work with some VPNs</p></li></ul><h3>Configure <code>dnsmasq</code> config for the .code domain</h3><p>This will instruct <code>dnsmasq</code> to resolve and <code>*.code</code> DNS queries to localhost 127.0.0.1</p><p><code>/opt/homebrew/etc/dnsmasq.d/code.conf</code></p><h3>Setup system wide DNS</h3><p>Now we&#039;ll tell macOS to use our local <code>dnsmasq</code> name server for all DNS queries.</p><ol start="1"><li><p>Go to <strong>System Preferences</strong></p></li><li><p>Go to <strong>Network</strong></p></li><li><p>Select your Network Interface</p></li><li><p>Press the <strong>Details...</strong> button</p></li><li><p>Go to the <strong>DNS</strong> section</p></li><li><p>Add <code>127.0.0.1</code> as DNS server</p></li></ol><p>Now, <strong>restart your system</strong> and you should be able to access your Lando projects on your new custom domain.</p><h3>Note on using VPNs</h3><p>When using VPNs like Mullvad with this configuration, you may run into issues where your local <code>dnsmasq</code> server can not forward DNS queries to other DNS servers. <a target="_blank" href="https://github.com/mullvad/mullvadvpn-app/issues/6080">This is a known issue with Mullvad VPN</a>.</p><p>Your best bet now is just to add the project Domains to your <code>/etc/hosts</code> file.</p><hr><h2>Debug</h2><h4>Rebuild Lando projects</h4><p>If you&#039;ve already built projects with Lando, make sure to rebuild them so all traffic is correctly routed.</p><h4>Verify <code>dnsmasq</code> is running</h4><h4>Start <code>dnsmasq</code> manually to see errors</h4><p>For this, you need to stop any processed run by Homebrew.</p><h4>Check <code>dnsmasq</code> configuration</h4><p>Ensure <code>127.0.0.1</code> is the first DNS server.</p><h4>Check if your macOS firewall is disabled</h4><p>The following command should output &quot;<em>Firewall is disabled. (State = 0)</em>&quot;</p><h4>Check if macOS is using <code>dnsmasq</code> as DNS server</h4><ol start="1"><li><p>Go to <strong>System Preferences</strong></p></li><li><p>Go to <strong>Network</strong></p></li><li><p>Select your Network Interface</p></li><li><p>Press the <strong>Details...</strong> button</p></li><li><p>Go to the <strong>DNS</strong> section</p></li><li><p>Add <code>127.0.0.1</code> as DNS server</p></li></ol><h3>Test DNS resolve</h3><p>In the <code>dig</code> output, you should get something like</p><p></p><p></p>]]></summary>
<updated>2025-01-26T00:00:00+00:00</updated>
<link length="158044" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/fix-lando-not-using-custom-domain-on-macos/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>No, you can&#039;t use your $6,299.00 Camera as a Webcam. That will be $5</title>
<link href="https://romanzipp.com/blog/no-you-cant-use-your-6299-canon-camera-as-a-webcam"></link>
<id>https://romanzipp.com/blog/no-you-cant-use-your-6299-canon-camera-as-a-webcam</id>
<summary type="html"><![CDATA[<p><strong><em>Update</em></strong><em>: Thanks for the feedback and suggestions, looks like many of you feel the same way. Reporting done on this article: <a target="_blank" href="https://news.ycombinator.com/item?id=42735393">Hacker News</a>, <a target="_blank" href="https://arstechnica.com/gadgets/2025/01/canon-charges-50-per-year-to-use-a-900-camera-as-a-functional-webcam/">Ars Technica</a>, <a target="_blank" href="https://youtu.be/xYLMZuKWLfE">Louis Rossmann</a>. Also there&#039;s now a <a href="https://romanzipp.com/rss">RSS feed</a> if you want to be updated, I&#039;ve reached to Canon myself.</em></p><p>Companies squeezing every last penny out of their customers is no news. And <a target="_blank" href="https://www.digitalcameraworld.com/features/has-canon-stopped-putting-its-customers-first">Canon</a> <a target="_blank" href="https://petapixel.com/2024/07/21/canon-doesnt-win-on-price-technology-or-public-opinion/">is</a> <a target="_blank" href="https://petapixel.com/2024/08/13/canon-says-its-not-blocking-third-party-batteries-in-the-r5-ii/">no</a> <a target="_blank" href="https://petapixel.com/2022/09/06/canon-confirms-its-going-after-lens-makers-for-patent-infringement/">stranger</a>.</p><p>Last year, I&#039;ve bought a Canon G5 X II camera which I wanted to use mainly for taking pictures at concerts. For me, it was the perfect match of focal range (<em>zoom</em>) and sensor size (<em>more light</em>) for any compact camera I&#039;ve compared. </p><p>Because I&#039;m only using this camera for a small range of events, it&#039;s just collecting dust in the meantime. </p><p>So, why don&#039;t <strong>use it as a webcam with my Macbook</strong>?</p><p>Admittedly, it did not cost me the $6300 from the article&#039;s title, much closer to $900. Nonetheless, everything I&#039;m describing translates to every other Canon camera model!</p><h2>Problems Problems Problems</h2><p>I&#039;ve tried this at first in 2024 with macOS 14, which did not work. I <a target="_blank" href="/blog/fujifilm-webcam-x-macos-issues">had similar experience</a> with FUJIFILM&#039;s X Webcam software where either the camera will not get recognized by the software or the camera feed will freeze or simply be not available within other apps.</p><p>As of January 2025 with macOS 15 Sequoia, these issues have been resolved for me.</p><p>Well actually, only if you are able to <strong>download the software at all</strong>. Seems like their Microsoft IIS server is having some issues. The following error page will be presented to you, after they asked you for your full legal name and mail address - without which you can not download the software.</p><p></p><h2>$5/mo, $50/yr</h2><p>So I&#039;ve been really excited when I finally found a downloadable file on the Canon webpage which was not blocked by a faulty newsletter grift and saw the live feed of my camera!</p><p>Well the excitement didn&#039;t last long since nearly every single setting is disabled if you&#039;re using the software without a paying Canon account.</p><p>No brightness adjustments, no color correction, only 720p. Even in the paid version there doesn&#039;t seem to be a white balance adjustment setting.</p><p>Canon will happily take your credit card for you to pay a small monthly price of $4.99 per month or even a discounted $49.99 per year!</p><blockquote><p><em>** The 30-day free trial is valued at $4.99 and can be cancelled at any time during the free trial period through your MyCanon Account Dashboard. After the free trial period, your subscription will automatically be rolled over into the annual or monthly non-refundable, auto-renewable subscription selected upon enrollment in the free trial, which can be cancelled at any time through your MyCanon Account Dashboard. The current available subscription plans are $49.99/year or $4.99/month.</em></p></blockquote><p>In a <a target="_blank" href="https://www.usa.canon.com/content/dam/canon-assets/product-assets/Cameras/camera-misc-pages/ewu/pdf/How%20to%20Subscribe.pdf">support document</a>, Canon lists all differences between the free and paid version. So you can be very gladful, they allow you to even connect the camera.</p><p>Software development isn’t free, and I’m happy to pay for software I use regularly. However, Canon is a hardware company, not a software company, and they should—due to the lack of standards—provide software that allows you to use their cameras as intended. Aside from development costs, there’s no justification for a subscription model, particularly from a company earning nearly <a target="_blank" href="https://global.canon/en/ir/finance/highlight.html">$1.9 billion in profit</a>*.</p><h2>Why</h2><p>So Canon will not allow you to use <strong><u>your own</u></strong> camera on <strong><u>your own</u></strong> computer with <strong><u>your own</u></strong> cables the way you intent to without paying for another subscription.</p><p>Canon, what the fuck?</p><hr><p>* In an earlier version of this article I wrote &quot;$3 billion in profit&quot;</p><p></p>]]></summary>
<updated>2025-01-17T00:00:00+00:00</updated>
<link length="352392" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/no-you-cant-use-you-900-canon-camera-as-a-webcam/canon.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Fix Laravel Job Queue not processing with MaxAttemptsExceededException</title>
<link href="https://romanzipp.com/blog/fix-laravel-job-queue-not-processing-with-maxattemptsexceededexception"></link>
<id>https://romanzipp.com/blog/fix-laravel-job-queue-not-processing-with-maxattemptsexceededexception</id>
<summary type="html"><![CDATA[<p>At <a target="_blank" href="https://streamfinity.tv">Streamfinity</a>, we recently ran into an issue where the Job Queue would stop processing dispatched jobs and just fail them with a <code>MaxAttemptsExceededException</code>.</p><h2>The Situation</h2><p>With our analytics and stream tracking at Streamfinity, we are processing hundreds of thousands data points each day. Presumabily in every analytics assembly job, we are aggregating around 50.000 data points.</p><p>So as you can imagine those are long running jobs with non deterministic execution time.</p><p>Thus, we need to make sure that only a single job is processing the data at a time. This can be achieved with the <a target="_blank" href="https://laravel.com/docs/11.x/scheduling#preventing-task-overlaps">WithoutOverlapping</a> middleware. As long as a job is being locked (right before it starts processing) using Laravel atomic locking, each following attempt to process the same job class will result in a <code>MaxAttemptsExceededException</code>.</p><p>Because our jobs are long-running, errors can occur and jobs will fail. In case of failure or timeout, the <strong>lock will not be released</strong> and each following attempt of disaptching a job will also fail.</p><h2>Solution</h2><p>This is why you should always define an expiration time after which you can surely assume, the job has silently failed using the <code>expireAfter()</code> method.</p>]]></summary>
<updated>2025-01-12T00:00:00+00:00</updated>
<link length="927965" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/fix-laravel-job-queue-not-processing-with-maxattemptsexceededexception/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>2025 Edition: Best macOS Apps</title>
<link href="https://romanzipp.com/blog/2025-edition-best-macos-apps"></link>
<id>https://romanzipp.com/blog/2025-edition-best-macos-apps</id>
<summary type="html"><![CDATA[<p>This post is not sponsored. No referral links.</p><h2>Anybox</h2><p>I just love organizing my digital life. This also includes collecting various links, like new apps, interesting articles or fun tools. Recently I&#039;ve just been using AnyType with a Markdown doc but <a target="_blank" href="https://anybox.app/">Anybox</a> is a gamechanger!</p><p>A native macOS &amp; iOS app with iCloud sync. Also ships with a browser extension for saving links.</p><p><u>Price: $1.99 (monthly), $14.99 (yearly), $39.99 (lifetime)</u></p><h2>Zen Browser</h2><p>The Browser Company recently rug-pulled from their pretty popular Arc Browser - so is it smart to switch to the <strong>Firefox</strong>-eqlivalent, <a target="_blank" href="https://zen-browser.app/">Zen Browser</a>? Maybe not. But it&#039;s awesome!</p><p>The sidebar offers loads of customization possibilities and workspaces allow for neat organization. There are also built-in tools for split views. They have also been really quick with bumping their Firefox versions.</p><p><u>Price: Free &amp; Open Source</u></p><h2>NetNewsWire</h2><p>Yep, we&#039;re going RSS. I recently switched from Reeder to <a target="_blank" href="https://netnewswire.com/">NetNewsWire</a>. I did not really like the version 5 of Reeder, many config options were dropped and the link saving functionality was too present for me because I&#039;m using Anybox for that.</p><p>NetNewsWire is nearly perfect! The only thing missing for me is a preview of the OG Image, but I can live without.</p><p><u>Price: Free &amp; Open Source</u></p><h2>frame0</h2><p><a target="_blank" href="https://frame0.app/">frame0</a> is a pretty new (currently in beta) desktop app for sketching, diagrams and wireframes. Think of it a the small child of <a target="_blank" href="https://excalidraw.com/">Excalidraw</a> and Figma.</p><p>The screenshot above is my own Vim cheat sheet, btw.</p><p><u>Price: Free</u></p><h2>Ghostty</h2><p>I didn&#039;t know that I could fall in love with a Terminal emulator but here we are. If you&#039;ve slept over <a target="_blank" href="https://ghostty.org/">Ghostty</a>, first of all - how? Secondly: It&#039;s fire!</p><p>Recently I&#039;ve made a small blog post on setting up <a href="https://romanzipp.com/blog/ghostty-zellij-fish-shell">Ghostty + Zellij + Fish Shell</a>.</p><p><u>Price: Free &amp; Open Source</u></p><h2>AirBuddy</h2><p><a target="_blank" href="https://v2.airbuddy.app/">AirBuddy</a> is a macOS app that seamlessly connects AirPods or other Bluetooth headphones to your Mac, providing a convenient and efficient way to switch between devices with ease.</p><p><u>Price: 12,99 €</u></p><h2>Rectangle</h2><p><a target="_blank" href="https://github.com/rxhanson/Rectangle">Rectangle</a> is a handy macOS app that enables users to efficiently manage their windows by offering customizable keyboard shortcuts and easy window resizing options, making multitasking and organizing workspaces a breeze.</p><p><u>Price: Free &amp; Open Source</u></p>]]></summary>
<updated>2025-01-11T00:00:00+00:00</updated>
<link length="130578" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/2025-edition-best-macos-apps/apps.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Ghostty + Zellij + Fish Shell</title>
<link href="https://romanzipp.com/blog/ghostty-zellij-fish-shell"></link>
<id>https://romanzipp.com/blog/ghostty-zellij-fish-shell</id>
<summary type="html"><![CDATA[<p>If you have some issues, questions or comments, there is a <a target="_blank" href="https://github.com/ghostty-org/ghostty/discussions/3740"><strong>GitHub discussion</strong></a> about this procedure!</p><h2>Why Ghostty?...</h2><p>At first I did not understand why Ghostty got so much hype. I&#039;ve used <a target="_blank" href="https://wezfurlong.org/wezterm/index.html">WezTerm</a> and was pretty satisfied with it (even did <a target="_blank" href="https://romanzipp.com/blog/how-to-toggle-wezterm-blurred-window-background-on-focus">some fun scripting</a> for transparent window background when the window is out of focus). </p><p>Although there were some quirks with WezTerm:</p><ul><li><p>I could not get WezTerm to forward macOS <code>CMD + ...</code> keybindings to Zellij,<br><strong>This is what we&#039;re gonna solve.</strong></p></li><li><p>I had to set a separate DPI and font size for each of my external displays and the integrated Macbook screen.<br><strong>Automatically works in Ghostty.</strong></p></li></ul><h2>Install...</h2><ul><li><p><strong>Ghostty</strong><br>Well, head over to the <a target="_blank" href="https://ghostty.org/docs/install/binary">Ghostty install docs</a>. I assume you already did that if you clicked on this article.</p></li><li><p><strong>Fish</strong><br>A <a target="_blank" href="https://fishshell.com/">shell environment</a> - but modern. Easily extendable.</p></li><li><p><strong>Zellij</strong><br><a target="_blank" href="https://zellij.dev/">Zellij</a> is basically a modern type of tmux, written in Rust - of course.</p></li></ul><h2>Integrate</h2><p>We have some <strong>requirements</strong>:</p><ul><li><p>Automatically launch <strong>Zellij</strong> when opening a <strong>Terminal in Ghostty</strong></p></li><li><p>We <strong>do not</strong> want Zellij if we&#039;re in <strong>another Terminal</strong> - such as the integrated Terminal in JetBrains IDEs</p></li><li><p>Forward typical macOS <strong>tab-management keybindings</strong> to Zellij</p></li></ul><p>Ghostty as an <code>initial-command</code> config option but I didn&#039;t feel like the Ghostty config was the right place for our environment check. Additionally, we would loose the automatic shell detection when overriding this config option.</p><p>For <strong>keybindings</strong>, I do not need native Terminal tabs but rather want to use tabs + panes in Zellij. So I want to use the usual key combinations of <code>Command + n</code> (new tab) and <code>Command + Option + Arrow</code> for switching between them.</p><h3>Ghostty <code>ghostty</code> Config file</h3><p>See <a target="_blank" href="https://ghostty.org/docs/config">Ghostty Configuration docs</a>, I&#039;ve placed my config in <code>~/.config/ghostty/ghostty</code>.</p><p>The default configuration works really well for me out of the box, I&#039;ve only made some minor adjustments:</p><h3>Fish <code>config.fish</code></h3><p>Ghostty should <strong>automatically detect</strong> your Shell if you&#039;ve installed Fish correctly. If this is not the case, add the following config line to your <strong>Ghostty config file</strong>.</p><p>See the <a rel="nofollow" href="https://fishshell.com/docs/current/tutorial.html">Fish tutorial docs</a> for more info, typically the config should be placed in <code>~/.config/fish/config.fish</code>.</p><h3>Zellij <code>config.kdl</code> Config file</h3><p>Above, we&#039;ve specified the <code>ZELLIJ_CONFIG_DIR</code>, so place your <code>config.kdl</code> in that folder, in my case <code>~/.config/zellij/config.kdl</code></p><p>If Zellij is not starting into Fish shell, add the following config line to your <code>config.kdl</code></p><p>And this is what we got!</p><p></p>]]></summary>
<updated>2024-12-28T00:00:00+00:00</updated>
<link length="224659" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/ghostty-zellij-fish-shell/cover.jpeg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Change WezTerm blurred Window Background &amp; Opacity on Focus</title>
<link href="https://romanzipp.com/blog/how-to-toggle-wezterm-blurred-window-background-on-focus"></link>
<id>https://romanzipp.com/blog/how-to-toggle-wezterm-blurred-window-background-on-focus</id>
<summary type="html"><![CDATA[<p>Make sure you have a <code>.wezterm.lua</code> Config file ready in your home directory and it&#039;s correctly loaded by WezTerm. Refer to the <a target="_blank" href="https://wezfurlong.org/wezterm/config/files.html">Configuration Docs</a>.</p><h2>The Config</h2><p>The configuration as a constant <code>opacity</code> variable which is just there for consistency. An initial background opacity will be set when the configuration is read the first time.</p><p>We then listen to the <code>window-focus-changed</code> event to - <em>get any previous and</em> - set a new config override.</p><p>This is inteded to run on <strong>macOS</strong>, apparently you can build a <a target="_blank" href="https://wezfurlong.org/wezterm/config/lua/config/win32_system_backdrop.html">similar effect</a> on Windows.</p><h2>Sources</h2><ul><li><p><a href="https://wezfurlong.org/wezterm/config/lua/wezterm/on.html">https://wezfurlong.org/wezterm/config/lua/wezterm/on.html</a></p></li><li><p><a href="https://wezfurlong.org/wezterm/config/lua/window-events/window-resized.html">https://wezfurlong.org/wezterm/config/lua/window-events/window-resized.html</a></p></li><li><p><a href="https://wezfurlong.org/wezterm/config/lua/config/macos_window_background_blur.html">https://wezfurlong.org/wezterm/config/lua/config/macos_window_background_blur.html</a></p></li><li><p><a href="https://wezfurlong.org/wezterm/config/lua/window/index.html">https://wezfurlong.org/wezterm/config/lua/window/index.html</a></p></li></ul>]]></summary>
<updated>2024-12-07T00:00:00+00:00</updated>
<link length="462204" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/how-to-toggle-wezterm-blurred-window-background-on-focus/cover2.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Must-change Zed Settings</title>
<link href="https://romanzipp.com/blog/must-have-zed-settings"></link>
<id>https://romanzipp.com/blog/must-have-zed-settings</id>
<summary type="html"><![CDATA[<p>I recently started using Zed for full time development work and really fell in love. This post will show you some settings which helped me customizing the experience to my liking.</p><h2>Style</h2><h2>Language specific configuration</h2><h3>Markdown</h3><h3>LaTeX</h3><h3>PHP</h3><h2>Vim Mode</h2>]]></summary>
<updated>2024-10-10T00:00:00+00:00</updated>
<link length="198466" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/must-have-zed-settings/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Format PHP with PHP-CS-Fixer in Zed Editor</title>
<link href="https://romanzipp.com/blog/format-php-with-php-cs-fixer-in-zed-editor"></link>
<id>https://romanzipp.com/blog/format-php-with-php-cs-fixer-in-zed-editor</id>
<summary type="html"><![CDATA[<p>I recently tried out the new <a target="_blank" href="https://zed.dev/">Zed</a> code editor, which also has first party support for PHP Language Servers <a target="_blank" href="https://github.com/phpactor/phpactor">phpactor</a> or <a target="_blank" href="https://github.com/bmewburn/vscode-intelephense/">intelliphense</a>!</p><p></p><p>One issue I ran into is auto formatting code. I&#039;m a fan of auto formatting since this preserves a cohesive code style over many projects and helps to reduce merge issues.</p><h2>External formatters in Zed</h2><p>Formatters in Zed work a bit different than some implementations in VSCode or similar editors.</p><p>You can <a target="_blank" href="https://zed.dev/docs/configuring-zed#formatter">configure an external formatter</a> by specifying an <code>external</code> key with a <code>command</code> and <code>arguments</code> values.</p><p>Once you run the <code>editor: format</code> action or save the file (with <code>format_on_save</code> enabled), you can provide the formatter with the current file in two ways</p><ol start="1"><li><p>Set a <code>{buffer_path}</code> placeholder variable</p></li><li><p>Append a <code>-</code> to pipe in the file contents to the <code>command</code></p></li></ol><p>We will use the second way since you could also call commands inside docker containers. When mounting your project root inside a container, the absolute path placed inside <code>{buffer_path}</code> will mismatch and you will need to do some magic to convert it into a relative path.</p><h2>Format using PHP-CS-Fixer</h2><p>I&#039;ve created a <a target="_blank" href="https://github.com/romanzipp/PHP-CS-Fixer-Config/blob/master/bin/php-cs-fixer-stdin">bin script</a> in my <a target="_blank" href="https://github.com/romanzipp/PHP-CS-Fixer-Config">PHP-CS-Fixer Config project</a> that takes in the STDIN, calls PHP-CS-Fixer to format the file contents and returns the result as STDOUT.</p><p>The bin script is pretty opinionated and only uses the fix command of PHPCS, feel free to fork it, contribute or do whatever!</p><h3>Install</h3><p>You could just install the PHP-CS-Fixer-Config dependency or copy the script below. Make sure to alter the command path if you wish to use the manual way.</p><h2>php-cs-fixer-stdin.php</h2><p></p>]]></summary>
<updated>2024-10-02T00:00:00+00:00</updated>
<link length="256620" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/format-php-with-php-cs-fixer-in-zed-editor/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>How to log API Requests with Guzzle in PHP (YouTube API Client)</title>
<link href="https://romanzipp.com/blog/how-to-log-api-requests-with-guzzle-in-php-youtube-api-client"></link>
<id>https://romanzipp.com/blog/how-to-log-api-requests-with-guzzle-in-php-youtube-api-client</id>
<summary type="html"><![CDATA[<p>A quick tip if you want to see/log the raw HTTP responses when interfacing with a PHP library that does not expose the responses.</p><h2>Default Situation</h2><p>Imagine you want to request some video details from the YouTube API but also want to inspect some headers of the response.</p><p>The Google/YouTube PHP library does not allow you to do so.</p><h2>Add Guzzle Middleware</h2><p>Instead, we simply add a history <a target="_blank" href="https://docs.guzzlephp.org/en/stable/handlers-and-middleware.html">middleware</a> to the HTTP client, in our case <a target="_blank" href="https://docs.guzzlephp.org/en/stable/">Guzzle</a>.</p><p>It&#039;s that easy.</p>]]></summary>
<updated>2024-08-12T00:00:00+00:00</updated>
<link length="1237997" type="image/png" href="https://cdn-a.romanzipp.com/blog/how-to-log-api-requests-with-guzzle-in-php-youtube-api-client/cover.png" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>How to leverage Multi-Stage Caches with Laravel and HAProxy</title>
<link href="https://romanzipp.com/blog/how-to-leverage-multi-stage-caches-with-laravel-and-haproxy"></link>
<id>https://romanzipp.com/blog/how-to-leverage-multi-stage-caches-with-laravel-and-haproxy</id>
<summary type="html"><![CDATA[<p>This article will explain in detail how we handle 50+ million requests per month with response caching at <a target="_blank" href="https://streamfinity.tv">Streamfinity</a> using multiple layers.</p><p>Lets take this absolutely non-scientific flow diagram.</p><p>Our goal is, to reduce load on our backend servers and hit the database as little as possible. This can be made possible using multiple stages or layers of cache at different points.</p><h2>When NOT to cache</h2><p>There are some caviats to caching responses and data. At first, we want to make sure that we only return cached responses for the right requests. This includes not using response caching with URI indexes on authorized routes because the response content differs for every user sending a Bearer token.</p><p>An ideal scenario for response caching is a static endpoint which could be replaced by a simple JSON file. An example at Streamfinity would be the endpoint which returns all possible extension stores for our browser extension stores, such as Chrome Web Store, Firefox AMO etc. The client sends a request with a simplified User-Agent as GET parameter. The endpoint then returns all available stores with the first compatible store featuring a <code>recommended</code> key. This endpoint is unauthenticated and thus qualifies ideally for response caching.</p><h2>Stage 1: Cloudflare</h2><p>Static assets like images, JS and CSS files are cached by Cloudflare by default. Every new build of our application generates frontend assets with a unique hash so the clients always receive the latest version independent of Cloudflare&#039;s cache.</p><h2>Stage 2: HAProxy</h2><p><strong>At first, just some base goals:</strong></p><ul><li><p>We want to cache server responses in HAProxy</p></li><li><p>We only want to cache the response if a <code>X-Proxy-Cache</code> header has been sent from the server</p></li></ul><p><strong>HAProxy will only cache the data if all of the following are true:</strong></p><ul><li><p>The size of the resource does not exceed <code>max-object-size</code></p></li><li><p>The response from the server is <em>200 OK</em></p></li><li><p>The response does not have a <code>Vary</code> header</p></li><li><p>The response does not have a <code>Cache-Control: no-cache</code> header</p></li></ul><h3>Cache Section</h3><p>The <code>cache</code> section defines the cache store to use. This is the place to configure objects sizes and cache durations. The default <code>max-age</code> can be overridden by the <code>Cache-Control</code> header.</p><h3>Backend</h3><p>Let&#039;s look at the following <a target="_blank" href="https://www.haproxy.com/documentation/haproxy-configuration-tutorials/core-concepts/backends/">HAProxy backend</a> we use at <a target="_blank" href="https://streamfinity.tv">Streamfinity</a> and intersect every line.</p><h4>Cache Store</h4><p>The <code>cache-use</code> statement instructs HAProxy to use the cache store named <code>bucket</code> for all cache-related actions.</p><h4>Check for Headers</h4><ul><li><p>If HAProxy finds the header <code>X-Proxy-Cache</code> in the server response, we want to store the response (<code>cache-store</code>) in the cache <code>bucket</code></p></li><li><p>The original <code>Cache-Control</code> header with the duration should be removed, so we only cache the data on the HAProxy and don&#039;t instruct clients to keep the data locally</p></li></ul><h3>Add Cache-Status Header</h3><p>You can also add a header which indicates if a given response originates from the HAProxy cache or was served by the backend server. Thse two lines check if the <code>srv_id</code> fetch method returns the name of a server that was used to handle the request. If no value is returned, it means that HAProxy used the cache.</p><h2>Stage 3: Redis</h2><p>We use Redis in a Cluster deployment to cache application data which is accessed from multiple places or cache partial responses which are not eligible for full response caching via HAProxy.</p>]]></summary>
<updated>2024-08-08T00:00:00+00:00</updated>
<link length="773632" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/how-to-leverage-multi-stage-caches-with-laravel-and-haproxy/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Level Up your PHP Code Style</title>
<link href="https://romanzipp.com/blog/level-up-your-php-code-style"></link>
<id>https://romanzipp.com/blog/level-up-your-php-code-style</id>
<summary type="html"><![CDATA[<h2>1. PHP CS Fixer</h2><p>The <a target="_blank" href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer">PHP Coding Standards Fixer</a> (<a target="_blank" href="https://github.com/PHP-CS-Fixer/PHP-CS-Fixer">PHP CS Fixer</a>) tool fixes your code to follow standards; whether you want to follow PHP coding standards as defined in the PSR-1, PSR-2, etc., or other community driven ones like the Symfony one. You can <strong>also</strong> define your (team&#039;s) style through configuration.</p><h4>Why?</h4><p>Especially when working in teams, different syntax formatting can lead to merge conflicts resulting in frustration and possibly bugs. Thus, a standardized syntax is a key element in collaborating with others. All of my projects require the same coding style.</p><h4>Configuration Management</h4><p>Over the time I&#039;ve built a preferred style config for my own projects which I&#039;ve <a target="_blank" href="https://github.com/romanzipp/PHP-CS-Fixer-Config">open sourced</a> at <a target="_blank" href="https://github.com/romanzipp/PHP-CS-Fixer-Config">romanzipp/PHP-CS-Fixer-Config</a>. This repository contains some curated PHP-CS-Fixer rules with custom presets. Of course, presets can be extended and rules can be overridden in each consuming project.</p><h4><code>.php-cs-fixer.dist.php</code></h4><p>To run PHP-CS-Fixer, just execute...</p><h4>Integrate with your CI</h4><p>One argument of the PHP-CS-Fixer cli we can make use of, is <code>--dry</code> option. This will not modify your code and only run the validation which returns an error code if the optimal code format missmatches the source. This will allow your to <strong>integrate a syntax linting step into your CI</strong>, failing builds if the format is off.</p><p><strong>Tip</strong>: Add a hotkey to your IDE such as <code>CMD + SHIFT + C</code> to automatically format your code.</p><hr><h2>2. PHPStan</h2><p><a target="_blank" href="https://phpstan.org/">PHPStan</a> is a static linter for your PHP projects. As simple as that.</p><p>Configuration is done through YAML files, which contain the PHP language level, strictness and other parameters. This is an example <code>phpstan.neon.dist</code></p><p>To run PHPStan, just execute...</p><p></p><h4>Integrate with PHPStorm</h4><p>PHPStan can also perform linting and show issues directly inline in your IDE, such as PHPStorm. See the <a target="_blank" href="https://www.jetbrains.com/help/phpstorm/using-phpstan.html">official JetBrains PHPStorm guide</a> on how to integrate with PHPStan.</p><hr><h2>3. Laravel Model Doc - <a target="_blank" href="https://github.com/romanzipp/Laravel-Model-Doc">GitHub</a></h2><p>Laravel has catapulted PHP to a new level and the language is more popular than ever. But one thing that has always <strong>driven me crazy</strong> is the <strong>lack of typing</strong> which leads in developers needing to rely on IDE plugins to get helpful code suggestions.</p><p>This is why I&#039;ve created the <a target="_blank" href="https://github.com/romanzipp/Laravel-Model-Doc">Laravel-Model-Doc package</a>, which <strong>automatically generates PHPDoc comments</strong> for all of your Models and writes them to the class file.</p><h3>The Problem</h3><p>Laravel provides many handy features, such as accessing loaded relationships via a magic accessor. Unfortunately, static linters will see this as a syntax error since the attribute has not been explicitly declated. Additionally, you will not get any autocomplete support from your IDE.</p><p>With added PHPDoc blocks, declared relationships will get the according accessor and provide a <code>_count</code> attribute. And much more!</p><h3>How</h3><p>Laravel-Model-Doc takes many sources into consideration when generating doc blocks, such as...</p><ul><li><p>Model Relationships</p></li><li><p>Model Factories</p></li><li><p>The Database structure (attributes, fields)</p></li><li><p>Custom accessor methods</p></li><li><p>Query scope methods</p></li></ul><p>In the latest update, the package will also add <strong>generics annotations</strong> such as <code>Collection&lt;ModelClass&gt;</code>.</p><h3>Let&#039;s see it in Action</h3><p>One tiny caveat before using the package: You will need to make some adjustments to your models, which - <em>in my opinion</em> - additionally provide more safety. These are:</p><ol start="1"><li><p>Specify the table name explicitly <code>protected $table = &#039;users&#039;;</code></p></li><li><p>Add return types to your relationship methods <code>public function teams(): HasMany</code></p></li><li><p>Add return types to your accessor methods</p></li></ol><h4>Before</h4><h4>After</h4><p><a href="https://github.com/romanzipp/Laravel-Model-Doc">See on how to implement Laravel-Model-Doc on GitHub</a></p>]]></summary>
<updated>2024-08-01T00:00:00+00:00</updated>
<link length="393270" type="image/png" href="https://cdn-a.romanzipp.com/blog/level-up-your-php-code-style/cover.png" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>How to use Cloudflare Image Resizing with Statamic CMS</title>
<link href="https://romanzipp.com/blog/how-to-use-cloudflare-image-resizing-with-statamic-cms"></link>
<id>https://romanzipp.com/blog/how-to-use-cloudflare-image-resizing-with-statamic-cms</id>
<summary type="html"><![CDATA[<h2>Why</h2><p>Properly resizing images on web pages offers several advantages:</p><ul><li><p><strong>Improved Load Times</strong>: Reduces file size, leading to faster page loading and better user experience.</p></li><li><p><strong>Enhanced Performance</strong>: Decreases bandwidth usage and server load.</p></li><li><p><strong>SEO Benefits</strong>: Faster loading pages are favored by search engines, potentially improving rankings.</p></li><li><p><strong>Mobile Optimization</strong>: Ensures images display correctly and load quickly on mobile devices.</p></li><li><p><strong>Bandwidth Savings</strong>: Minimizes data consumption for users, particularly important for those on limited data plans.</p></li><li><p><strong>User Experience</strong>: Avoids layout shifts and ensures images fit within the intended design.</p></li><li><p><strong>Accessibility</strong>: Enhances accessibility by ensuring images are appropriately sized for screen readers and other assistive technologies.</p></li><li><p><strong>Cost Efficiency</strong>: Reduces hosting and CDN costs due to smaller file sizes and reduced bandwidth usage.</p></li></ul><h2>Cloudflare Images</h2><p>Cloudflare offers an <a target="_blank" href="https://www.cloudflare.com/developer-platform/cloudflare-images/">Images</a> product which can easily resize images hosted on their R2 storage buckets or on your own web page.</p><p>To enable CF Images, ...</p><ol start="1"><li><p>head over to your <a target="_blank" href="https://dash.cloudflare.com">Cloudflare Dashboard</a></p></li><li><p>Go to <strong>Images</strong></p></li><li><p>Select <strong>Transformations</strong> from the Sidebar</p></li><li><p>Choose your <strong>Domain/Zone</strong></p></li><li><p>and click &quot;<strong>Enable for zone</strong>&quot;</p></li></ol><h2>Integrate Cloudflare Images with Statamic</h2><h3>Create new Tag class</h3><p>Ad new file <code>CloudflareImageTag</code> should have been created in the folder <code>app/Modifiers</code>.</p><h3>Tag class</h3><h2>Usage</h2><p>To show the resized version of an image, simple attach the <code>cf_image</code> tag.</p><p></p>]]></summary>
<updated>2024-07-08T00:00:00+00:00</updated>
<link length="195880" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/statamic-cloudflare-images/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Docker &quot;Rosetta is only intended to run on Apple Silicon&quot; on macOS Sequoia</title>
<link href="https://romanzipp.com/blog/maocs-sequoia-docker-resetta-is-only-intended-to-run-silicon"></link>
<id>https://romanzipp.com/blog/maocs-sequoia-docker-resetta-is-only-intended-to-run-silicon</id>
<summary type="html"><![CDATA[<p>When upgrading from macOS Sonoma to the new macOS Sequoia Developer Beta, there are chances you will run into the following issue with the error message</p><blockquote><p>rosetta error: Rosetta is only intended to run on Apple Silicon with a macOS host using Virtualization.framework with Rosetta mode enabled</p></blockquote><p>Here&#039;s how to fix it.</p><h2>Install Rosetta</h2><p>Run the following command to install the Rosetta translation layer if not already done.</p><h2>Update Docker</h2><p>Update your Docker Desktop installation by navigating to <strong>Settings</strong> &gt; <strong>Software Update</strong> &gt; <strong>Check for Updates</strong>.</p><h2>Check for Updates</h2><p>There are chances that you will need to update XCode when upgrading your macOS version. Check for updates using the following command.</p><p>You will get an output like:</p><p>Copy the <strong>Label</strong> text and paste it into the <code>-i</code> argument.</p><p>If you have issues with the installation, download XCode from the <a href="https://developer.apple.com/download/applications/">Apple Developer Hub</a>.</p><h2>Disable Docker x86_64/amd64 emulation</h2><p>As a last step, try disabling the x86_64/amd64 emulation using Rosetta on Apple Silicon in your <strong>Docker Desktop General settings</strong>.</p>]]></summary>
<updated>2024-06-11T00:00:00+00:00</updated>
<link length="1112281" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/maocs-sequoia-docker-resetta-is-only-intended-to-run-silicon/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Streamfinity takes off!</title>
<link href="https://romanzipp.com/blog/streamfinity-reactions-new-tool-launches"></link>
<id>https://romanzipp.com/blog/streamfinity-reactions-new-tool-launches</id>
<summary type="html"><![CDATA[<h2>A Giant Leap Towards More Fairness &amp; Transparency in the Reaction Game</h2><p>I’m stoked to announce the official launch of <a href="https://streamfinity.tv">Streamfinity</a>. It’s an innovative platform that connects streamers, video creators, and communities in a way that’s never been done before, making it possible to reveal previously hidden view counts through livestream and video reactions.</p><p>Streamfinity offers a bunch of features that provide significant value for streamers, video creators, and viewers alike. For instance, you can track which livestreams are reacting to a YouTube video. Streamers can analyze how individual videos perform in their streams. Plus, with the new Streamfinity Trends, you can see which videos are hot in the livestreams.</p><h3>These new analytics open up a massive potential for the exploitation of video content by streamers as well as copyright-holding video creators.</h3><p>But that’s not all. Our core mission is to enable fair and transparent reactions, and for that, clear usage rights are absolutely necessary. To make these easy to manage and communicate to everyone, anyone with a YouTube account on Streamfinity.tv can specify how their published videos can be used in livestreams or other YouTube videos. These so-called Reaction Policies are then played out to all users via the <a href="https://github.com/Streamfinity/Extension">open-source browser extension</a> - the <strong>Streamfinity Buddy</strong>.</p><h3>This is a revolutionary step for the entire industry - worldwide.</h3><p>The <a href="https://streamfinity.app">Streamfinity Buddy</a> reveals even more potential. With a large number of users, a simple communication platform is created directly on YouTube. Through this, people can write and rate Community Notes for individual videos starting from 01.07. These Community Notes aim to clarify whether a video is spreading so-called fake news, disinformation, or even hate &amp; agitation. All this with the help of a simple explanation, appropriate timestamps, and external sources.</p><p>For the future, more exciting features and optimizations are planned. For example, we’re gearing up to track the co-streaming of selected live events. For this, we have an “Event Hub” planned, where event organizers can promote their own event, inform about it, and track the co-streams - and much more.</p><p>Streamfinity has become a massive project. In 2022, Roman Zipp and Christian Fassbender started it. Completely independent, with the goal of making the Reaction Game better, more fair, and more transparent for everyone. Over time, we received support from Chris Staufer, Romina Schöner, and Matthias Münzel. No investors, no restrictions. We’re just a group of friends with a vision.</p><h2>Any questions? Hit us up!</h2><p><strong>Roman Zipp</strong><br>Founder &amp; Lead Software Engineer<br><a href="mailto:roman@streamfinity.tv">roman@streamfinity.tv</a></p><p><strong>Christian Fassbender</strong><br>Founder &amp; Managing Director<br><a href="mailto:christian@streamfinity.tv">christian@streamfinity.tv</a></p><p><strong>Chris Staufer</strong><br>Co-Founder &amp; Creative Director<br><a href="mailto:chris@streamfinity.tv">chris@streamfinity.tv</a></p><p><strong>Romina Schöner</strong><br>Head of Campaign Development<br><a href="mailto:mina@streamfinity.tv">mina@streamfinity.tv</a></p><p><strong>Matthias Münzel</strong><br>Software Engineer<br><a href="mailto:matze@streamfinity.tv">matze@streamfinity.tv</a></p><p>Web: <a href="https://www.streamfinity.tv">https://www.streamfinity.tv</a><br>LinkedIn: <a href="https://www.linkedin.com/company/streamfinitytv/">https://www.linkedin.com/company/streamfinitytv/</a><br>Discord: <a href="https://sfin.it/discord">https://sfin.it/discord</a></p>]]></summary>
<updated>2024-06-04T00:00:00+00:00</updated>
<link length="236127" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/streamfinity-reactions-new-tool-launches/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Run Multi-Step Job inside Docker Container with GitHub Actions</title>
<link href="https://romanzipp.com/blog/github-actions-run-multiple-jobs-in-container"></link>
<id>https://romanzipp.com/blog/github-actions-run-multiple-jobs-in-container</id>
<summary type="html"><![CDATA[<h2>What</h2><p>This post will explore the possibility to run multiple GitHub Actions steps inside a Docker container that is built in the same workflow.</p><p>I will visualize this with a simple example of a PHP project utilizing PHPUnit, PHPStan and PHP-CS-Fixer but this of course works for every language or tooling.</p><h2>Why</h2><p>With GitHub Actions you have the possibility to choose from endless available workflows built by the community such as PHP-CS-Fixer or PHPUnit.</p><p>The problem with this that - if you&#039;re distributing your project as a Docker container (as you should) - your <strong>CI environment can be vastly different</strong> from your container environment.</p><p>You have the option to pin a specific PHP version but nonetheless if you&#039;ve worked with Docker containers before you will know there are a lot of quirks - such as Alpine images, specific environment variables, multi-step build stages, ...</p><h2>Why in parallel</h2><p>Speed.</p><h2>The idea</h2><p><strong>TLDR</strong>; If you just want to see the <strong>full workflow file</strong>, scroll down.</p><p>We want to firstly build a reusable Docker container and then run any tasks in parallel afterwards.</p><h3>1. Build Container</h3><p>In this build step we will build the container and save it as a tarball to a temporary directory <code>/tmp/project.tar</code>. To make it later available to other jobs we will upload it as an artifact named <code>project</code>.</p><h3>2. use Container in parallel jobs</h3><p>In any other following job, we attach a <code>needs: [ build-image ]</code> to tell GitHub Actions that we depend on the previous job.</p><p>The first step is to download previously uploaded artifact (container) <code>project</code> and load it into the Docker daemon.</p><h3>3. Cleanup</h3><p>Since we made use of artifacts, these files will be persisted after the default cleanup time of 30 days. This will take up storage quota from your GitHub account.</p><p>Note to add <code>if: always()</code> to always execute this step - even if previous jobs failed. Also specify all previous build steps in the <code>needs: []</code> array.</p><h2>Notes!</h2><h3>Dependencies</h3><p>If you&#039;re using the same Dockerfile for your production and CI environment, be sure to add a configuration/environment variable which indicates the Docker build to only install production dependencies outside of the CI.</p><h3>Quota Usage</h3><p>If your workflows are running for a longer time and GitHub Actions quota is important to you, note that we have observed that running multiple steps in parallel using different jobs counts more to your quota since every job counts against your quota on its own. The following example is not representative of actual execution times since the job logs originate from different points in time but rather visualize the issue.</p><hr><h2>Workflow File</h2><p>Full GitHub Actions workflow file using PHPUnit (+MySQL), PHPStan and PHP-CS-Fixer.</p>]]></summary>
<updated>2024-02-28T00:00:00+00:00</updated>
<link length="243710" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/github-actions-run-multiple-jobs-in-container/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>How to fix Nomad using wrong network interface for jobs</title>
<link href="https://romanzipp.com/blog/nomad-consul-bind-wrong-interface-public-ip"></link>
<id>https://romanzipp.com/blog/nomad-consul-bind-wrong-interface-public-ip</id>
<summary type="html"><![CDATA[<p>This guide will help you to fix the issue when Nomad / Consul are binding jobs on the wrong interface.</p><h2>Get your private interface</h2><p>First, run <code>ifconfig</code> to check if the interface is available and get it&#039;s name.</p><p>If your networking is configured correctly you will find your private interface named like <code>ens...</code>, <code>enp...</code>.</p><h2>Fix</h2><p>You can either hardcode the interface name or use the <a href="https://pkg.go.dev/github.com/hashicorp/go-sockaddr/template">go-sockaddr/template</a> templating language to get the private interface name.</p><p>The following example will get the <code>name</code> of the first network interface in the <code>10.0.0.0/8</code> address space (this will match all ip addresses from <code>10.0.0.0</code> to <code>10.255.255.255</code>).</p><p>It&#039;s important to <strong>restart Nomad and all jobs</strong> afterwards. Only restarting Nomad will not be enough since the job will keep running in the background.</p><h3>References</h3><p><a href="https://developer.hashicorp.com/nomad/docs/configuration/client#network_interface">See Nomad </a><code>network_interface</code> Docs</p><h2>Troubleshooting</h2><p>To see all configuration values and debug info, run <code>nomad operator debug</code> and quit using <code>Ctrl+C</code>. A .tar.gz file will be created in the current directory. Download, extract it and check the <code>cluster/agent-self.json</code> file for the <code>NetworkInterface</code> value to see if the value has been set correctly.</p>]]></summary>
<updated>2024-02-26T00:00:00+00:00</updated>
<link length="725142" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/nomad-consul-bind-wrong-interface-public-ip/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Fujifilm X100VI vs all other X100 series cameras - What are the differences?</title>
<link href="https://romanzipp.com/blog/fujifilm-x100vi-2024-compared-to-x100-series"></link>
<id>https://romanzipp.com/blog/fujifilm-x100vi-2024-compared-to-x100-series</id>
<summary type="html"><![CDATA[<p>Fujifilm just released the X100VI - the latest addition to the X100 series. The X100VI will be available for purchase from February 28 for a list price of $1.599 - but how does it compare to the previous X100 series cameras? Should you buy the X100VI or the X100V?</p><p>This post will compare the <strong>new X100VI</strong> to the predecessors X100V, X100F, X100T, X100S and X100 in important key facts that really matter.</p><h2>The new Fujifilm X100VI</h2><ul><li><p>40MP BSI CMOS APS-C X-Trans sensor</p></li><li><p>35mm equiv F2 lens</p></li><li><p>In-body IS rated at up to 6EV of correction</p></li><li><p>Hybrid optical/electronic viewfinder (3.69M dot OLED panel)</p></li><li><p>Machine-learning trained subject recognition AF</p></li><li><p>14 film simulations</p></li><li><p>6.2K video capture and 10-bit recording</p></li><li><p>Built-in ND filter</p></li><li><p>Tilt up/down rear touchscreen</p></li></ul><p><a href="https://amzn.to/3I76wAI">Available for $ 1.599</a> from February 28.</p><h2>Comparison</h2><p>This is by no means a complete feature list - but rather important key facts that were important to me like film simulations, screen size, autofocus systems or sensor types. You can also <a href="https://romanzipp.com/assets/blog/fujifilm-x100vi-2024-compared-to-x100-series/fujifilm-x100vi-vs-x100-comparison.pdf">download this table as PDF</a>.</p><p></p><h2>Accessories</h2><p>Here are some accessories I use for my X100S that I <strong>actually own and like</strong>. Of course, you can buy all items on Amazon via the referral link - you know how it goes!</p><h3><a href="https://amzn.to/3Lthodr">Tiffen GLIMMERGLASS 1 Filter 49mm</a></h3><blockquote><p>The <a href="https://amzn.to/3Lthodr">Tiffen Glimmerglass</a> filter adds a kind of cinema-like bloom to your images without being too intruding like the <a href="https://amzn.to/412KgyB">Black Pro-Mist</a> filter. All of <a href="https://romanzipp.com/photos">my X100S images</a> are taken with the Glimmerglass filter. See <a href="https://youtu.be/rFZRWbnLrs4">GxAce&#039;s video</a> on the filter for some great examples.</p><p>Currently <a href="https://amzn.to/3Lthodr">64,77 € on Amazon</a></p><p></p></blockquote><h3><a href="https://amzn.to/3VtjDll">Haoge LAR-X100W 49mm Adapter Ring</a></h3><blockquote><p>To use any 49mm filter on your Fujifilm X100 series camera you need a adapter ring. Otherwise the lense element will touch the filter glass resulting in an error and <strong>possibly damaging</strong> your camera in the long run.</p><p>Available for only <a href="https://amzn.to/3AKigFB">9,99 € on Amazon</a></p><p></p></blockquote><h3><a href="https://amzn.to/445p79U">Shutter Button</a></h3><blockquote><p>There is a custom red konkav and konvex shutter button included in this kit.</p><p>Currently <a href="https://amzn.to/445p79U">7,94 € on Amazon</a></p><p></p></blockquote><h3><a href="https://amzn.to/3VcJKgb">Thumb Grip</a></h3><blockquote><p>A great advantage of the X100 series is it&#039;s compact formfactor - which is also one of its negativ points. You can greatly increase your grip with a custom thumb grip which fits perfectly in the hot shoe.</p><p>Available for <a href="https://amzn.to/40HIW43">7,44 € on Amazon</a></p><p></p></blockquote><h3><a href="https://amzn.to/445JEet">Hot Shoe Cover</a></h3><blockquote><p>If you feel like a thumb grip is not necessary, a neat hot shoe cover with the &quot;FUJIFILM X&quot; logo can be a great fit. I am rocking this cover item on my X-S10.</p><p>Currently <a href="https://amzn.to/445JEet">12,08 € on Amazon</a></p><p></p></blockquote><h3><a href="https://amzn.to/40YOg3v">Peak Design Leash</a></h3><blockquote><p>Peak Design has undeniably created the best ecosystem of camera carry equipment. The thinnest of their camera straps is a perfect fit for your X100. I&#039;m also carrying a <a href="https://amzn.to/41Xql52">Peak Design Cuff</a> in my backpack.</p><p>Available for <a href="https://amzn.to/3naPBpU">52,98 € on Amazon</a></p><p></p></blockquote><h3><a href="https://amzn.to/3LN6Zua">Apple SD Card to Lightning Adapter</a> (or <a href="https://amzn.to/3RtFn0f">USB-C</a>)</h3><blockquote><p>Unfortunately only the X100T and above ship with built in WiFi so this adapter comes in handy if you want to transfer images to your iPhone.</p><p>Currently <a href="https://amzn.to/3LN6Zua">35,00 € on Amazon</a></p><p></p></blockquote><h3><a href="https://amzn.to/46HU2cr">Charger &amp; Extra Batteries</a> (X100, X100S, X100T)</h3><blockquote><p>Currently <a href="https://amzn.to/3Ay4KVf">35,90 € on Amazon</a></p><p></p></blockquote><h3><a href="https://amzn.to/3oZyurM">Screen Protector</a></h3><blockquote><p>Available for <a href="https://amzn.to/3oZyurM">4,99 € on Amazon</a></p><p></p></blockquote>]]></summary>
<updated>2024-02-20T00:00:00+00:00</updated>
<link length="1381282" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/fujifilm-x100vi-2024-compared-to-x100-series/cover2.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Camera Gear you didn&#039;t know you needed in 2024</title>
<link href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024"></link>
<id>https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024</id>
<summary type="html"><![CDATA[<p>I bought and tested all items by myself - <strong>I have no affiliation with any company</strong> listed here. There are some Amazon affiliate links (*) included.</p><p>In the sense of sustainability don&#039;t be preassured to buy anything listed here unless it helps you to create!</p><h2>Dörr QC-2 (S) Lense Changer</h2><p>When I only carry a single camera body and needed to change lenses, I always ran into the inconvenience to take off my backpack and fumble around with lenses which takes time and</p><p>Especially when shooting concerts or protests, you need to <strong>have all your gear on hand</strong> which made me search for better alternatives.</p><p>The Dörr QC-2 Lense Changer has <strong>two attachment points for lenses</strong> (available for Sony E, Canon EF and Nikon F mounts) and can be carried around your body so you always have access to <strong>3 lenses at the same time</strong> (1x on the camera, 2x on the QC-2).</p><p><a href="https://www.doerr-foto.de/en-us/lenses/lens-accessories/accessories/lens-changer-qc-2s-sony-e-mount-306107">25,41 € on doerr-foto.de</a> (<a href="https://www.doerr-foto.de/en-us/lenses/lens-accessories/accessories/lens-changer-qc-2s-sony-e-mount-306107">Sony E</a>, <a href="https://www.doerr-foto.de/en-us/lenses/lens-accessories/accessories/lens-changer-qc-2c-canon-eos-306105">Canon EF</a>, <a href="https://www.doerr-foto.de/en-us/lenses/lens-accessories/accessories/lens-changer-qc-2n-nikon-f-mount-306106">Nikon F</a>)</p><p></p><hr><h2>Tenba Axis V2 Backpack</h2><p>If you knew me you&#039;d be familiar that I&#039;m a sucker for bagpacks. The Tenba Axis V2 (24L version here) is <strong>by far the best</strong> camera backpack I&#039;ve come across.</p><p>In this configuration I can easily carry: 1 Sony camera body, 3 lenses, 2 flashes, 1 compact camera, 1 Godox flash accessory kit, 1 Godox remote trigger, 1 cleaning kit, 2 straps, 1 carry vest, 1 rain cover.</p><p>Some of my favorite features:</p><ul><li><p>Quick access side pocket for camera body + 24-70mm lense</p></li><li><p>Quick access top pocket for misc items</p></li><li><p>2 chest straps, 1 detachable belly strap</p></li><li><p>Separate laptop deparment</p></li><li><p>Multiple smaller pockets for random stuff</p></li><li><p><strong>Molle</strong> attachment points all over the outside for additional pockets</p></li></ul><p>On the left side below the first aid kit you can also see my <a href="https://amzn.to/3vE585z">Tenba Tools Reload Battery</a> * pack which can hold 2 normal sized camera batteries for quick access. On the front you can also mount a tripod. The right water bottle comparment can fit up to a 32 oz Hydro Flask bottle.</p><p><a href="https://amzn.to/3vCOSln">263,99 € on Amazon</a> *</p><p></p><hr><h2>SMALLRIG Cold Shoe Camera Mount</h2><p>A light all-metal cold shoe mount for you smartphone which you can use for BTS footage or even self portraits.</p><p><a href="https://amzn.to/48Uawj9">24,52 € on Amazon</a> *</p><p></p><hr><h2>SMALLRIG Reflector &amp; Diffusor (24&quot;)</h2><p>This 5-in-1 reflector from smallrig is a great value for everyone who wants to shoot portraits with natural light. You can also use the white base part as a diffusor for an off-camera flash.</p><p><a href="https://amzn.to/3vyzOox">39,90 € on Amazon</a> *</p><p></p><hr><h2>GODOX S-R1 Magnetic Adapter</h2><p>If you have an older Godox flash with a rectangular mount and want to adapt <a href="https://amzn.to/48Ugroj"><strong>GODOX Accessories made for the V1 flash</strong></a> * you can do just that with the S-R1 magnetic adapter which screws on your <strong>TT-Series flash</strong>.</p><p><a href="https://amzn.to/4bc0b4j">9,99 € on Amazon</a> *</p><p></p><hr><h2>GODOX V1 Flash</h2><p>Probably the best and most versitile value flash out there.</p><p><a href="https://amzn.to/3vywnyh">228,00 € on Amazon</a> * (<em>but you can find it cheaper elsewhere</em>)</p><hr><h2>Shoudler Strap/Vest</h2><p>When shooting concerts, I normally carry two Sony bodies - one with a wide lense and a multi-purpose 24-70mm. This vest allows you to attach two cameras without having any straps interfering with another.</p><p><a href="https://amzn.to/48VHYpG">23,99 € on Amazon</a> *</p><p>I also 3D printed four attachment points for Peak Design anchors so I never have to switch out my ARCA-Swiss plate.</p><p>⬇️ <a href="https://romanzipp.com/assets/blog/camera-gear-you-didnt-know-you-needed-in-2024/Peak-Design-Anchor.zip"><strong>Download the .obj file for 3D printing</strong></a></p><p></p><hr><h2>SMALLRIG 71&quot; Tripod</h2><p>This is by far the <strong>best valued</strong> Tripod I encountered. All metal construction with a <strong>detachable leg for monopod</strong> operation!</p><p><a href="https://amzn.to/3vAeDCB">63,91 € on Amazon</a> *</p><p></p><hr><h2>Phone mount for ARCA-Swiss plate</h2><p>This metal constructed and sturdy adapter lets you mount any smartphone to a ARCA-Swiss fitted base plate. Handy if you want to use your iPhone on a tripod.</p><p><a href="https://amzn.to/48VG08I">25,89 € on Amazon</a> *</p><hr><h2>Sensor &amp; Camera Cleaning Kit</h2><p>Tihs UES brand camera cleaning kit includes everxthing you need to keep your sensor &amp; camera from dust and even comes with a sturdy case.</p><p><a href="https://amzn.to/3HmXYFs">22,99 € on Amazon</a> *</p><p></p><hr><h2>AA Battery Box</h2><p>Some flashes - especially from GODOX - still come with AA batteries which can be really frustrating to work with. Instead of tossing them in a garbage pocket of your backpack and losing track of which were already empty - just stuff them away easily with some labeled boxes.</p><p><a href="https://amzn.to/3vzIds6">6,98 € on Amazon</a> *</p><h2>Accessories featured</h2><ul><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#d%C3%B6rr-qc-2-s-lense-changer">Dörr QC-2 (S) Lense Changer</a></p></li><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#tenba-axis-v2-backpack">Tenba Axis V2 Backpack</a></p></li><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#smallrig-cold-shoe-camera-mount">SMALLRIG Cold Shoe Camera Mount</a></p></li><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#smallrig-reflector--diffusor-24">SMALLRIG Reflector &amp; Diffusor (24&quot;)</a></p></li><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#godox-s-r1-magnetic-adapter">GODOX S-R1 Magnetic Adapter</a></p></li><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#godox-v1-flash">GODOX V1 Flash</a></p></li><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#shoudler-strapvest">Shoudler Strap/Vest</a></p></li><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#smallrig-71-tripod">SMALLRIG 71&quot; Tripod</a></p></li><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#phone-mount-for-arca-swiss-plate">Phone mount for ARCA-Swiss plate</a></p></li><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#sensor--camera-cleaning-kit">Sensor &amp; Camera Cleaning Kit</a></p></li><li><p><a href="https://romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024#aa-battery-box">AA Battery Box</a></p></li></ul>]]></summary>
<updated>2024-01-16T00:00:00+00:00</updated>
<link length="2110316" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/camera-gear-you-didnt-know-you-needed-in-2024/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Fix Consul reboot loop</title>
<link href="https://romanzipp.com/blog/consul-fix-restart-loop"></link>
<id>https://romanzipp.com/blog/consul-fix-restart-loop</id>
<summary type="html"><![CDATA[<p>I&#039;ve recently encountered an issue with HasiCorp&#039;s Consul being stuck in a boot loop.</p><p>The Issue</p><p>Although the following lines may not be directly correlated with the issue, I chose to include them just in case anyone - like me - searches for those errors and actually has the same - but different problem.</p><h3>Systemd reports</h3><h3>Application logs</h3><p>Solution</p><p>Add the current server IP address to the <code>retry_join</code> array in your <code>consul.hcl</code> config.</p><p>Here you go.</p>]]></summary>
<updated>2023-10-06T00:00:00+00:00</updated>
<link length="978159" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/consul-fix-restart-loop/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Best Productivity Apps for macOS 2023</title>
<link href="https://romanzipp.com/blog/best-macos-productivity-apps-2023"></link>
<id>https://romanzipp.com/blog/best-macos-productivity-apps-2023</id>
<summary type="html"><![CDATA[<p>This is a curated but not complete list of my favorite productivity apps on macOS. I&#039;m constantly looking for new and interesting tools to try out. As everytime this list does not contain any referal links and is not endorsed by any company mentioned.</p><h2>1. AnyType</h2><p>AnyType is like Notion on sterodies - with privacy and security. Notion has been my go-to tool for organizing any strucutred and non-stuctured information which are not specific enough to been designated to a separate app.</p><p>My problem was always that I had to split up certain private and sensitive information because Notion is an online-first cloud service without E2EE (which <strong>doesn&#039;t even support two factor authentication</strong>). AnyType in contrast is an <strong>offline-first</strong> app with a possibility to sync data between devices on your <strong>local network</strong> with an equal - if not superior - featureset.</p><p><strong>Price</strong>: free (Open Source)</p><blockquote><p>the everything app for those who celebrate trust &amp; autonomy</p></blockquote><p></p><p></p><p><a href="https://anytype.io/">Download <strong>AnyType</strong></a></p><h2>2. TickTick</h2><p>TickTick is a seamingly simple reminder / ToDo app. The feature that sold me on TickTick (and is not supported by any other app right now) is importing &amp; deleting items from the iOS stock Reminders app which allows me to use Siri for creating tasks.</p><p><strong>Price</strong>: free ($36/year option)</p><p></p><p><a href="https://ticktick.com/">Download <strong>TickTick</strong></a></p><h2>3. Raycast</h2><p>If you find yourself on this blog post, you probably already heard about Raycast. If not: New &amp; hyped alternative to Alfred / built-in Spotlight.</p><p><strong>Price</strong>: free</p><p></p><p><a href="https://www.raycast.com/">Download <strong>Raycast</strong></a></p><h2>4. Reeder 5</h2><p>We need to make RSS feeds great again.</p><p><strong>Price</strong>: $ 9.99</p><p></p><p><a href="https://reederapp.com/">Download <strong>Reeder</strong></a></p><h2>5. Bike</h2><p>It seems that 30 bucks is a bit much for a simple outlining app which only supports basic layouting. But Bike allows me to quickly take notes and structure them in a hierarchy which is optimal for my workflow.</p><p>When researching topics, all notes firstly land in Bike.</p><p><strong>Price</strong>: $ 30.00</p><p></p><p><a href="https://www.hogbaysoftware.com/bike/">Download <strong>Bike</strong></a></p><h2>6. Deliveries</h2><p>Deliveries is an all-in-one parcel tracking app with support for a unholy amount of shipping providers. You can also forward your shipment notification mails to a provided address for automatic tracking.</p><p><strong>Price</strong>: 5,49 €/year (or 0,99 €/month)</p><p></p><p><a href="https://deliveries.app/en.html">Download <strong>Deliveries</strong></a></p><h2>7. Texifier</h2><p>LaTeX made easy.</p><p><strong>Price</strong>: 49,99 €</p><p></p><p><a href="https://romanzipp.com/blog/best-macos-productivity-apps-2023">Download <strong>Texifier</strong></a></p>]]></summary>
<updated>2023-09-18T00:00:00+00:00</updated>
<link length="486219" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/best-macos-productivity-apps-2023/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Get FUJIFILM X Webcam working on macOS</title>
<link href="https://romanzipp.com/blog/fujifilm-webcam-x-macos-issues"></link>
<id>https://romanzipp.com/blog/fujifilm-webcam-x-macos-issues</id>
<summary type="html"><![CDATA[<p>I&#039;ve been experiencing many issues using my FUJIFILM X-S10 as a webcam on macOS Ventura 13. This is the whole knowledge I could extract from various sources which helped me resolving most of my problems.</p><p>Make sure you <a href="https://fujifilm-x.com/de-de/support/download/software/x-webcam/">download the FUJIFILM X Webcam Software</a> first.</p><h2>Camera not available in macOS</h2><ul><li><p>Change your connection mode to USB Tether Shooting Auto <strong>SETUP</strong> → <strong>CONNECTION SETUP</strong> → <strong>CONNECTION MODE</strong> → <strong>USB TETHER SHOOTING AUTO</strong></p></li><li><p>Try changing your USB cable</p></li></ul><h4>Startup procedure</h4><ol start="1"><li><p>Start your FUJIFILM camera</p></li><li><p>Set the mode dial to <strong>P</strong></p></li><li><p>Flip out the display</p></li><li><p>Connect the camera to your Mac</p></li></ol><h2>Lagging video</h2><p>Following these steps will help and maybe fully resolve issue with stuttering or laggy video.</p><p>Notice that you need to disconnect your camera first in order to change any setting on your camera.</p><ul><li><p>Turn the mode dial to <strong>P</strong></p></li><li><p>Disable <strong>EYE AUTOFOCUS</strong></p></li><li><p>Switch focus mode to <strong>MANUAL FOCUS</strong></p></li><li><p>Change power mode to <strong>BOOST</strong><br><strong>SETUP</strong> → <strong>POWER MANAGEMENT</strong> → <strong>PERFORMANCE</strong> → <strong>BOOST</strong><br><strong>SETUP</strong> → <strong>POWER MANAGEMENT</strong> → <strong>BOOST SETTING</strong> → <strong>fps</strong></p></li><li><p>Try changing the <strong>DIGITAL ZOOM</strong> option in the FUJIFILM Webcam X Softare to a value greater than x1.0</p></li><li><p>Enable <strong>NATURAL LIVE VIEW</strong> on your camera<br><strong>SCREEN SETTING</strong> → <strong>NATURAL LIVE VIEW</strong> → <strong>ON</strong></p></li><li><p>Change <strong>DYNAMIC RANGE</strong> to 100</p></li></ul><h4>If you have a newer 2021 Fujifilm camera:</h4><ul><li><p>Select either AUTO or POWER SUPPLY OFF/COMM ON for USB POWER SUPPLY/COMM SETTING in the network/USB setting menu.</p></li><li><p>Choose 6: USB WEBCAM for SELECT CONNECTION SETTING.</p></li></ul><h2>Camera not available in Discord/FaceTime/...</h2><p>For me many apps such as Discord, FaceTime or WebEx won&#039;t recognize the FUJIFILM X Webcam softare as a camera. You can work around this by streaming your camera feed through OBS which will create a <em>virtual camera</em>.</p><ul><li><p>Download OBS Studio for macOS</p></li><li><p><a href="https://obsproject.com/wiki/MacOS-Virtual-Camera-Compatibility-Guide">Follow this guide on how to make you apps compatible</a></p></li></ul><h2>Last resort: Capture Card</h2><p>I also ended up using a Capture Card to get a clean and smooth feed from my camera. For the FUJIFILM X-S10 you will need a <a href="https://amzn.to/3OopGFV">left angled Micro HDMI cable</a>. I&#039;m using the <a href="https://amzn.to/3O0o1oH">Guermok 4k30 / 1080p60</a> which works just fine for video conferencing software. This solution costs around 27 € at the time of writing.</p><p></p><p>Make sure to enable &quot;Clean Feed HDMI Output&quot; to avoid getting UI overlays on your output.</p><h2>Sources</h2><ul><li><p><a href="https://fujifilm-dsc.com/en/manual/x-h2_connection/overview_usage/webcam/index.html">FUJIFILM: Using the Camera as a Webcam</a></p></li><li><p><a href="https://www.reddit.com/r/fujifilm/comments/ilcxux/fujfilm_x_webcam_very_choppy/">Reddit: Fujfilm X Webcam Very Choppy</a></p></li><li><p><a href="https://www.dpreview.com/forums/thread/4553229">DPReview: Fujifilm X Webcam Video Lag</a></p></li><li><p><a href="https://www.reddit.com/r/fujifilm/comments/s8lhpl/using_fujifilm_as_a_webcam_questions_and_answers/">Reddit: Using Fujifilm as a webcam, questions and answers</a></p></li></ul>]]></summary>
<updated>2023-07-04T00:00:00+00:00</updated>
<link length="1476741" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/fujifilm-webcam-x-macos-issues/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>All (good) FUJIFILM compact cameras - quick overview</title>
<link href="https://romanzipp.com/blog/all-fujifilm-compact-cameras-ever-made"></link>
<id>https://romanzipp.com/blog/all-fujifilm-compact-cameras-ever-made</id>
<summary type="html"><![CDATA[<p>When looking to buy a compact camera such as a the X100 (see my full <a href="https://romanzipp.com/blog/all-fujifilm-x100-cameras-comparison">X100 camera comparison here</a>) I stumbled across some fascinating devices you can still buy used.</p><p>I still ended up buying a used X100S but there are some awesome compact cameras which could fit your needs.</p><p>One of my main concerns is sensor size. I&#039;ve marked APS-C size sensor in bold.</p><ul><li><p>23,6 x 15,8 mm: APS-C sensor size</p></li><li><p>8,8 x 6,6 mm: smaller CMOS type sensor</p></li></ul><table><tbody><tr><th rowspan="1" colspan="1"><p>Brand</p></th><th rowspan="1" colspan="1"><p>Model</p></th><th rowspan="1" colspan="1"><p>Focal Length</p></th><th rowspan="1" colspan="1"><p>min. F</p></th><th rowspan="1" colspan="1"><p>Year</p></th><th rowspan="1" colspan="1"><p>MP</p></th><th rowspan="1" colspan="1"><p>Sensor</p></th><th rowspan="1" colspan="1"><p>Film Sims</p></th><th rowspan="1" colspan="1"><p>Price</p></th></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/X100V.aspx">X100V</a></p></td><td rowspan="1" colspan="1"><p>35mm</p></td><td rowspan="1" colspan="1"><p>F2</p></td><td rowspan="1" colspan="1"><p>2020</p></td><td rowspan="1" colspan="1"><p>26,1</p></td><td rowspan="1" colspan="1"><p><strong>23,6 x 15,8 mm</strong></p></td><td rowspan="1" colspan="1"><p>✅</p></td><td rowspan="1" colspan="1"><p>-</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/X100F.aspx">X100F</a></p></td><td rowspan="1" colspan="1"><p>35mm</p></td><td rowspan="1" colspan="1"><p>F2</p></td><td rowspan="1" colspan="1"><p>2017</p></td><td rowspan="1" colspan="1"><p>24,3</p></td><td rowspan="1" colspan="1"><p><strong>23,6 x 15,8 mm</strong></p></td><td rowspan="1" colspan="1"><p>✅</p></td><td rowspan="1" colspan="1"><p>1200 €</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/X100T.aspx">X100T</a></p></td><td rowspan="1" colspan="1"><p>35mm</p></td><td rowspan="1" colspan="1"><p>F2</p></td><td rowspan="1" colspan="1"><p>2014</p></td><td rowspan="1" colspan="1"><p>16,3</p></td><td rowspan="1" colspan="1"><p><strong>23,6 x 15,8 mm</strong></p></td><td rowspan="1" colspan="1"><p>✅</p></td><td rowspan="1" colspan="1"><p>700 €</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/X100S.aspx">X100S</a></p></td><td rowspan="1" colspan="1"><p>35mm</p></td><td rowspan="1" colspan="1"><p>F2</p></td><td rowspan="1" colspan="1"><p>2013</p></td><td rowspan="1" colspan="1"><p>16,3</p></td><td rowspan="1" colspan="1"><p><strong>23,6 x 15,8 mm</strong></p></td><td rowspan="1" colspan="1"><p>✅</p></td><td rowspan="1" colspan="1"><p>600 €</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/FinePix_X100.aspx">X100</a></p></td><td rowspan="1" colspan="1"><p>35mm</p></td><td rowspan="1" colspan="1"><p>F2</p></td><td rowspan="1" colspan="1"><p>2011</p></td><td rowspan="1" colspan="1"><p>12,3</p></td><td rowspan="1" colspan="1"><p><strong>23,6 x 15,8 mm</strong></p></td><td rowspan="1" colspan="1"><p>✅</p></td><td rowspan="1" colspan="1"><p>400 €</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/XF10.aspx">XF10</a></p></td><td rowspan="1" colspan="1"><p>28mm</p></td><td rowspan="1" colspan="1"><p></p></td><td rowspan="1" colspan="1"><p>2018</p></td><td rowspan="1" colspan="1"><p>24,2</p></td><td rowspan="1" colspan="1"><p><strong>23,6 x 15,8 mm</strong></p></td><td rowspan="1" colspan="1"><p>❌</p></td><td rowspan="1" colspan="1"><p>500 €</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/XF1.aspx">XF1</a></p></td><td rowspan="1" colspan="1"><p>25-100mm</p></td><td rowspan="1" colspan="1"><p></p></td><td rowspan="1" colspan="1"><p>2012</p></td><td rowspan="1" colspan="1"><p>12,3</p></td><td rowspan="1" colspan="1"><p>8,8 x 6,6 mm</p></td><td rowspan="1" colspan="1"><p>❌</p></td><td rowspan="1" colspan="1"><p>-</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/XQ2.aspx">XQ2</a></p></td><td rowspan="1" colspan="1"><p>25-100mm</p></td><td rowspan="1" colspan="1"><p></p></td><td rowspan="1" colspan="1"><p>2015</p></td><td rowspan="1" colspan="1"><p>12,3</p></td><td rowspan="1" colspan="1"><p>8,8 x 6,6 mm</p></td><td rowspan="1" colspan="1"><p>❌</p></td><td rowspan="1" colspan="1"><p>-</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/XQ1.aspx">XQ1</a></p></td><td rowspan="1" colspan="1"><p>25-100mm</p></td><td rowspan="1" colspan="1"><p></p></td><td rowspan="1" colspan="1"><p>2013</p></td><td rowspan="1" colspan="1"><p>12,3</p></td><td rowspan="1" colspan="1"><p>8,8 x 6,6 mm</p></td><td rowspan="1" colspan="1"><p>❌</p></td><td rowspan="1" colspan="1"><p>-</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/X70.aspx">X70</a></p></td><td rowspan="1" colspan="1"><p>28mm</p></td><td rowspan="1" colspan="1"><p></p></td><td rowspan="1" colspan="1"><p>2016</p></td><td rowspan="1" colspan="1"><p>16,7</p></td><td rowspan="1" colspan="1"><p><strong>23,6 x 15,8 mm</strong></p></td><td rowspan="1" colspan="1"><p>❌</p></td><td rowspan="1" colspan="1"><p>650 €</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/X30.aspx">X30</a></p></td><td rowspan="1" colspan="1"><p>28-112mm</p></td><td rowspan="1" colspan="1"><p></p></td><td rowspan="1" colspan="1"><p>2014</p></td><td rowspan="1" colspan="1"><p>12,3</p></td><td rowspan="1" colspan="1"><p>8,8 x 6,6 mm</p></td><td rowspan="1" colspan="1"><p>❌</p></td><td rowspan="1" colspan="1"><p>490 €</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/X20.aspx">X20</a></p></td><td rowspan="1" colspan="1"><p>28-112mm</p></td><td rowspan="1" colspan="1"><p></p></td><td rowspan="1" colspan="1"><p>2013</p></td><td rowspan="1" colspan="1"><p>12,3</p></td><td rowspan="1" colspan="1"><p>8,8 x 6,6 mm</p></td><td rowspan="1" colspan="1"><p>❌</p></td><td rowspan="1" colspan="1"><p>450 €</p></td></tr><tr><td rowspan="1" colspan="1"><p>Fujifilm</p></td><td rowspan="1" colspan="1"><p><a href="https://www.digitalkamera.de/Kamera/Fujifilm/FinePix_X10.aspx">X10</a></p></td><td rowspan="1" colspan="1"><p>28-112mm</p></td><td rowspan="1" colspan="1"><p></p></td><td rowspan="1" colspan="1"><p>2011</p></td><td rowspan="1" colspan="1"><p>12,3</p></td><td rowspan="1" colspan="1"><p>8,8 x 6,6 mm</p></td><td rowspan="1" colspan="1"><p>✅</p></td><td rowspan="1" colspan="1"><p>200 €</p></td></tr></tbody></table>]]></summary>
<updated>2023-06-28T00:00:00+00:00</updated>
<link length="279850" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/all-fujifilm-compact-cameras-ever-made/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Best Utility Tools &amp; Apps for macOS 2023</title>
<link href="https://romanzipp.com/blog/best-macos-utility-tools-apps-2023"></link>
<id>https://romanzipp.com/blog/best-macos-utility-tools-apps-2023</id>
<summary type="html"><![CDATA[<p>Here you go, a short list of my most loved utility apps on macOS.</p><h2>1. CleanShot X</h2><p><strong>Price</strong>: $ 29.00</p><p>CleanShot is a supercharged screenshot utility which adds tons of functionality compared to the built-in macOS screenhot utility. CleanShot can be <a href="https://cleanshot.sjv.io/R5KeDR">bought</a> as a one-time payment or used with a $8/mo <a href="https://cleanshot.sjv.io/R5KeDR">subscription</a> if you need their cloud service.</p><p><a href="https://cleanshot.sjv.io/R5KeDR">Download <strong>Cleanshot</strong></a></p><h2>2. AirBuddy</h2><p>AirBuddy is a macOS app that seamlessly connects AirPods or other Bluetooth headphones to your Mac, providing a convenient and efficient way to switch between devices with ease.</p><p><strong>Price</strong>: 12,99 €</p><p><a href="https://v2.airbuddy.app/">Download <strong>AirBuddy</strong></a></p><h2>3. Little Snitch</h2><p>Little Snitch is a powerful macOS app that allows users to monitor and control outgoing network connections, providing an enhanced level of privacy and security by keeping a close eye on all the data leaving their Mac.</p><p>Approving an denying ever connection can be a bit tedious but it&#039;s worth it to deny apps syping on you or even stop malware to connect to remote servers.</p><p><strong>Price</strong>: 69,00 €</p><p><a href="https://www.obdev.at/products/littlesnitch/index.html">Download <strong>Little Snitch</strong></a></p><h2>4. Rectangle</h2><p>Rectangle is a handy macOS app that enables users to efficiently manage their windows by offering customizable keyboard shortcuts and easy window resizing options, making multitasking and organizing workspaces a breeze.</p><p><strong>Price</strong>: free + Open Source</p><p><a href="https://github.com/rxhanson/Rectangle/releases">Download <strong>Rectangle</strong> on <strong>GitHub</strong></a></p><h2>5. ForkLift</h2><p>I am storing much of my data on a NAS in my home network. Unfortunately, Finder does not work great with SMB shares resuling in long copy times, directories take forever to load and the Finder gets unresponsive regurarily. ForkLift has a much better support for network shares.</p><p><strong>Price</strong>: $ 19,95</p><p><a href="https://binarynights.com/store">Download <strong>ForkLift</strong></a></p><h2>6. Easy Move+Resize</h2><p>Easy Move+Resize is a convenient macOS app that simplifies window management by providing intuitive keyboard shortcuts and mouse gestures, making it effortless to move and resize windows on your Mac for optimal productivity.</p><p><strong>Price</strong>: free + Open Source</p><p>There is also an alternative app called <a href="https://github.com/finestructure/Hummingbird">Hummingbird</a> which has a similar functionality and is originally inspired by Easy Move+Resiize but allows you to move &amp; resize any windows without clicking.</p><p><a href="https://github.com/dmarcotte/easy-move-resize">Download <strong>Easy Move+Resize</strong> on <strong>GitHub</strong></a></p><h2>7. Linear Mouse</h2><p>Linear Mouse allows you to modify the scrolling &amp; acceleration preferences of any non-Apple mouse.</p><p><strong>Price</strong>: free + Open Source</p><p><a href="https://github.com/linearmouse/linearmouse">Download <strong>Linear Mouse</strong> on <strong>GitHub</strong></a></p><h2>8. Pure Paste</h2><p>Pure Paste is a utility that cleans the copy+paste stash from any formatting. Allowing you to copy text from any WYSIWYG editor to another without messing up the formatting.</p><p><strong>Price</strong>: free</p><p><a href="https://sindresorhus.com/pure-paste">Download <strong>Pure Paste</strong> from the <strong>App Store</strong></a></p>]]></summary>
<updated>2023-06-28T00:00:00+00:00</updated>
<link length="554243" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/best-macos-utility-tools-apps-2023/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Run Cloudflare Tunnel for Lando service container</title>
<link href="https://romanzipp.com/blog/run-cloudflare-tunnel-for-lando-service"></link>
<id>https://romanzipp.com/blog/run-cloudflare-tunnel-for-lando-service</id>
<summary type="html"><![CDATA[<p>This post will guide you through creating a <a href="https://www.cloudflare.com/products/tunnel/">Cloudflare Tunnel</a> for a local <a href="https://lando.dev/">Lando</a> service container.</p><h2>Prequisites</h2><p>You will need...</p><ul><li><p>A <a href="https://dash.cloudflare.com/">Cloudflare</a> account</p></li><li><p>A <strong>domain</strong> connected to your Cloudflare account which will be used to route external traffic</p></li><li><p><a href="https://lando.dev/">Lando</a> with a configured project</p></li></ul><h2>Create Tunnel</h2><ol start="1"><li><p>Create a new directory <code>.cloudflare</code> in your project root</p></li><li><p><a href="https://dash.cloudflare.com/argotunnel">Authorize Argo Tunnel for Domain</a></p><ul><li><p>Select your <strong>domain</strong></p></li><li><p>A file <code>cert.pem</code> will be starting to download</p></li></ul></li><li><p>Store <code>cert.pem</code> in <code>.cloudflare/cert.pm</code></p></li><li><p>Run <code>cloudflared tunnel --config=.cloudflare/config.yml --origincert=./.cloudflare/cert.pem create &quot;RabbitHole&quot;</code></p></li><li><p>The output should be</p><blockquote><p>Created tunnel RabbitHole with id <code>&lt;TUNNEL-ID&gt;</code></p></blockquote></li><li><p>Set the value of the <code>tunnel</code> attribute in <code>.cloudflare/config.yml</code> to the previously returned <code>&lt;TUNNEL-ID&gt;</code></p><blockquote><p>For example <code>tunnel: fbedd849-eadc-47f1-82aa-02458008fd2f</code></p></blockquote></li><li><p>Create <strong>DNS CNAME</strong> record with any custom subdomain (like &quot;local.domain.tld&quot;) pointing to <code>&lt;TUNNEL-ID&gt;.cfargotunnel.com</code></p></li><li><p>Start Tunnel via the script below</p></li></ol><h2>Start Tunnel</h2><p>In my case I want to expose the <code>appserver_nginx</code> Lando service to the tunnel.</p><p>You can debug all requests using the <code>--loglevel debug</code> flag.</p><h3>Fin</h3><p>You should now reach your Lando service externally using your previously added CNAME DNS record (&quot;local.domain.tld&quot;).</p>]]></summary>
<updated>2023-06-07T00:00:00+00:00</updated>
<link length="181036" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/run-cloudflare-tunnel-for-lando-service/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>All FUJIFILM X100 cameras compared + X100VI</title>
<link href="https://romanzipp.com/blog/all-fujifilm-x100-cameras-comparison"></link>
<id>https://romanzipp.com/blog/all-fujifilm-x100-cameras-comparison</id>
<summary type="html"><![CDATA[<p>I recently made the decision to buy a X100 camera in addition to my <a href="https://amzn.to/40YFeDD">FUJIFILM X-S10</a> for an always-carry option. Unfortunately the recent hype around the X100V caused an explosion in prices - also for used cameras.</p><p>But which of the FUJIFILM X100 series cameras is the best fit? I watched many YouTube videos and read articles but haven&#039;t found any compact comparison chart with all important key facts - <strong>so I made one</strong>. In this comprehensive blog post, I&#039;ll compare and contrast all of the X100 models - from the original X100 to the latest X100VI.</p><ul><li><p>FUJIFILM <strong>X100</strong> FinePix (<a href="https://dl.fujifilm-x.com/support/manual/x/finepix_x100_manual_de.pdf">Manual</a>)</p></li><li><p>FUJIFILM <strong>X100S</strong> (<a href="https://dl.fujifilm-x.com/support/manual/x/fujifilm_x100s_manual_en.pdf">Manual</a>)</p></li><li><p>FUJIFILM <strong>X100T</strong> (<a href="https://dl.fujifilm-x.com/de-de/handbuecher/X100T.pdf">Manual</a>)</p></li><li><p>FUJIFILM <strong>X100F</strong> (<a href="https://fujifilm-dsc.com/en-int/manual/x100f/x100f_omw_en_s_f.pdf">Manual</a>)</p></li><li><p>FUJIFILM <strong>X100V</strong> (<a href="https://fujifilm-dsc.com/en-int/manual/x100v/x100v_omw_en_s_f.pdf">Manual</a>)</p></li><li><p>FUJIFILM <strong>X100VI</strong> (<a href="https://fujifilm-dsc.com/en/manual/x100vi/x100vi_manual_en_s_f.pdf">Manual</a>)</p></li></ul><h2>Comparison</h2><p>This is by no means a complete feature list - but rather important key facts that were important to me like film simulations, screen size, autofocus systems or sensor types. You can also <a href="/assets/blog/all-fujifilm-x100-cameras-comparison/fujifilm-x100-comparison.pdf">download this table as PDF</a>.</p><h2>Accessories</h2><p>Here are some accessories I use for my X100S that I <strong>actually own and like</strong>. Of course, you can buy all items on amazon via the referral link - you know how it goes!</p><h4><a href="https://amzn.to/3Lthodr">Tiffen GLIMMERGLASS 1 Filter 49mm</a></h4><blockquote><p>The <a href="https://amzn.to/3Lthodr">Tiffen Glimmerglass</a> filter adds a kind of cinema-like bloom to your images without being too intruding like the <a href="https://amzn.to/412KgyB">Black Pro-Mist</a> filter. All of <a href="https://romanzipp.com/photos">my X100S images</a> are taken with the Glimmerglass filter. See <a href="https://youtu.be/rFZRWbnLrs4">GxAce&#039;s video</a> on the filter for some great examples.</p><p>Currently <a href="https://amzn.to/3Lthodr">64,77 € on Amazon</a></p></blockquote><h4><a href="https://amzn.to/3VtjDll">Haoge LAR-X100W 49mm Adapter Ring</a></h4><blockquote><p>To use any 49mm filter on your Fujifilm X100 series camera you need a adapter ring. Otherwise the lense element will touch the filter glass resulting in an error and <strong>possibly damaging</strong> your camera in the long run.</p><p>Available for only <a href="https://amzn.to/3AKigFB">9,99 € on Amazon</a></p></blockquote><p></p><h4><a href="https://amzn.to/445p79U">Shutter Button</a></h4><blockquote><p>There is a custom red konkav and konvex shutter button included in this kit.</p><p>Currently <a href="https://amzn.to/445p79U">7,94 € on Amazon</a></p><p></p></blockquote><h4><a href="https://amzn.to/3VcJKgb">Thumb Grip</a></h4><blockquote><p>A great advantage of the X100 series is it&#039;s compact formfactor - which is also one of its negativ points. You can greatly increase your grip with a custom thumb grip which fits perfectly in the hot shoe.</p><p>Available for <a href="https://amzn.to/40HIW43">7,44 € on Amazon</a></p><p></p></blockquote><h4><a href="https://amzn.to/445JEet">Hot Shoe Cover</a></h4><blockquote><p>If you feel like a thumb grip is not necessary, a neat hot shoe cover with the &quot;FUJIFILM X&quot; logo can be a great fit. I am rocking this cover item on my X-S10.</p><p>Currently <a href="https://amzn.to/445JEet">12,08 € on Amazon</a></p><p></p></blockquote><h4><a href="https://amzn.to/40YOg3v">Peak Design Leash</a></h4><blockquote><p>Peak Design has undeniably created the best ecosystem of camera carry equipment. The thinnest of their camera straps is a perfect fit for your X100. I&#039;m also carrying a <a href="https://amzn.to/41Xql52">Peak Design Cuff</a> in my backpack.</p><p>Available for <a href="https://amzn.to/3naPBpU">52,98 € on Amazon</a></p><p></p></blockquote><h4><a href="https://amzn.to/3LN6Zua">Apple SD Card to Lightning Adapter</a> (or <a href="https://amzn.to/3RtFn0f">USB-C</a>)</h4><blockquote><p>Unfortunately only the X100T and above ship with built in WiFi so this adapter comes in handy if you want to transfer images to your iPhone.</p><p>Currently <a href="https://amzn.to/3LN6Zua">35,00 € on Amazon</a></p><p></p></blockquote><h4><a href="https://amzn.to/46HU2cr">Charger &amp; Extra Batteries</a> (X100, X100S, X100T)</h4><blockquote><p>Currently <a href="https://amzn.to/3Ay4KVf">35,90 € on Amazon</a></p><p></p></blockquote><h4><a href="https://amzn.to/3oZyurM">Screen Protector</a></h4><blockquote><p>Available for <a href="https://amzn.to/3oZyurM">4,99 € on Amazon</a></p><p></p></blockquote>]]></summary>
<updated>2023-04-27T00:00:00+00:00</updated>
<link length="410816" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/all-fujifilm-x100-cameras-comparison/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>IT Security Guide (DE)</title>
<link href="https://romanzipp.com/blog/it-security-guide-de"></link>
<id>https://romanzipp.com/blog/it-security-guide-de</id>
<summary type="html"><![CDATA[<p>IT Security Guide</p><p>Wir haben hier einen kleinen, kompakten Guide erstellt, der eine Sensibilisierung im Thema der IT-Sicherheit herstellen soll und eine Orientierung mit konkreten Maßnahmen vorgibt. Auch wenn die hier angeführten Maßnahmen nicht sehr komfortabel erscheinen und zusätzliche Schritte im Alltag erfordern, ist die digitale Sicherheit heutzutage um so wichtiger.</p><p>Alle hier empfohlenen Apps sind open source &amp; kostenlos und wurden von mir genutzt oder mindestens evaluiert.</p><p>Datensicherheit</p><ol start="1"><li><p>Welche <strong>sensiblen Daten</strong> sind wo gespeichert? (Sensible Daten sind beispielsweise Dokumente, Fotos, Kontaktdaten) Prüfe auch, ob sensible Daten auf Fotos in deiner synchronisierten Fotobibliothek vorhanden sind. (Fotos von Ausweis/Führerschein)</p></li><li><p>Vermeide, sensible Daten auf <strong>Cloud-Speichern</strong> zu hinterlegen (Dropbox, Google Drive, iCloud)</p></li><li><p><strong>Achtung</strong>: Wenn du sensible Daten gelöscht hast, entferne diese auch aus dem <strong>Papierkorb</strong></p></li><li><p>Beschränke auch den <strong>physischen Zugriff</strong> zu Daten. (Passwörter und PINs bei Smartphones, Laptops, Desktop-Rechnern. Festplatten mit Passwörtern sichern)</p></li><li><p>Stelle sicher und teste, dass du deine Geräte jederzeit entfernt <strong>orten und sperren</strong> kannst.</p></li></ol><h3>Backups</h3><ul><li><p>Stelle sicher, dass du jederzeit den Verlust deiner Daten - beispielsweise durch Schadsoftware - auf Rechner und Smartphone verkraften kannst. (<em>Desaster Recovery</em>)</p></li><li><p>Dafür sind <strong>regelmäßige Backups</strong> von wichtigen Daten erforderlich</p></li><li><p>Stelle sicher, dass die Speichermedien für das Backup <strong>nicht dauerhaft</strong> mit dem Computer und/oder Netzwerk verbunden sind.</p></li></ul><h3>Allgemeine Hinweise</h3><ul><li><p>Versuche, so wenig Daten wie möglich anfallen zu lassen. Daten, die nicht anfallen, können auch nicht abhanden kommen.</p></li><li><p>Dein persönliches Sicherheitskonzept nur so sicher wie das schwächste Glied in der Kette.</p></li></ul><p>Accountsicherheit</p><h2>Passwörter</h2><p>Mit einem <strong>Passwort-Manager</strong> bewegt man sich nicht nur <strong>sicherer</strong> sondern auch <strong>schneller und effizienter</strong> durchs Internet.</p><ul><li><p>Der eingebaute Passwortmanagers des Browsers (Chrome/Firefox) sollte auf alle Fälle <strong>vermieden</strong> werden.</p></li><li><p>Jeder Dienst/Website/App sollte ein <strong>eindeutiges, langes Passwort</strong> haben. (mindestens 16 Stellen)</p></li><li><p>Mit dem <strong>Master-Passwort</strong> sicherst du den Zugriff zu deinem Passwort-Manager.</p><ul><li><p>An das Master-Passwort solltest du dich <strong>leichter erinnern</strong> können. Es muss dennoch lang und komplex genug sein. (z.B. ein ausgedachter Satz)</p></li><li><p>Das Master-Passwort sollte <strong>niemals aus persönlichen Informationen</strong> bestehen (Geburtsdatum, Wohnort, Automarke o.ä.)</p></li><li><p>Das Master-Passwort sollte <strong>niemals irgendwo digital abgelegt</strong> werden.</p></li></ul></li><li><p>Stelle sicher, dass du <strong>jederzeit von überall Zugriff</strong> auf den Passwort-Manager hast. Die meisten Passwort-Manager verfügen über eine Cloud-Synchonisierung. Diese ist idR sicher und wird dringend empfohlen.</p></li><li><p>Wenn möglich, aktiviere die 2-Faktor Anmeldung auch für deinen Passwort Manager (mehr dazu im folgenden Absatz)</p></li></ul><h3>Passwort-Manager Empfehlungen:</h3><ul><li><p>Bitwarden <a href="https://bitwarden.com">https://bitwarden.com</a> (Alle Plattformen, iOS, Android, Desktop, Browser Add-On, uvm. inkl. Synchronisation)</p></li></ul><h2>2-Faktor Anmeldung</h2><p>Es sollte für alle Accounts die 2-Faktor Anmeldung aktiviert sein. Dabei muss bei jedem neuen Login für einen geschützten Dienst ein automatisch generierter Code von einem anderen Gerät (“der 2. Faktor”) eingegeben werden.</p><ul><li><p>Aktiviere die 2-Faktor Anmeldung für alle Accounts, bei denen es möglich ist.</p></li><li><p>Nachdem du die 2-Faktor Anmeldung bei einem Dienst aktiviert hast, werden oft <strong>Backup-Codes</strong> generiert. Diese <strong>sicher</strong> speichern.</p></li><li><p>Die 2-Faktor Anmeldung über <strong>SMS</strong> sollte <strong>vermieden werden</strong> - ist aber besser als garnichts.</p></li><li><p>Erstelle regelmäßig ein Backup der 2-Faktor Authenticator App.</p></li></ul><p>⚠️ Mit dem Verlust der 2-Faktor Authenticator App geht auch der Zugang zum Konto selbst verloren.</p><h3>2-Faktor Authenticator App Empfehlungen:</h3><ul><li><p><strong>iOS</strong>: Ravio Authenticator <a href="https://apps.apple.com/de/app/raivo-authenticator/id1459042137">https://apps.apple.com/de/app/raivo-authenticator/id1459042137</a></p></li><li><p><strong>iOS</strong>: 2FAS <a href="https://apps.apple.com/us/app/2fa-authenticator-2fas/id1217793794">https://apps.apple.com/us/app/2fa-authenticator-2fas/id1217793794</a></p></li><li><p><strong>Android</strong>: Aegis Authenticator <a href="https://play.google.com/store/apps/details?id=com.beemdevelopment.aegis">https://play.google.com/store/apps/details?id=com.beemdevelopment.aegis</a></p></li><li><p><strong>Android</strong>: 2FAS <a href="https://play.google.com/store/apps/details?id=com.twofasapp">https://play.google.com/store/apps/details?id=com.twofasapp</a></p></li></ul><p>Der <strong>Google Authenticator</strong> sollte <strong>auf keinen Fall</strong> genutzt werden! *</p><h3>Wichtige zu sichernde Dienste:</h3><ul><li><p>Cloud-Speicher (Dropbox)</p></li><li><p>Social-Media (Twitter, Instagram, TikTok, Discord, Twitch)</p></li><li><p>Finanz-Apps (PayPal, Banking, Investment)</p></li><li><p><strong>Google</strong> <a href="https://myaccount.google.com/signinoptions/two-step-verification">https://myaccount.google.com/signinoptions/two-step-verification</a></p></li><li><p><strong>Apple</strong> <a href="https://appleid.apple.com/account/manage">https://appleid.apple.com/account/manage</a></p></li><li><p><strong>Microsoft</strong> <a href="https://account.microsoft.com/security">https://account.microsoft.com/security</a></p></li></ul><h2>Zugriffe</h2><ul><li><p><strong>Welche Personen</strong> haben noch Zugriff auf deine Accounts?</p><ul><li><p>Ist dieser Zugriff <strong>zwingend notwendig</strong>?</p></li><li><p>Ist der Zugriff von weiteren Personen mit 2-Faktor Anmeldung geschützt?</p></li></ul></li><li><p>Aktiviere Benachrichtigungen über neue Logins (standardmäßig oft aktiv)</p></li><li><p>Haben <strong>andere Dienste</strong> Zugriff auf meine Accounts?</p></li></ul><p>Auf vielen Diensten kann man sich über seine bestehenden Accounts anmelden (z.B. “Login mit Google”).<br>Diese Dienste haben damit bestimmte Zugriffsrechte auf deinen Accounts. (z.B. im eigenen Namen Tweets verfassen, auf Kontakte zugreifen etc.)<br>Prüfe, welche Anwendung Zugriff auf wichtige Accounts haben und entferne diese, wenn sie nicht zwingend notwendig sind. (Diese Liste ist selbstverständlich nicht vollständig)</p><ul><li><p><strong>Google</strong> <a href="https://myaccount.google.com/permissions">https://myaccount.google.com/permissions</a></p></li><li><p><strong>Apple</strong> <a href="https://appleid.apple.com/account/manage/section/security">https://appleid.apple.com/account/manage/section/security</a></p></li><li><p><strong>Twitter</strong> <a href="https://twitter.com/settings/connected_apps">https://twitter.com/settings/connected_apps</a></p></li></ul><p>Instagram, TikTok, Discord …</p><ul><li><p>Welche Smartphone <strong>Apps</strong> haben welche Berechtigungen? Entferne nicht notwendige Berechtigungen.</p></li><li><p>Sind <strong>alte Geräte</strong> in deinem Google/Apple Account registriert? Diese bei Bedarf entfernen.</p><ul><li><p><strong>Google:</strong> <a href="https://myaccount.google.com/security">https://myaccount.google.com/security</a></p></li><li><p><strong>Apple:</strong> <a href="https://appleid.apple.com/account/manage/section/devices">https://appleid.apple.com/account/manage/section/devices</a></p></li></ul></li></ul><h2>Gerätesicherheit</h2><ul><li><p>Windows: Prüfe, ob der <strong>Windows Defender</strong> aktiviert ist. Antivirus/Antimalwaresoftware von anderen Herstellern ist nicht zwingend notwendig und kann sogar ein Risiko sein.</p></li><li><p>Prüfe welche Anwendungen auf dem Gerät installiert sind und/oder im Hintergrund laufen. Bei unbekannten Diensten den Namen googlen und/oder Experten konsultieren.</p></li></ul><h2>Phishing</h2><ul><li><p>Sei vorsichtig, wenn du auf <strong>Links aus externen Quellen</strong> klickst</p></li><li><p>Stimmt die <strong>Internetadresse</strong> genau überein?</p></li><li><p>Wirst du per E-Mail aufgefordert, eine Aktion in deinem Konto vorzunehmen (bsp. PayPal möchte dass du dein Passwort aktualisierst), besuche die Internetseite selbst im Browser anstatt auf den Link zu klicken.</p></li><li><p><strong>Ad-Blocker</strong> haben oft eingebaute Phishing &amp; Malware Filter Empfehlung: uBlock Origin <a href="https://ublockorigin.com/">https://ublockorigin.com/</a></p></li><li><p>Dein <strong>Passwort-Manager</strong> (als Browser Add-On) wird dir ein Passwort nicht vorschlagen, wenn die Adresse nicht exakt übereinstimmt. Der Passwort-Manager wird dich beispielsweise niemals bei einer betrügerischen Seite <code>services-paypal.scam</code> mit deinen <code>paypal.com</code> Zugangsdaten anmelden lassen.</p></li></ul><p>Roman Zipp, <a href="mailto:ich@ich.wtf">ich@ich.wtf</a>, Version 03-2024</p><h2>Footnotes</h2><p>* Bei Verlust des Zugriff auf das Google Konto wird auch der Google Authenticator gesperrt.</p>]]></summary>
<updated>2023-04-26T00:00:00+00:00</updated>
<link length="128105" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/it-security-guide-de/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Connect to any Lando service via Shell alias</title>
<link href="https://romanzipp.com/blog/open-database-tableplus-lando-cli"></link>
<id>https://romanzipp.com/blog/open-database-tableplus-lando-cli</id>
<summary type="html"><![CDATA[<p>When using <a href="https://lando.dev">Lando</a> as local development tooling, you will be familiar that localhost <strong>ports get assigned randomly</strong>. This can be tricky if you need to connect to a container regurarily.</p><p>This is a short shell function which builds a MySQL/MariaDB connection URI string using the <code>lando</code> and <code>jq</code> binaries.</p><h2>Install jq</h2><p><a href="https://stedolan.github.io/jq/">JQ</a> is a lightweight and flexible command-line JSON processor made by <a href="https://github.com/stedolan">Stephen Dolan</a> which is used to extract details form the <code>lando info</code> JSON output.</p><h4>macOS</h4><h4>Ubuntu</h4><h4>Windows</h4><p><a href="https://stedolan.github.io/jq/download/">See official install guide</a>.</p><h2>Shell function</h2><p>Of course, you can alter the function to output any combination of connection details.</p><p>This example always uses the <code>database</code> lando service.</p><p></p>]]></summary>
<updated>2023-04-24T00:00:00+00:00</updated>
<link length="193391" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/open-database-tableplus-lando-cli/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Nomad reserved memory &amp; CPU &quot;OOM killed&quot; issue</title>
<link href="https://romanzipp.com/blog/nomad-oom-killed-out-of-memory-fix"></link>
<id>https://romanzipp.com/blog/nomad-oom-killed-out-of-memory-fix</id>
<summary type="html"><![CDATA[<p>I recently ran into an issue where Nomad has reserved too much CPU &amp; memory althoough configured otherwise. This can result in tasks being killed by the OOMKill.</p><h2>Workaround</h2><p>There is a workaround by overriding the available memory and/or CPU power in your Nomad client config file.</p><h2>Nomad client config</h2><p>You can compute your &quot;real&quot; CPU compute power by multiplying the number of cores with the MHz. Example: 4 core CPU with 2 GHz each = <code>4 * 2000</code> = <code>8000</code>.</p><p>To get your CPUs clock speed, use the lscpu util:</p><p>The Nomad client config is located at <code>/etc/nomad/nomad.hcl</code> by default.</p><h3>Sources</h3><ul><li><p><a href="https://developer.hashicorp.com/nomad/docs/configuration/client#network_speed">client Block - Nomad Docs</a></p></li><li><p><a href="https://github.com/hashicorp/nomad/issues/5672">Allow for 0 res allocations / Disable resource constraints for particular agent #5672</a></p></li><li><p><a href="https://medium.com/@souri.rv/hashicorp-nomad-and-the-memory-options-with-the-docker-driver-59960fea0f23">Hashicorp Nomad and the memory options with the docker driver</a></p></li></ul>]]></summary>
<updated>2023-04-24T00:00:00+00:00</updated>
<link length="725142" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/nomad-consul-bind-wrong-interface-public-ip/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Reset Calendar App on macOS</title>
<link href="https://romanzipp.com/blog/reset-apple-calendar-on-macos"></link>
<id>https://romanzipp.com/blog/reset-apple-calendar-on-macos</id>
<summary type="html"><![CDATA[<p>I recently ran into an issue where my CalDAV provider went down for a couple of hours so many synced events were displayed as duplicates in my macOS Calendar app. The CalDAV account was configured via a <a href="https://developer.apple.com/documentation/devicemanagement/profile">Profile</a> so removing it meant I also needed to re-configure my mail account.</p><h2>Reset Calendar.app</h2><p>Fortunately there&#039;s a way to reset all synced events <strong>without loosing any preferences</strong>.</p><ol start="1"><li><p>Quit the Calendar app</p></li><li><p>In Finder: Go to <strong>Users ▸ You Profile ▸ Library ▸ Calendars</strong></p><ul><li><p><em>If you don&#039;t see the <strong>Library</strong> folder, press <strong>CMD ⌘ + Shift ⇧ + . (Dot)</strong></em></p></li></ul></li><li><p>Delete the following files:</p><ul><li><p><code>Calendar.sqlitedb</code></p></li><li><p><code>Calendar.sqlitedb-shm</code></p></li><li><p><code>Calendar.sqlitedb-wal</code></p></li></ul></li></ol><p>Now, re-open the Calendar app, press <strong>CMD ⌘ + R</strong> and wait for the calendars &amp; events to re-sync cleanly. This can take a couple of minutes based on the size of your remote calendars.</p><p>If you&#039;re missing any items in the sidebar, go to <strong>Settings ▸ Accounts</strong> and <strong>toggle &quot;Enable the account&quot;</strong>.</p>]]></summary>
<updated>2023-04-14T00:00:00+00:00</updated>
<link length="362139" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/reset-apple-calendar-on-macos/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Plausible self-hosted with Docker and Nomad</title>
<link href="https://romanzipp.com/blog/plausible-self-host-docker-nomad"></link>
<id>https://romanzipp.com/blog/plausible-self-host-docker-nomad</id>
<summary type="html"><![CDATA[<p>This guide will show you how to host Plausible on Nomad &amp; Consul. Please see the <a href="https://plausible.io/docs/self-hosting">Plausible self-hosting Docs</a> for more information.</p><h2>Requirements</h2><ul><li><p>Docker</p></li><li><p><a href="https://www.nomadproject.io/">Nomad</a></p></li><li><p><a href="https://www.consul.io/">Consul</a></p></li></ul><h2>Prequisites</h2><ol start="1"><li><p>Note that this templates uses the Nomad Server <code>client.disable_file_sandbox</code> option se we can mount the environment config file as env values</p></li><li><p>Create a <strong>folder on your host machine</strong>. In the example we will use <code>/mnt/plausible</code></p></li><li><p>Update the values in <code>plausible-conf.env</code></p></li></ol><h3>Folder tree</h3><h3><code>plausible-conf.env</code></h3><h2>Nomad Job Template</h2><p></p>]]></summary>
<updated>2023-04-11T00:00:00+00:00</updated>
<link length="150271" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/plausible-self-host-docker-nomad/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Get started with HashiCorp Nomad &amp; Consul</title>
<link href="https://romanzipp.com/blog/get-started-with-hashi-nomad-consul"></link>
<id>https://romanzipp.com/blog/get-started-with-hashi-nomad-consul</id>
<summary type="html"><![CDATA[<h2>About this Guide</h2><p>This post will guide you through the initial setup of <a href="https://www.nomadproject.io/">Nomad</a>, <a href="https://www.consul.io/">Consul</a> and <a href="https://www.vaultproject.io/">Vault</a>.</p><p>Additionally, I will cover some common additional steps for</p><ul><li><p>AWS CLI (for ECR)</p></li><li><p>Docker (+ Authentication)</p></li></ul><h2>1. Prequisites</h2><h3>CNI Bridge</h3><p>Nomad uses CNI plugins to configure the network namespace used to secure the Consul service mesh sidecar proxy. All Nomad client nodes using network namespaces must have CNI plugins installed. See the <a href="https://www.nomadproject.io/docs/integrations/consul-connect#cni-plugins">Consul CNI Docs for more information</a>.</p><p><a href="https://developer.hashicorp.com/nomad/docs/install">See Nomad Install Docs for more information</a></p><h3>Configure environment values</h3><p>This script configures multiple env values <code>NOMAD_ADDR</code>, <code>VAULT_ADDR</code>, <code>CONSUL_HTTP_ADDR</code> so we can run cli commands without appending the address and port every time.</p><h2>2. Installation</h2><h3>Get private interface IP</h3><p>You need to obtain the private IP of your chosen network interface. Check if the command below fits your needs or set the IP address manually.</p><h3>Install require packages</h3><h3>Install Docker</h3><p>See the <a href="https://docs.docker.com/engine/install/ubuntu/">official Docker install guide</a> for more information.</p><h3>Add HashiCorps PPAs</h3><p>See the <a href="https://developer.hashicorp.com/nomad/docs/install">official install guide</a> if your prefer to use the prebuilt binary.</p><h3>Install Nomad, Consul &amp; Vault</h3><h2>3. Configuration</h2><h3>3.1 Docker AWS ECR Authentication</h3><p>We will create a new <code>/etc/docker/config.json</code> file to provide Nomad with our Docker login credentials. Replace <code>&lt;aws_id&gt;</code> and <code>&lt;aws_region&gt;</code> with your own values.</p><p></p><hr><h3>3.2 Nomad</h3><p>Before getting started with Nomad instances, we need to configure some environment values in <code>/etc/nomad.d/nomad.env</code></p><p>We will now configure your Nomad instances as <strong>client</strong> and/or <strong>server</strong>. Place this file in <code>/etc/nomad.d/nomad.hcl</code></p><h4>Nomad Client</h4><h4>Nomad Client &amp; Server</h4><h4>Some values explained</h4><ul><li><p>The server <code>server.bootstrap_expect</code> values defined, how many nomad server instances need to be running in order to select a leader.</p></li><li><p>The <code>client.template.disable_file_sandbox</code> allows you to mount host files into you job allcos.</p></li></ul><h3>3.3 Consul</h3><h3>Setup TLS &amp; encryption (optional)</h3><p>To enable internal TLS encryption we need to generate a certificate using the following commands. See the <a href="https://developer.hashicorp.com/consul/commands/tls/cert">Consul TLS docs for more information</a>.</p><p>You now need to distribute the generated <code>consul-agent-ca.pem</code> certificate to all consul agents and place it in <code>/etc/consul.d/certs/consul-agent-ca.pem</code></p><h3>Generate agent certificates</h3><p>On your host Consul server, generate an agent certificate for each Consul agent you want to deploy.</p><p>Distribute your agent certificate to the respective server</p><h3>Configure each agent</h3><p>Again, choose which servers will be used as <strong>client</strong> or <strong>server</strong> for your Consul instances.</p><h3>Consul Client</h3><h3>Consul Server</h3><h2>4. Cheat-Sheet</h2><p>Here are some handy commands I commonly use for debugging.</p><p></p>]]></summary>
<updated>2023-04-08T00:00:00+00:00</updated>
<link length="544682" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/get-started-with-hashi-nomad-consul/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>My 2023 Web Development Setup</title>
<link href="https://romanzipp.com/blog/2023-setup"></link>
<id>https://romanzipp.com/blog/2023-setup</id>
<summary type="html"><![CDATA[<h2>IDE</h2><p>I am mainly using <a href="https://www.jetbrains.com/">JetBrains</a> products for my daily work such as <a href="https://romanzipp.com/blog/2023-setup">PHPStorm</a> and <a href="https://www.jetbrains.com/go/">GoLand</a>. I&#039;ve been sticking to the <a href="https://plugins.jetbrains.com/plugin/15418-github-theme">GitHub Theme</a> for several years now which includes a light and dark version.</p><h2>Terminal</h2><p>My Terminal is <a href="https://iterm2.com/">iTerm2</a> with a customized <a href="https://ohmyz.sh/">oh-my-zsh</a> Theme.</p><h2>MacOS</h2><p>I am currently running a <a href="https://amzn.to/3GPNxKL">2021 14&quot; MacBook Pro</a> with a M1 Pro and 32 GB RAM.</p><h2>iOS</h2><h2>Hardware</h2><ul><li><p>Keyboard: <a href="https://amzn.to/43shdXY">Apple Magic Keyboard</a> / <a href="https://amzn.to/43ezBTZ">Logi MX Keys for Mac</a></p></li><li><p>Mouse: <a href="https://amzn.to/43j56fu">Logi MX Master 3s for Mac</a></p></li><li><p>Webcam: <a href="https://amzn.to/3mfyjaL">Logitech StreamCam</a></p></li></ul><h3>Audio</h3><ul><li><p>Audio-Interface: <a href="https://amzn.to/3MvdNxp">Audient ID14 MKII</a></p></li><li><p>Speakers: <a href="https://amzn.to/43eyvaP">Yamaha HS6</a></p></li><li><p>Microphone: <a href="https://amzn.to/41ccuaU">audio-technica AT2020</a></p></li><li><p>Headphones: <a href="https://amzn.to/40OL6ji">Beyerdynamic DT770 Pro</a></p></li><li><p>ADAT Interface: <a href="https://amzn.to/41bgybf">Behringer ADA8200 Ultragain Digital</a></p></li></ul><h3>Guitar</h3><ul><li><p>E-Guitar: <a href="https://amzn.to/3zK1HsA">Fender Player Series Strat PF</a></p></li><li><p>E-Guitar: <a href="https://amzn.to/3Uo7eyO">Ibanez GRG121DX-BKF</a></p></li><li><p>Acoustic Guitar: <a href="https://amzn.to/3MvM0gi">Fender Malibu Player</a></p></li><li><p>Ukulele: <a href="https://amzn.to/3ZSrYzu">Fender Billie Eilish</a></p></li><li><p>Amp-Modeler: <a href="https://amzn.to/3ZPUoug">Hotone Ampero</a></p></li></ul><h2>Lando</h2><p><a href="https://lando.dev/">Lando</a> is a dead-simple but highly customizable wrapper for local development using Docker containers. When working with multiple PHP projects on different versions, spinning up Docker containers for PHP, nginx, databases or services only takes a simple <code>lando start</code>.</p>]]></summary>
<updated>2023-03-03T00:00:00+00:00</updated>
<link length="15707134" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/2023-setup/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Consul connection drops: &quot;nf_conntrack: table full, dropping packet&quot;</title>
<link href="https://romanzipp.com/blog/nomad-consul-conntrack-connection-drop"></link>
<id>https://romanzipp.com/blog/nomad-consul-conntrack-connection-drop</id>
<summary type="html"><![CDATA[<p>When we were stress testing our new infrastructure based on <a href="https://www.nomadproject.io/">Nomad</a> &amp; <a href="https://www.consul.io/">Consul</a> we quickly experienced issues where all packets were dropped after a couple of seconds. There were no issues indicating any problems with CPU load or network bandwidth. In addition, we weren&#039;t able to monitor the uptime of any jobs because <a href="https://www.haproxy.org/">HAProxy</a> only displayed L7 CONN issues.</p><h2>The evidence</h2><p>After looking through all possible logfiles the <code>kern.log</code> showed a lot of errors which indicated a network issue.</p><p></p><h2>Conntrack</h2><p>A <a href="https://people.netfilter.org/pablo/docs/login.pdf">Conntrack</a> Firewall is a type of firewall that uses the Linux kernel&#039;s connection tracking system (known as &quot;conntrack&quot;) to improve network security. With this firewall, incoming and outgoing network traffic is examined to determine its state, and rules are applied based on that state.</p><p>The conntrack firewall is based on the idea that all network traffic should be classified into one of several states, such as &quot;new,&quot; &quot;established,&quot; or &quot;related.&quot; These states are based on the protocol and port information contained in each packet, as well as other information such as source and destination addresses. The firewall then applies rules to each state, allowing or blocking traffic based on criteria set by the system administrator.</p><h2>table full, dropping packets.</h2><p>This error message means that the <strong>connection tracking table has reached its limit</strong>, causing various issues like network timeouts that can occur randomly or consistently.</p><p>The conntrack table stores information about active connections that are being processed by the kernel. In <strong>Nomad</strong> clusters, this frequently happens when jobs communicate with external endpoints or other services within the same cluster via <strong>Consul</strong>. NAT and stateful firewall rules are used in such situations, and these rules are maintained in the conntrack table as entries.</p><h2>The fix</h2><p>You can determine the current maximum table size via the following command:</p><p></p><p>You can use the <code>sysctl</code> utility to increase the maximum table limit. I&#039;ve used a value of <code>262144</code> for a 8 GB ubuntu system. Please keep in mind that the table will be regurarily flushed.</p><p></p><p>To persist this change, add the following config file to your sysctl daemon which will be run on each boot.</p><p></p>]]></summary>
<updated>2022-09-22T00:00:00+00:00</updated>
<link length="978159" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/consul-fix-restart-loop/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Sprinter: Monitor your internet connection uptime and latency</title>
<link href="https://romanzipp.com/blog/sprinter"></link>
<id>https://romanzipp.com/blog/sprinter</id>
<summary type="html"><![CDATA[<p><a href="https://github.com/romanzipp/Sprinter">Sprinter on GitHub</a></p><h2>What</h2><p>Sprinter allows you to monitor your internet connection latency and uptime. It&#039;s a self contained go application delivered via Docker.</p><p></p><h2>Setup</h2><p>You can easly deploy a Sprinter instance via <a href="https://www.docker.com/">Docker</a>.</p><p><code>docker pull ghcr.io/romanzipp/sprinter:latest</code></p><p>Copy</p><h2>More Information</h2><p>See <a href="https://github.com/romanzipp/Sprinter">Sprinter on GitHub</a>.</p>]]></summary>
<updated>2022-09-21T00:00:00+00:00</updated>
<link length="482059" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/sprinter/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>Wanderer: Automatic deployment of Nomad jobs via GitHub Actions</title>
<link href="https://romanzipp.com/blog/wanderer"></link>
<id>https://romanzipp.com/blog/wanderer</id>
<summary type="html"><![CDATA[<p><a href="https://github.com/romanzipp/Wanderer">Wanderer on GitHub</a></p><h2>What</h2><p>Wanderer is a self-hosted <strong>deployment</strong> tool for <strong>Nomad</strong> orchestrated jobs.</p><h2>Features</h2><ul><li><p>Provides a centralized repository for <a href="https://www.nomadproject.io/">Nomad</a> HCL templates</p></li><li><p>Offers API for CD tools to automate deployment of new versions</p></li><li><p>Simple Web UI for editing templates &amp; monitoring deployments</p></li><li><p>Supports <a href="https://www.nomadproject.io/">Nomad</a> instances behind <a href="https://www.cloudflare.com/products/zero-trust/access/">Cloudflare Access</a> Zero Trust network</p></li><li><p><a href="https://docs.github.com/en/actions">GitHub Actions</a> Workflow available for easy pipeline integration</p></li></ul><p></p><h2>UI</h2><p>Wanderer comes with a basic Web GUI which provides all necessary operations such as editing Nomad clusters, templates or issuing API tokens.</p><p>Nice to know: There is not a single line of JavaScript.</p><p></p><h2>Deploy in Nomad</h2><p>You can also deploy Wanderer in your <a href="https://www.nomadproject.io/">Nomad</a> cluster. This is an example HCL template:</p><h2>More Information</h2><p>See <a href="https://github.com/romanzipp/Wanderer">Wanderer on GitHub</a>.</p>]]></summary>
<updated>2022-09-14T00:00:00+00:00</updated>
<link length="262090" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/wanderer/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
<entry>
<title>How to link a Composer package for local development</title>
<link href="https://romanzipp.com/blog/composer-local-package-development-symlink"></link>
<id>https://romanzipp.com/blog/composer-local-package-development-symlink</id>
<summary type="html"><![CDATA[<h2>1. (optional) Remove remote package</h2><h2>2. Add local repository</h2><p>Add the <code>symlink</code> option if your filesystem supports symlinks.</p><p>The <code>url</code> value can be the absolute or relative path to the package</p><p></p><h2>3. Require the package again</h2><p>Be sure, to add the <code>@dev</code> version</p><p></p>]]></summary>
<updated>2018-05-16T00:00:00+00:00</updated>
<link length="75764" type="image/jpeg" href="https://cdn-a.romanzipp.com/blog/composer-local-package-development-symlink/cover.jpg" rel="enclosure"></link>
<author><name>Roman Zipp</name>
<email>hey@romanzipp.com</email>
</author>
</entry>
</feed>