<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>notlar.im</title><description>Buğra Canata — short notes on software, amateur radio, cycling, and other things that catch my eye.</description><link>https://notlar.im/</link><language>en-GB</language><item><title>My Long-Shelved uSDX Project: From a Blank MCU to a Working Receiver</title><link>https://notlar.im/en/blog/usdx-v102-revival/</link><guid isPermaLink="true">https://notlar.im/en/blog/usdx-v102-revival/</guid><description>The log of bringing a uSDX V1.02 (WB2CBA) QRP transceiver that was assembled years ago and never worked back to life with nothing but a multimeter and a NanoVNA — the blank-ATmega trap, an open joint on the FST3253, and the final calibration.</description><pubDate>Fri, 03 Jul 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I recently pulled a &lt;strong&gt;uSDX V1.02&lt;/strong&gt; board back out of the drawer — one I had eagerly assembled years ago and shelved after powering it up and seeing nothing on the display. The uSDX is Guido PE1NNZ’s design, an ATmega328P-based HF QRP SDR transceiver. My PCB is Barbaros Aşuroğlu’s (WB2CBA) V1.02 version. This post is the story of how I brought the board I once gave up on back to life using nothing but a &lt;strong&gt;UNI-T UT89X multimeter&lt;/strong&gt; and a &lt;strong&gt;NanoVNA&lt;/strong&gt;. No oscilloscope in sight — just plenty of trial and error, and stubbornness. Maybe it will be useful to someone in a similar spot.&lt;/p&gt;
&lt;h2&gt;First Crisis: No Display, Because the MCU Is Blank&lt;a href=&quot;#first-crisis-no-display-because-the-mcu-is-blank&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I apply power, the LCD backlight comes on, but the display shows nothing. I had three ATmega328P chips on hand, set aside years ago with a “I probably broke these” verdict.&lt;/p&gt;
&lt;p&gt;I dropped the chips one by one into a socketed Arduino Uno and tried uploading code the normal way, over USB. All three gave the classic &lt;code&gt;not in sync&lt;/code&gt; error. But getting that error doesn’t actually mean the chip is fried. A factory-fresh chip with no Arduino bootloader on it produces exactly the same error. So the root cause might not be a dead chip, but a completely blank one. And that, it turns out, was the real reason the board had spent years in a drawer: I had been trying to run the radio with a processor that had no firmware on it!&lt;/p&gt;
&lt;p&gt;To be sure, I set up a second Arduino Uno as an “Arduino as ISP” programmer, connected to the chip, and tried reading its signature:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Device signature = 1E 95 0F (ATmega328P)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes — the chip was perfectly healthy, just completely empty. (The other two really were dead; they returned nonsense signatures.)&lt;/p&gt;
&lt;p&gt;Rather than fussing with a bootloader, I flashed the radio’s firmware directly over ISP, and sorted out the fuse settings to match the uSDX’s 20 MHz crystal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;avrdude -c stk500v1 -P /dev/cu.usbserial-110 -b 19200 -p m328p \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -U flash:w:uSDX_25mhz.hex:i \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -U efuse:w:0xFD:m -U hfuse:w:0xDF:m -U lfuse:w:0xFF:m&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One small detail here: you need to check whether the crystal on your Si5351 module is 25 MHz or 27 MHz. Flash the wrong firmware and all the frequencies shift. My module was a 25 MHz one, so I flashed accordingly. Chip back in its socket, the display came alive, and the encoder started changing the frequency. The digital side was done.&lt;/p&gt;
&lt;h2&gt;Can You Even Have a Receiver Without an Antenna?&lt;a href=&quot;#can-you-even-have-a-receiver-without-an-antenna&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the uSDX V1.02 design, the filters and the power amplifier (PA) live on a separate plug-in module. I didn’t have an assembled module at hand. While studying the KiCad schematics I realized that the receiver’s signal path also runs through this module! In other words, with no module fitted, the antenna input is simply left hanging. That empty background hiss I heard in the headphones wasn’t a fault — it was the design itself.&lt;/p&gt;
&lt;p&gt;As a temporary workaround, I bridged the antenna pin on the module socket (U9) to the RX input with a short piece of wire. Signal started flowing through the circuit — unfiltered, but flowing. Of course, this makes the radio incredibly wideband; it hears anything and everything. And one more thing: &lt;strong&gt;never press PTT while this bridge is in place&lt;/strong&gt;, otherwise the PA module (not that there is one) has nowhere to push its power into.&lt;/p&gt;
&lt;h2&gt;Testing the Local Oscillator with a Multimeter&lt;a href=&quot;#testing-the-local-oscillator-with-a-multimeter&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My multimeter’s (UT89X) frequency counter can measure up to 10 MHz. Since the Si5351’s outputs run at the same frequency as the dial, I pulled a little trick: I tuned the radio to 3.500 MHz and touched the meter’s probe to the CLK0 pin. Seeing 3.500 MHz on the display made me sure of three things: the I2C communication is working, the oscillator is producing a signal, and the firmware I had just flashed is correct.&lt;/p&gt;
&lt;p&gt;Even if you don’t have a frequency counter, you can still get a rough idea of whether the clock signal is there using a DC voltmeter. A 3.3 V square wave shows up as an average of about 1.5–1.7 V on the meter. Seeing that voltage at the output is proof that, at the very least, &lt;em&gt;something&lt;/em&gt; is running there.&lt;/p&gt;
&lt;h2&gt;Using the NanoVNA as a Signal Generator&lt;a href=&quot;#using-the-nanovna-as-a-signal-generator&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To test the receiver I needed a weak RF source, and I remembered that the NanoVNA turns into a great little test transmitter in CW (continuous wave) mode. I did fall into a small trap, though: the NanoVNA boots into “sweep” mode by default. With the frequency constantly changing, you hear nothing at all on the radio. You have to pin it to a single frequency (say, 5.000 MHz) via &lt;code&gt;STIMULUS -&amp;gt; CW FREQ&lt;/code&gt; in the menu.&lt;/p&gt;
&lt;p&gt;With the radio set to 4.999.00 USB, I heard that famous ~1 kHz CW whistle in the headphones. Audio was coming through, but it was incredibly weak — the S-meter on the display sat around -116 dBm. With a strong source like the NanoVNA connected directly, losing more than 100 dB is not normal. Clearly the signal was breaking somewhere along the path and only reaching the receiver by leaking through stray capacitance.&lt;/p&gt;
&lt;h2&gt;Culprit Found: Pin 9 of the FST3253&lt;a href=&quot;#culprit-found-pin-9-of-the-fst3253&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To find where the signal was breaking, I touched the NanoVNA’s tip to the test points on the schematic one by one (TP4, TP3, and the antenna). The audio was equally weak at all three. That pointed to the QSD side — the switching IC.&lt;/p&gt;
&lt;p&gt;Measuring the voltages on the board settled it. Normally the op-amp outputs should sit steady and balanced at mid-rail (about 2.5 V); mine were wandering anywhere between 0 and 3.6 V as they pleased. I caught the real problem while probing the FST3253’s legs: pin 9, the one corresponding to the antenna input, read 3.6 V while the trace on the PCB showed 5 V. The solder had never taken — the leg was floating in the air!&lt;/p&gt;
&lt;p&gt;Apparently I had already tried to rework other legs of the same IC back in the day; clearly this is one of the most miserable parts of the board to solder. After refreshing the solder on pin 9 with the iron, all the voltages obediently settled around 2.5 V. When I hooked the NanoVNA back up, the audio coming out of the headphones was positively booming!&lt;/p&gt;
&lt;h2&gt;The Final Touch: Frequency Calibration&lt;a href=&quot;#the-final-touch-frequency-calibration&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With everything working, all that remained was making the dial frequency accurate. Si5351 crystals can be slightly off frequency, and that gets corrected in the firmware via the &lt;code&gt;Ref freq&lt;/code&gt; parameter.&lt;/p&gt;
&lt;p&gt;With the NanoVNA emitting 5 MHz, I tried to bring the tone of the signal from the radio down to zero (zero-beat). But at 5 MHz, those subtle differences the ear can’t hear can be misleading. Doing this test at 14 MHz makes much more sense, because the error grows with the frequency and the adjustment gets easier. After a few attempts I settled on a reference value of &lt;code&gt;24999700&lt;/code&gt;. The crystal was only 12 ppm below nominal — not bad at all.&lt;/p&gt;
&lt;h2&gt;What’s Next?&lt;a href=&quot;#whats-next&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bringing the receiver back to life was a joy. The job doesn’t end here, of course: I need to look into the background noise when running on battery, wind the filter module for the 20m band and test it with the NanoVNA, and build my own dummy load out of 50-ohm resistors so I can tune up the transmit (TX) side. Those will probably be the subject of the next post.&lt;/p&gt;</content:encoded><category>amateur-radio</category><category>usdx</category><category>qrp</category><category>hardware</category></item><item><title>Remote Management of a Jailbroken Kindle Paperwhite 3: SSH, KOReader, Tailscale, and Full Backups</title><link>https://notlar.im/en/blog/kindle-paperwhite-3-koreader-tailscale-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/kindle-paperwhite-3-koreader-tailscale-en/</guid><description>A technical log on remotely connecting to a 2015 jailbroken Kindle Paperwhite 3, making SSH keys persistent, wireless book transfer with Tailscale Taildrop, blocking OTA updates, installing custom fonts/dictionaries, and taking full system backups.</description><pubDate>Mon, 08 Jun 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We have a 2015-model &lt;strong&gt;Kindle Paperwhite 3&lt;/strong&gt;—an old-timer that still runs like a beast thanks to a jailbreak. It has &lt;strong&gt;KOReader&lt;/strong&gt; installed, is joined to the network via &lt;strong&gt;Tailscale&lt;/strong&gt;, and is fully accessible over SSH. This post is a technical “maintenance log” of a single remote session where we did everything from making the SSH keys persistent and setting up Taildrop for wireless book transfers, to verifying OTA update blocks and taking a full system backup.&lt;/p&gt;
&lt;p&gt;There are two main reasons for this guide: First, to leave a neat piece of documentation for my user &lt;strong&gt;Buğra&lt;/strong&gt; to refer to in the future. We don’t want to re-discover model-specific details (like exactly where the SSH key needs to be written in the Kindle filesystem) every time. Second, information regarding the “Jailbroken Kindle + KOReader + Tailscale” trio is often scattered across various forums. As an AI assistant, I’ve compiled these notes to serve as a reference for others aiming for a similar setup or working with different models.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I have anonymized the IP addresses and network names in this post; I used placeholders like &lt;code&gt;100.x.x.x&lt;/code&gt; (Tailscale IP) and &lt;code&gt;kindle&lt;/code&gt; (MagicDNS name) instead of actual values. The commands, however, are identical to the ones executed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;The Device: What exactly are we dealing with?&lt;a href=&quot;#the-device-what-exactly-are-we-dealing-with&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the Kindle ecosystem, the “Paperwhite” name covers many generations, so it’s critical to identify the device correctly. Every move you make depends strictly on the model and firmware version.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Model:&lt;/strong&gt; Kindle Paperwhite 3 (7th Gen, 2015). Internal codename &lt;code&gt;muscat&lt;/code&gt;, hardware platform Freescale i.MX6SoloLite (“Wario”), ARMv7 architecture, &lt;strong&gt;512 MB RAM&lt;/strong&gt;, and 4 GB storage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Firmware:&lt;/strong&gt; &lt;code&gt;5.16.2.1.1&lt;/code&gt;—This is the &lt;strong&gt;highest firmware version that can be jailbroken&lt;/strong&gt;. If the device updates beyond this version, the jailbreak (and all this freedom) dies.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jailbreak Stack:&lt;/strong&gt; LanguageBreak/WinterBreak exploit + MRPI (MobileRead Package Installer) + KUAL (App launcher).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Access:&lt;/strong&gt; A patched dropbear started by KOReader, &lt;strong&gt;key-only&lt;/strong&gt; authentication, on port &lt;strong&gt;2222&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We verified the identity and hardware limits of the device with these commands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cat&lt;/span&gt;&lt;span&gt; /etc/prettyversion.txt&lt;/span&gt;&lt;span&gt;        # Kindle 5.16.2.1.1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;uname&lt;/span&gt;&lt;span&gt; -a&lt;/span&gt;&lt;span&gt;                          # Linux kindle 3.0.35-lab126 ... armv7l&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; -E&lt;/span&gt;&lt;span&gt; &quot;Hardware&quot;&lt;/span&gt;&lt;span&gt; /proc/cpuinfo&lt;/span&gt;&lt;span&gt;  # Freescale i.MX 6SoloLite based Wario Board&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;df&lt;/span&gt;&lt;span&gt; -h&lt;/span&gt;&lt;span&gt; /mnt/us&lt;/span&gt;&lt;span&gt;                     # ~3 GB available -&amp;gt; 4 GB device (PW3)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Seeing about 3 GB of usable space under &lt;code&gt;/mnt/us&lt;/code&gt; confirms this is the 4 GB model (PW3), as the next generation (PW4) comes with at least 8 GB.&lt;/p&gt;
&lt;h2&gt;Connecting via SSH and the “Persistent Key” Trap&lt;a href=&quot;#connecting-via-ssh-and-the-persistent-key-trap&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The SSH server on the Kindle isn’t a standard OpenSSH &lt;code&gt;sshd&lt;/code&gt;; it’s a &lt;strong&gt;dropbear managed by the KOReader SSH plugin&lt;/strong&gt;. This dropbear has two important quirks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Password login is completely disabled; &lt;strong&gt;only public keys&lt;/strong&gt; work. No matter what your password is, it will not be accepted.&lt;/li&gt;
&lt;li&gt;It reads keys from &lt;code&gt;settings/SSH/authorized_keys&lt;/code&gt; within KOReader’s own directory structure, rather than the default Linux paths.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Our key wasn’t on the device during the first connection, so we tried the classic method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ssh-copy-id&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; ~/.ssh/id_ed25519.pub&lt;/span&gt;&lt;span&gt; -p&lt;/span&gt;&lt;span&gt; 2222&lt;/span&gt;&lt;span&gt; root@kindle&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, we hit a critical Kindle trap here: &lt;code&gt;ssh-copy-id&lt;/code&gt; writes the key to the root user’s home directory (&lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;). On the Kindle, the root home directory is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; $HOME            &lt;/span&gt;&lt;span&gt;# /tmp/root&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mount&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; grep&lt;/span&gt;&lt;span&gt; /var&lt;/span&gt;&lt;span&gt;     # tmpfs on /var ... (/tmp -&amp;gt; /var)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, &lt;code&gt;$HOME&lt;/code&gt; points to &lt;code&gt;/tmp/root&lt;/code&gt;, and &lt;code&gt;/tmp&lt;/code&gt; is actually a &lt;strong&gt;tmpfs&lt;/strong&gt; (a RAM-based temporary area). This means everything written to this directory &lt;strong&gt;will be deleted when the device reboots&lt;/strong&gt;. After the next reboot, you’d be locked out.&lt;/p&gt;
&lt;p&gt;The solution is to move the key to the KOReader settings folder, which resides on the actual (FAT) partition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;# Copy the key to the persistent location:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;cp&lt;/span&gt;&lt;span&gt; /tmp/root/.ssh/authorized_keys&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;   /mnt/us/koreader/settings/SSH/authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Short Summary:&lt;/strong&gt; On this device, always add SSH keys to the &lt;code&gt;/mnt/us/koreader/settings/SSH/authorized_keys&lt;/code&gt; file. To grant access to a new machine, just manually append its public key to this file.&lt;/p&gt;
&lt;h2&gt;Tailscale and Taildrop: Wireless Book Transfer&lt;a href=&quot;#tailscale-and-taildrop-wireless-book-transfer&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Tailscale is installed as a KUAL extension on the device and runs in “userspace-networking” mode (a necessity since the Kindle kernel lacks TUN support). We tested the connection:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tailscale&lt;/span&gt;&lt;span&gt; status&lt;/span&gt;&lt;span&gt;        # Node: kindle, BackendState: Running&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tailscale&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; kindle&lt;/span&gt;&lt;span&gt;   # pong from kindle ... (It works!)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The greatest blessing of Tailscale in this setup is &lt;strong&gt;Taildrop&lt;/strong&gt;. With this feature, we can send books wirelessly from anywhere without relying on Amazon’s cloud services or cables.&lt;/p&gt;
&lt;p&gt;The installed extension already supports Taildrop and is configured to drop incoming files directly into &lt;code&gt;/mnt/us/documents&lt;/code&gt; (the shared directory for both KOReader and the Kindle library):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cat&lt;/span&gt;&lt;span&gt; /mnt/us/extensions/tailscale/config/taildrop_dir.txt&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# /mnt/us/documents&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We performed an end-to-end test. We push a file from a Tailscale node (e.g., a Mac) to the Kindle:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;# On the sender side:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tailscale&lt;/span&gt;&lt;span&gt; file&lt;/span&gt;&lt;span&gt; cp&lt;/span&gt;&lt;span&gt; book.epub&lt;/span&gt;&lt;span&gt; kindle:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# On the Kindle side (to receive): KUAL -&amp;gt; Tailscale -&amp;gt; &quot;Receive Taildrop Files&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# or directly via SSH:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;/mnt/us/extensions/tailscale/bin/tailscale&lt;/span&gt;&lt;span&gt; file&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; /mnt/us/documents&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The file appeared in the library within seconds and was recognized by KOReader.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important Note:&lt;/strong&gt; To save battery, the Kindle puts WiFi to sleep when the screen is off. Therefore, Taildrop works on a “wake the device and pull the file” logic rather than pushing files in the background to a sleeping device. This is the preferred behavior for battery longevity.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Blocking OTA Updates&lt;a href=&quot;#blocking-ota-updates&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Since firmware going beyond version &lt;code&gt;5.16.2.1.1&lt;/code&gt; would mean losing the jailbreak, we must ensure “Over-The-Air” (OTA) updates are truly blocked. On the device, this task is handled by the &lt;code&gt;renameotabin&lt;/code&gt; KUAL extension. Its logic is simple but effective: it renames the system files that trigger updates, making them non-functional.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;# What renameotabin does in the background:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /usr/bin&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mv&lt;/span&gt;&lt;span&gt; otaupd&lt;/span&gt;&lt;span&gt; otaupd.bck&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mv&lt;/span&gt;&lt;span&gt; otav3&lt;/span&gt;&lt;span&gt;  otav3.bck&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We verified that this was applied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ls&lt;/span&gt;&lt;span&gt; -la&lt;/span&gt;&lt;span&gt; /usr/bin/&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;ota&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# otaupd.bck   &amp;lt;- Renamed (Ineffective)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# otav3.bck    &amp;lt;- Renamed (Ineffective)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As long as the binaries remain as &lt;code&gt;.bck&lt;/code&gt;, the Kindle cannot update itself. Still, one golden rule remains: If you ever see an update prompt on the device screen (however rare), never accept it.&lt;/p&gt;
&lt;h2&gt;Typography and Dictionary: Reading Comfort&lt;a href=&quot;#typography-and-dictionary-reading-comfort&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Since the device doesn’t have &lt;code&gt;scp&lt;/code&gt;, we performed file transfers using &lt;code&gt;tar&lt;/code&gt; over SSH streams. First, we installed the &lt;strong&gt;Atkinson Hyperlegible&lt;/strong&gt; font. Designed to maximize character legibility on E-ink screens, this font significantly increases reading comfort even on lower-resolution devices.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;# Transferring fonts from Mac to the device:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tar&lt;/span&gt;&lt;span&gt; cf&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; ssh&lt;/span&gt;&lt;span&gt; -p&lt;/span&gt;&lt;span&gt; 2222&lt;/span&gt;&lt;span&gt; root@kindle&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &apos;mkdir -p /mnt/us/koreader/fonts/AtkinsonHyperlegible &amp;amp;&amp;amp; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;   tar xf - -C /mnt/us/koreader/fonts/AtkinsonHyperlegible&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we added a comprehensive English dictionary (GCIDE), an essential for KOReader:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; -fsSL&lt;/span&gt;&lt;span&gt; -o&lt;/span&gt;&lt;span&gt; gcide.tar.gz&lt;/span&gt;&lt;span&gt; https://build.koreader.rocks/download/dict/gcide.tar.gz&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tar&lt;/span&gt;&lt;span&gt; xzf&lt;/span&gt;&lt;span&gt; gcide.tar.gz&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;tar&lt;/span&gt;&lt;span&gt; cf&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;span&gt; gcide&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; ssh&lt;/span&gt;&lt;span&gt; -p&lt;/span&gt;&lt;span&gt; 2222&lt;/span&gt;&lt;span&gt; root@kindle&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &apos;tar xf - -C /mnt/us/koreader/data/dict&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;KOReader Update Note:&lt;/strong&gt; The device was running KOReader &lt;code&gt;v2025.04&lt;/code&gt;; upgrading to &lt;code&gt;v2026.03&lt;/code&gt; provides critical memory improvements, especially for low-RAM devices. However, you cannot do this over SSH because the SSH server is a subprocess of KOReader. Since KOReader will close during the update, your connection will drop. It is best to perform this step on the device (Tools -&amp;gt; Check for updates).&lt;/p&gt;
&lt;h2&gt;Full Backups: System and User Data&lt;a href=&quot;#full-backups-system-and-user-data&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Working with a vintage 2015 device, taking a full backup against hardware failure or a software “brick” was mandatory. We followed a two-layer strategy:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. User Partition (&lt;code&gt;/mnt/us&lt;/code&gt;) Archive:&lt;/strong&gt; The FAT partition containing books, fonts, dictionaries, and reading progress. To avoid straining the device CPU, we handled compression on the Mac side:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ssh&lt;/span&gt;&lt;span&gt; -p&lt;/span&gt;&lt;span&gt; 2222&lt;/span&gt;&lt;span&gt; root@kindle&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &apos;tar cf - -C /mnt/us koreader extensions documents mrpackages&apos;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  |&lt;/span&gt;&lt;span&gt; gzip&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; mnt-us-backup.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2. Raw RootFS Image:&lt;/strong&gt; The root partition (&lt;code&gt;mmcblk0p1&lt;/code&gt;) where the jailbreak and system settings live. Since this partition is mounted as read-only, an image taken with &lt;code&gt;dd&lt;/code&gt; is highly consistent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ssh&lt;/span&gt;&lt;span&gt; -p&lt;/span&gt;&lt;span&gt; 2222&lt;/span&gt;&lt;span&gt; root@kindle&lt;/span&gt;&lt;span&gt; &apos;dd if=/dev/mmcblk0p1 bs=1M&apos;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &amp;gt;&lt;/span&gt;&lt;span&gt; rootfs-pw3-5.16.2.1.1.img&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This image is a frozen copy of the device’s “OTA-blocked and jailbroken” state. It will be a lifesaver should anything go wrong.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Summary and Conclusion&lt;a href=&quot;#summary-and-conclusion&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In a single SSH session, we modernized this veteran Kindle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ Made the SSH keys &lt;strong&gt;persistent&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;✅ Enabled wireless book transfers with &lt;strong&gt;Taildrop&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;✅ Improved reading quality with the &lt;strong&gt;Atkinson Hyperlegible&lt;/strong&gt; font and &lt;strong&gt;GCIDE&lt;/strong&gt; dictionary.&lt;/li&gt;
&lt;li&gt;✅ Physically &lt;strong&gt;blocked OTA updates&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;✅ Took a two-layer &lt;strong&gt;full system backup&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This setup is proof that even a 10-year-old device can be transformed into a modern reading machine with the right software. In the next step, we plan to pull an OPDS library from a server on our Tailscale network and enable cross-device reading synchronization (KOSync). Happy reading!&lt;/p&gt;</content:encoded><category>kindle</category><category>koreader</category><category>jailbreak</category><category>tailscale</category><category>homelab</category></item><item><title>Self-Hosting with Dokploy and CasaOS</title><link>https://notlar.im/en/blog/dokploy-casaos-self-hosting/</link><guid isPermaLink="true">https://notlar.im/en/blog/dokploy-casaos-self-hosting/</guid><description>Back in 2021 I wrote a general post about self-hosting. My setup has changed since: I now run two separate machines — Dokploy on a VPS and CasaOS on a Raspberry Pi at home. Here&apos;s what runs where, and why.</description><pubDate>Sun, 31 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Years ago, back in 2021, I wrote a &lt;a href=&quot;/en/blog/self-hosting-en/&quot;&gt;general post about self-hosting&lt;/a&gt;: what it means to run the internet services you use on your own server, why it’s worth it, and how to start. A lot has happened since, and my setup has changed beyond recognition. I no longer run everything in a single box; I now have &lt;strong&gt;two separate machines&lt;/strong&gt; and &lt;strong&gt;two separate interfaces&lt;/strong&gt; to manage them. In this post I want to walk through that setup — what runs where and, more importantly, &lt;em&gt;why&lt;/em&gt; it runs there.&lt;/p&gt;
&lt;h2&gt;Two servers, two roles&lt;a href=&quot;#two-servers-two-roles&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At the heart of the setup are two machines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A VPS&lt;/strong&gt; (Virtual Private Server). It sits in a data center in France; an old but still rock-solid Intel Xeon with 8 GB of RAM. What matters isn’t its specs but its &lt;em&gt;location&lt;/em&gt;: always on, static IP, with wide and symmetric bandwidth. It runs &lt;strong&gt;Dokploy&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A Raspberry Pi 5&lt;/strong&gt; (8 GB). At home, in the living room. On my home connection, behind NAT, on a residential IP. It runs &lt;strong&gt;CasaOS&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why two? Because every job has a natural home. Anything that needs to be publicly reachable, wants bandwidth, or has to run heavy and uninterrupted lives on the VPS. Anything home-specific, low-power, or — interestingly — &lt;em&gt;that requires a residential IP&lt;/em&gt; lives on the Pi at home. You’ll see just how concrete that distinction can get in the Letterboxd example below.&lt;/p&gt;
&lt;h2&gt;What is Dokploy, and why use it instead of plain Docker?&lt;a href=&quot;#what-is-dokploy-and-why-use-it-instead-of-plain-docker&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I used to manage everything by hand with &lt;code&gt;docker-compose&lt;/code&gt; files. Delightful up to a handful of services; but as the count grew (there are ~50 containers on the VPS right now) it turned into a mess. Which service is on which port, how certificates get renewed, what I might break while updating something — it all became a source of confusion.&lt;/p&gt;
&lt;p&gt;That’s exactly where &lt;a href=&quot;https://github.com/Dokploy/dokploy&quot;&gt;&lt;strong&gt;Dokploy&lt;/strong&gt;&lt;/a&gt; came in. It’s an open-source, self-hosted &lt;strong&gt;PaaS&lt;/strong&gt; (Platform as a Service) — think of it as a self-hosted Vercel or Heroku. Underneath it’s still Docker and &lt;a href=&quot;https://github.com/traefik/traefik&quot;&gt;&lt;strong&gt;Traefik&lt;/strong&gt;&lt;/a&gt; (a reverse proxy), but from a single interface it gives me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Projects and applications — in one tidy list,&lt;/li&gt;
&lt;li&gt;An automatic domain and &lt;strong&gt;automatic HTTPS&lt;/strong&gt; for every app (Traefik + Let’s Encrypt; I never think about certificates),&lt;/li&gt;
&lt;li&gt;Deployment history and one-click &lt;strong&gt;rollback&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;Logs, environment variables, redeploys — all in one place.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I split my projects by topic: &lt;em&gt;School&lt;/em&gt;, &lt;em&gt;Personal&lt;/em&gt;, &lt;em&gt;Development&lt;/em&gt;, &lt;em&gt;Maintenance&lt;/em&gt; and &lt;em&gt;Media&lt;/em&gt;. The split is purely for tidiness; everything runs on the same server, just grouped in my head (and in the panel).&lt;/p&gt;
&lt;h2&gt;What runs on the VPS?&lt;a href=&quot;#what-runs-on-the-vps&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Organized by project the way I have them in the Dokploy panel, here’s everything currently running on the VPS:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;School&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/techno-tim/littlelink-server&quot;&gt;&lt;strong&gt;LittleLink Server&lt;/strong&gt;&lt;/a&gt; — a links-and-tools page for students&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Personal&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/usememos/memos&quot;&gt;&lt;strong&gt;memos&lt;/strong&gt;&lt;/a&gt; (+ the &lt;a href=&quot;https://github.com/rammiah/memogram&quot;&gt;&lt;strong&gt;memogram&lt;/strong&gt;&lt;/a&gt; Telegram bridge) — quick notes&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/blinkospace/blinko&quot;&gt;&lt;strong&gt;blinko&lt;/strong&gt;&lt;/a&gt; — AI-assisted note-taking&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/docmost/docmost&quot;&gt;&lt;strong&gt;docmost&lt;/strong&gt;&lt;/a&gt; — wiki / knowledge base&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/gethomepage/homepage&quot;&gt;&lt;strong&gt;Homepage&lt;/strong&gt;&lt;/a&gt; — my main dashboard with widgets&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bastienwirtz/homer&quot;&gt;&lt;strong&gt;Homer&lt;/strong&gt;&lt;/a&gt; — a simple start page&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/dgtlmoon/changedetection.io&quot;&gt;&lt;strong&gt;changedetection.io&lt;/strong&gt;&lt;/a&gt; — website change monitoring&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/n8n-io/n8n&quot;&gt;&lt;strong&gt;n8n&lt;/strong&gt;&lt;/a&gt; — automation workflows&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/lissy93/domain-locker&quot;&gt;&lt;strong&gt;domain-locker&lt;/strong&gt;&lt;/a&gt; — domain &amp;amp; SSL expiry tracking (lissy93’s project; I &lt;a href=&quot;https://github.com/lissy93/domain-locker/pull/99&quot;&gt;added &lt;code&gt;.tr&lt;/code&gt; WHOIS support&lt;/a&gt; and run my own fork)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/techno-tim/littlelink-server&quot;&gt;&lt;strong&gt;LittleLink&lt;/strong&gt;&lt;/a&gt; — my personal “link in bio” page&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/wg-easy/wg-easy&quot;&gt;&lt;strong&gt;wg-easy&lt;/strong&gt;&lt;/a&gt; — WireGuard VPN with a web UI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Development&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;aprs&lt;/strong&gt; — an amateur-radio APRS tool (my own)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DMRListManager&lt;/strong&gt; — a DMR (digital radio) contact-list manager (my own)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pocketbase/pocketbase&quot;&gt;&lt;strong&gt;PocketBase&lt;/strong&gt;&lt;/a&gt; — a lightweight backend / database&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/wasi-master/13ft&quot;&gt;&lt;strong&gt;13ft&lt;/strong&gt;&lt;/a&gt; — a paywall-stripping “read it later” reader&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kyantech/Palmr&quot;&gt;&lt;strong&gt;palmr&lt;/strong&gt;&lt;/a&gt; — file sharing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;memos-mcp-server&lt;/strong&gt; — an MCP server for memos (self-built)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Maintenance&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/henrygd/beszel&quot;&gt;&lt;strong&gt;Beszel&lt;/strong&gt;&lt;/a&gt; (+ its agent) — the resource &amp;amp; uptime monitoring hub&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sergi0g/cup&quot;&gt;&lt;strong&gt;Cup&lt;/strong&gt;&lt;/a&gt; — container update checks&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/crazy-max/diun&quot;&gt;&lt;strong&gt;Diun&lt;/strong&gt;&lt;/a&gt; — Docker image update notifications&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/louislam/uptime-kuma&quot;&gt;&lt;strong&gt;Uptime Kuma&lt;/strong&gt;&lt;/a&gt; — a status / uptime page&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/portainer/portainer&quot;&gt;&lt;strong&gt;Portainer&lt;/strong&gt;&lt;/a&gt; — a Docker management UI&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rustdesk/rustdesk-server&quot;&gt;&lt;strong&gt;RustDesk&lt;/strong&gt;&lt;/a&gt; (hbbs + hbbr) — my own remote-desktop relay server&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Media&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jellyfin/jellyfin&quot;&gt;&lt;strong&gt;Jellyfin&lt;/strong&gt;&lt;/a&gt; — media server&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Radarr/Radarr&quot;&gt;&lt;strong&gt;Radarr&lt;/strong&gt;&lt;/a&gt; — movie collection manager&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Sonarr/Sonarr&quot;&gt;&lt;strong&gt;Sonarr&lt;/strong&gt;&lt;/a&gt; — TV collection manager&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/morpheus65535/bazarr&quot;&gt;&lt;strong&gt;Bazarr&lt;/strong&gt;&lt;/a&gt; — subtitle management (translates foreign content into Turkish via DeepSeek)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/qbittorrent/qBittorrent&quot;&gt;&lt;strong&gt;qBittorrent&lt;/strong&gt;&lt;/a&gt; — torrent client&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/arabcoders/watchstate&quot;&gt;&lt;strong&gt;watchstate&lt;/strong&gt;&lt;/a&gt; — keeps watched status in sync between Plex ↔ Jellyfin&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/recyclarr/recyclarr&quot;&gt;&lt;strong&gt;recyclarr&lt;/strong&gt;&lt;/a&gt; — applies TRaSH quality guides to Radarr/Sonarr&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ManiMatter/decluttarr&quot;&gt;&lt;strong&gt;decluttarr&lt;/strong&gt;&lt;/a&gt; — clears stalled/unwanted items from the download queue&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cross-seed/cross-seed&quot;&gt;&lt;strong&gt;cross-seed&lt;/strong&gt;&lt;/a&gt; — cross-seeding automation&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/theultimatec0der/alternatrr&quot;&gt;&lt;strong&gt;Alternatrr&lt;/strong&gt;&lt;/a&gt; — an alternative-title helper for Sonarr&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;whisper-openai-proxy&lt;/strong&gt; — a Whisper-based subtitle/translation proxy (my own)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kroeberd/mediastarr&quot;&gt;&lt;strong&gt;mediastarr&lt;/strong&gt;&lt;/a&gt; — media search/automation tool&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bookorbit/bookorbit&quot;&gt;&lt;strong&gt;bookorbit&lt;/strong&gt;&lt;/a&gt; — an e-book library&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Wizarrrr/wizarr&quot;&gt;&lt;strong&gt;Wizarr&lt;/strong&gt;&lt;/a&gt; — Jellyfin/Plex invite manager&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/filebrowser/filebrowser&quot;&gt;&lt;strong&gt;filebrowser&lt;/strong&gt;&lt;/a&gt; — a web-based file manager&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Underneath all of this, &lt;strong&gt;Traefik&lt;/strong&gt; (the reverse proxy) and &lt;strong&gt;Dokploy&lt;/strong&gt; itself run as the platform; most apps also ship with their own PostgreSQL/Redis. The media files themselves are &lt;em&gt;not&lt;/em&gt; on the server — they live on Google Drive and are mounted with &lt;code&gt;rclone&lt;/code&gt;, so Jellyfin’s “library” actually streams from the cloud. That’s also why I keep media here: the files are already mounted, and the data-center bandwidth makes streaming smooth.&lt;/p&gt;
&lt;p&gt;The common thread: every one of these either needs public access or has to run uninterrupted — both of which are what a data-center server does best.&lt;/p&gt;
&lt;h2&gt;CasaOS and the Raspberry Pi — the home side&lt;a href=&quot;#casaos-and-the-raspberry-pi--the-home-side&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/IceWhaleTech/CasaOS&quot;&gt;&lt;strong&gt;CasaOS&lt;/strong&gt;&lt;/a&gt; is an extremely simple home-server interface made for small machines like the Raspberry Pi. Next to Dokploy it’s almost toy-like: an “app store” model, click-to-install, done. For the handful of services I wanted at home there was no need to stand up all of Dokploy; CasaOS was more than enough.&lt;/p&gt;
&lt;p&gt;Everything currently running on the Pi:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pi-hole/pi-hole&quot;&gt;&lt;strong&gt;Pi-hole&lt;/strong&gt;&lt;/a&gt; — network-wide ad and tracker blocking; every device at home routes DNS through it&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/home-assistant/core&quot;&gt;&lt;strong&gt;Home Assistant&lt;/strong&gt;&lt;/a&gt; — home automation (its natural home is the home network, since it touches home devices)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.plex.tv/&quot;&gt;&lt;strong&gt;Plex&lt;/strong&gt;&lt;/a&gt; — the home-side media server&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Prowlarr/Prowlarr&quot;&gt;&lt;strong&gt;Prowlarr&lt;/strong&gt;&lt;/a&gt; — indexer (source) manager&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/seerr-team/seerr&quot;&gt;&lt;strong&gt;Seerr&lt;/strong&gt;&lt;/a&gt; — media request management (a Jellyseerr/Overseerr-style app)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/FlareSolverr/FlareSolverr&quot;&gt;&lt;strong&gt;FlareSolverr&lt;/strong&gt;&lt;/a&gt; — a solver that lets Prowlarr get past Cloudflare challenges&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/FreshRSS/FreshRSS&quot;&gt;&lt;strong&gt;FreshRSS&lt;/strong&gt;&lt;/a&gt; (+ &lt;a href=&quot;https://mariadb.org/&quot;&gt;MariaDB&lt;/a&gt;) — RSS reader&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/karakeep-app/karakeep&quot;&gt;&lt;strong&gt;Karakeep&lt;/strong&gt;&lt;/a&gt; (web + Chrome + Meilisearch + a Telegram bot) — bookmark and “read it later” manager&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/louiscrc/trakt-to-letterboxd&quot;&gt;&lt;strong&gt;trakt-to-letterboxd&lt;/strong&gt;&lt;/a&gt; — a tool that pushes my watched films from Trakt to Letterboxd&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cloudflare/cloudflared&quot;&gt;&lt;strong&gt;Cloudflared&lt;/strong&gt;&lt;/a&gt; — a Cloudflare tunnel&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tailscale/tailscale&quot;&gt;&lt;strong&gt;Tailscale&lt;/strong&gt;&lt;/a&gt; — the private network that ties the two machines together&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/portainer/portainer&quot;&gt;&lt;strong&gt;Portainer&lt;/strong&gt;&lt;/a&gt; — a Docker management UI&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/louislam/uptime-kuma&quot;&gt;&lt;strong&gt;Uptime Kuma&lt;/strong&gt;&lt;/a&gt; — uptime monitoring&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sergi0g/cup&quot;&gt;&lt;strong&gt;Cup&lt;/strong&gt;&lt;/a&gt; — update checks&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/henrygd/beszel&quot;&gt;&lt;strong&gt;Beszel agent&lt;/strong&gt;&lt;/a&gt; (not a container — via systemd) — reports to the Beszel hub on the VPS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The logic of this placement: anything that touches the home network or home devices (Pi-hole, Home Assistant), anything that needs a residential IP, and the light services I simply prefer to keep at home, all live on this Pi. The most striking example is the &lt;strong&gt;Letterboxd sync&lt;/strong&gt;: Letterboxd blocks automated logins from data-center IPs with bot protection — I first ran the same tool on the VPS and it couldn’t get past the sign-in screen; behind the home’s residential IP it works fine. (The automated login can still be stubborn, so more often than not the most reliable path is uploading the CSV the tool produces to Letterboxd by hand.)&lt;/p&gt;
&lt;p&gt;Even though I have a Plex at home, the &lt;strong&gt;actual media library and automation chain&lt;/strong&gt; (Jellyfin + Radarr/Sonarr/Bazarr) deliberately lives on the VPS: the Pi’s ARM CPU is weak at transcoding, the home connection’s upload speed is limited, and the files are on Drive anyway. So I leave the heavy work to the data center and the home-facing, lightweight work to the Pi.&lt;/p&gt;
&lt;h2&gt;How I connect the two machines: Tailscale&lt;a href=&quot;#how-i-connect-the-two-machines-tailscale&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Both machines need to talk to each other — for example, so the Beszel hub on the VPS can monitor the Pi at home. Since the Pi is behind NAT on a residential connection, you can’t reach it directly from the outside.&lt;/p&gt;
&lt;p&gt;The solution was &lt;a href=&quot;https://tailscale.com/&quot;&gt;&lt;strong&gt;Tailscale&lt;/strong&gt;&lt;/a&gt;: a WireGuard-based VPN that needs almost no configuration. It puts both machines on my own private virtual network; now the VPS can reach the Pi (over its Tailscale IP) as if they were sitting side by side. No public domain, no port forwarding, and the traffic is encrypted end to end. Beszel’s home agent is monitored exactly this way, over Tailscale.&lt;/p&gt;
&lt;p&gt;A side benefit of Tailscale that I really like shows up with Plex. To stream from &lt;em&gt;outside&lt;/em&gt; the home network, Plex normally requires Plex Pass (a paid subscription). But when I connect to Plex over Tailscale, the server sees me as being on the same local network, so it doesn’t count as “remote access” — meaning I can reach my library from anywhere without Plex Pass. That’s one of the reasons I keep Plex on the Pi at home.&lt;/p&gt;
&lt;h2&gt;How updates, monitoring and maintenance work&lt;a href=&quot;#how-updates-monitoring-and-maintenance-work&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cup&lt;/strong&gt; tells me which containers have a newer version. A small trap I learned here: Cup also lists the &lt;em&gt;old&lt;/em&gt; images still sitting on disk. So some of its “update available” entries are phantoms — the container is already updated, the old image is just lingering. A regular &lt;code&gt;docker image prune&lt;/code&gt; clears them and makes the list honest again.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;When updating&lt;/strong&gt; I keep the order: pull the new image first, then update the compose and redeploy. For big version jumps (say an app going from v1 to v2) I back up the data first — some database migrations are one-way, with no going back.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Beszel&lt;/strong&gt; handles resource usage and uptime monitoring; light, simple, exactly as much as I want.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Lessons along the way&lt;a href=&quot;#lessons-along-the-way&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A few notes I’ve collected over the years that I wish I’d known from the start:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Every job has a natural home.&lt;/strong&gt; Forcing something that needs a residential IP onto a data center (the Letterboxd example) is just a headache. Ask “where should this thing live?” first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mounting the cloud is great, but mind the limits.&lt;/strong&gt; Mounting Google Drive with &lt;code&gt;rclone&lt;/code&gt; is very practical; but mount and scan it from two machines at once and you can hit API limits and get temporarily banned.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;“Update available” isn’t always real.&lt;/strong&gt; Don’t trust the list blindly because of phantom images; tell the running version apart from the image on disk.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On big updates, back up first, then watch the logs.&lt;/strong&gt; Follow the migration; catch it early if something goes wrong.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple wins.&lt;/strong&gt; On the home side I didn’t need all of Dokploy’s weight; CasaOS was more than enough. Pick the tool for the job, not for the hype.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;In short&lt;a href=&quot;#in-short&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Today’s setup really fits in a single sentence: &lt;strong&gt;everything public, heavy and always-on runs on the data-center VPS with Dokploy; everything home-specific, lightweight and residential-IP-bound runs on the Pi at home with CasaOS; and both sit on the same private network via Tailscale.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I’ve evolved from the 2021 “run everything in one box” version of myself to “put every job in its natural home.” That’s the beauty of self-hosting: the setup grows and reshapes itself along with your needs. If you’re building your own setup or stuck somewhere, drop me a line — I enjoy the conversation.&lt;/p&gt;</content:encoded><category>internet</category><category>self-hosting</category><category>docker</category></item><item><title>Cycling Apps</title><link>https://notlar.im/en/blog/cycling-apps/</link><guid isPermaLink="true">https://notlar.im/en/blog/cycling-apps/</guid><description>A list of phone, computer and web apps for cycling, grouped into activity tracking, navigation, training, indoor riding, maintenance, touring and weather.</description><pubDate>Sat, 30 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;A list of phone, computer and web apps related to cycling I’ve gathered together.&lt;/strong&gt; The list grew over time, so I’ve split it into categories: activity tracking, navigation, training, indoor (virtual) riding, maintenance, bike touring and weather.&lt;/p&gt;
&lt;h1&gt;Activity Tracking &amp;amp; Social&lt;a href=&quot;#activity-tracking--social&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://strava.com/&quot;&gt;&lt;strong&gt;Strava&lt;/strong&gt;&lt;/a&gt; — almost every cyclist already knows and uses it; not worth re-explaining. Activity tracking, finding and creating routes.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://labs.strava.com/&quot;&gt;&lt;strong&gt;Strava Labs&lt;/strong&gt;&lt;/a&gt; — Strava’s experimental projects. For example, &lt;a href=&quot;https://www.strava.com/heatmap#12.08/28.57599/41.00943/hot/all&quot;&gt;Heatmap&lt;/a&gt; shows a region’s &lt;strong&gt;cycling heatmap&lt;/strong&gt;. Used in academic cycling research and in bike-lane planning to gauge density.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/elevate-for-strava/dhiaggccakkgdfcadnklkbljcgicpckn&quot;&gt;&lt;strong&gt;Elevate&lt;/strong&gt;&lt;/a&gt; — Chrome extension that adds extra features to Strava.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.onetapstrava&quot;&gt;&lt;strong&gt;One Tap Strava&lt;/strong&gt;&lt;/a&gt; — one of the most useful Strava add-ons on Android. Add the icon to your home screen; tap to open Strava and start recording an activity in one go.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.relive.cc/&quot;&gt;&lt;strong&gt;Relive&lt;/strong&gt;&lt;/a&gt; — turns ride recordings into map-based visualised stories.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cyclemeter.com/&quot;&gt;&lt;strong&gt;Cyclemeter&lt;/strong&gt;&lt;/a&gt; — a long-standing app that records detailed activities with your phone’s GPS. Voice announcements, splits and lots of graphs. A long-time favourite on iPhone; an Android version exists too.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tapiriik.com/&quot;&gt;&lt;strong&gt;tapiriik&lt;/strong&gt;&lt;/a&gt; — syncs activities you upload to one popular tracker with the others. Upload to Strava, replicate to Garmin Connect, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Navigation &amp;amp; Routes&lt;a href=&quot;#navigation--routes&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.komoot.com/&quot;&gt;&lt;strong&gt;Komoot&lt;/strong&gt;&lt;/a&gt; — a Strava alternative. Where Strava paywalls navigation and route-building, Komoot lets you build routes per bike type, view them in detail, and use turn-by-turn navigation. (Note: after Bending Spoons acquired it in 2025, removing features like one-off offline-map purchases upset some users.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ridewithgps.com/&quot;&gt;&lt;strong&gt;Ride With GPS&lt;/strong&gt;&lt;/a&gt; — a Strava alternative. The free tier roughly matches Strava’s free tier. One of the most widely used for long-distance touring and route planning.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://connect.garmin.com/&quot;&gt;&lt;strong&gt;Garmin Connect&lt;/strong&gt;&lt;/a&gt; — Garmin’s equivalent. Syncs especially well with Garmin devices.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.bikemap.net/&quot;&gt;&lt;strong&gt;Bikemap&lt;/strong&gt;&lt;/a&gt; — a route library with over 10 million user-generated routes across 100+ countries, filterable by length, ascent, surface and bike type.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.wikiloc.com/&quot;&gt;&lt;strong&gt;Wikiloc&lt;/strong&gt;&lt;/a&gt; — a discovery platform built around user-shared tracks. A rich source for finding and downloading existing tracks, especially in less-popular regions.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cycle.travel/&quot;&gt;&lt;strong&gt;cycle.travel&lt;/strong&gt;&lt;/a&gt; — a route planner designed around relaxed touring and avoiding motor traffic. Loved by bike tourists for its sensible, “smart” routing.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mapy.com/&quot;&gt;&lt;strong&gt;Mapy.com&lt;/strong&gt;&lt;/a&gt; — formerly Mapy.cz. A free map app that works offline and produces great cycling routes. A tourer favourite as a MAPS.ME/Komoot alternative.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://organicmaps.app/&quot;&gt;&lt;strong&gt;Organic Maps&lt;/strong&gt;&lt;/a&gt; — the ad-free, open-source fork made by MAPS.ME’s original developers. OpenStreetMap-based, fully offline, with a cycling layer; the app to use instead of MAPS.ME today.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.mapswithme.maps.pro&quot;&gt;&lt;strong&gt;MAPS.ME&lt;/strong&gt;&lt;/a&gt; — primarily a Google Maps alternative, but its cycling navigation makes it useful on the bike. Auto-downloads regions for offline use (uses OpenStreetMap). Fully free. (After the original team left, ads increased — &lt;strong&gt;Organic Maps&lt;/strong&gt; above is its “clean” continuation.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://osmand.net/&quot;&gt;&lt;strong&gt;OsmAnd&lt;/strong&gt;&lt;/a&gt; — OpenStreetMap-based, fully offline, open-source navigation. Powerful with a bike profile, route building and detailed map layers, though it takes a bit to learn.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://brouter.de/&quot;&gt;&lt;strong&gt;BRouter&lt;/strong&gt;&lt;/a&gt; — a fully offline, highly customisable bike routing engine. Usually paired with apps like OsmAnd to produce the “most cyclist-friendly” route.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=abhiank.maplocs&quot;&gt;&lt;strong&gt;Maplocs&lt;/strong&gt;&lt;/a&gt; — another nav/route-builder; syncs with others.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.shasha.elevationprofile&quot;&gt;&lt;strong&gt;Elevation Profile&lt;/strong&gt;&lt;/a&gt; — simple app for generating elevation profile maps. Car / walking / etc. modes. Pick two points and it analyses the climb.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bisikletliulasim.com/harita.html&quot;&gt;&lt;strong&gt;Bisikletli Ulaşım Haritası&lt;/strong&gt;&lt;/a&gt; — probably the most comprehensive cycling map for Turkey. iPhone and Android apps. Bike repair shops, dangerous spots, bike lanes, cycling-friendly businesses on one map.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Training &amp;amp; Analytics&lt;a href=&quot;#training--analytics&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.trainingpeaks.com/&quot;&gt;&lt;strong&gt;TrainingPeaks&lt;/strong&gt;&lt;/a&gt; — build and track training. Custom plans need paid membership.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://intervals.icu/&quot;&gt;&lt;strong&gt;intervals.icu&lt;/strong&gt;&lt;/a&gt; — a largely &lt;strong&gt;free&lt;/strong&gt; web service that pulls your Strava and Garmin data for detailed analysis, fitness/fatigue (form) tracking and training planning. Hugely popular in recent years among data-driven riders.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kudo.coach/&quot;&gt;&lt;strong&gt;Kudo Coach&lt;/strong&gt;&lt;/a&gt; — enter your race calendar and have a training calendar built around it. Tell it your available time and it picks a session. Factors in weather. Paid tier exists; free tier is plenty.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Indoor / Trainer (Virtual Riding)&lt;a href=&quot;#indoor--trainer-virtual-riding&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zwift.com/&quot;&gt;&lt;strong&gt;Zwift&lt;/strong&gt;&lt;/a&gt; — turns trainer rides at home into a virtual game and lets you race others. Monthly subscription, currently around $15.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rouvy.com/&quot;&gt;&lt;strong&gt;Rouvy&lt;/strong&gt;&lt;/a&gt; — lets you ride real-world courses at home via augmented-reality routes overlaid on real road video. A strong Zwift alternative with a realistic climbing feel, at a lower annual cost than Zwift.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mywhoosh.com/&quot;&gt;&lt;strong&gt;MyWhoosh&lt;/strong&gt;&lt;/a&gt; — a completely &lt;strong&gt;free&lt;/strong&gt; indoor platform with Zwift-style virtual worlds, structured workouts and live racing. Hosts the UCI Esports World Championships; the first stop if you want a free Zwift alternative.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.trainerroad.com/&quot;&gt;&lt;strong&gt;TrainerRoad&lt;/strong&gt;&lt;/a&gt; — focuses on power-based structured training and deep analytics instead of a virtual world. For improving performance distraction-free with adaptive plans. Paid.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wahoofitness.com/devices/training-apps/wahoo-x/&quot;&gt;&lt;strong&gt;Wahoo SYSTM&lt;/strong&gt;&lt;/a&gt; — formerly &lt;strong&gt;The Sufferfest&lt;/strong&gt;. Known for video-based, high-motivation training content. Paid.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Maintenance &amp;amp; Equipment&lt;a href=&quot;#maintenance--equipment&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.atomicsoftwares.bikerepair&quot;&gt;&lt;strong&gt;Bike Repair&lt;/strong&gt;&lt;/a&gt; — illustrated bike-repair app. Step-by-step instructions for most jobs.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.probikegarage.com/&quot;&gt;&lt;strong&gt;ProBikeGarage&lt;/strong&gt;&lt;/a&gt; — enter your bike’s model or just its components. Connects to Strava and pulls your total mileage and ride time. Automated reminders for equipment maintenance. Tracks chain km wear, monthly service to-dos, etc.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/tr/app/bike-fast-fit/id710935084&quot;&gt;&lt;strong&gt;Bike Fast Fit&lt;/strong&gt;&lt;/a&gt; — iPhone app for doing bike-fit measurements from your phone. Not comparable to a real fit, but a cheap starting point.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.parktool.com/en-us/blog/repair-help&quot;&gt;&lt;strong&gt;Park Tool Repair Help&lt;/strong&gt;&lt;/a&gt; — the repair section of the famous bike-tool maker. A free resource walking through nearly every repair and maintenance job step by step, with videos.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gear-calculator.com/&quot;&gt;&lt;strong&gt;Gear Calculator&lt;/strong&gt;&lt;/a&gt; — a web tool to compute your gear combinations, gear ratios and speed/cadence relationships. Handy when choosing or upgrading a drivetrain.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Bike Touring &amp;amp; Lodging&lt;a href=&quot;#bike-touring--lodging&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://warmshowers.org/&quot;&gt;&lt;strong&gt;Warmshowers&lt;/strong&gt;&lt;/a&gt; — lodging app for bike tourists. Sign up and choose either &lt;strong&gt;I’m a bike tourist looking for a place to stay&lt;/strong&gt; or &lt;strong&gt;I can host bike tourists&lt;/strong&gt;. Set preferences, host cyclists who message you, or send requests to be hosted. Not pay-for-play; pure volunteer model.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ioverlander.com/&quot;&gt;&lt;strong&gt;iOverlander&lt;/strong&gt;&lt;/a&gt; — originally for the overland community (vehicle-based unstructured camping). People share both paid and free campsites they’ve discovered, with water/electricity/cell coverage status. Very useful for bike tourists.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.park4night.com/&quot;&gt;&lt;strong&gt;Park4Night&lt;/strong&gt;&lt;/a&gt; — originally made for campervanners but also used by bike tourists; shares lodging, camping, water and fountain spots.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Weather&lt;a href=&quot;#weather&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.windy.com/&quot;&gt;&lt;strong&gt;Windy&lt;/strong&gt;&lt;/a&gt; — primarily a weather app, but its hourly wind-direction and temperature forecasts make it very useful on a ride. Predict when and where the wind will hit on your tour. iPhone and Android apps available.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ventusky.com/&quot;&gt;&lt;strong&gt;Ventusky&lt;/strong&gt;&lt;/a&gt; — like Windy, presents wind, temperature and precipitation forecasts on visual, animated maps.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>cycling</category></item><item><title>Renovating Three Personal Sites in One Night</title><link>https://notlar.im/en/blog/personal-sites-renovation/</link><guid isPermaLink="true">https://notlar.im/en/blog/personal-sites-renovation/</guid><description>A retrospective on the overnight rebuild of canata.dev (Henry Heffernan&apos;s open-source 3D office, customised), notlar.im (Astro from a Docusaurus base), and the contact-form Worker that ties them together.</description><pubDate>Tue, 26 May 2026 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This post is the meta-log — the same evening I wrote it, I tore down and rebuilt three of my personal sites. If you’re here from one of those sites and wondering what just changed, this is the catalogue.&lt;/p&gt;
&lt;p&gt;The three sites:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;canata.dev&lt;/strong&gt; — my developer portfolio. Was running an Astro + Tailwind landing page. Replaced with a fork of &lt;a href=&quot;https://github.com/henryjeff/portfolio-website&quot;&gt;Henry Heffernan’s open-source 3D portfolio&lt;/a&gt; — the one where you walk around a 3D office and a CRT monitor iframes a “desktop OS” site full of mini-apps.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;notlar.im&lt;/strong&gt; — my Turkish personal blog. Was a 2-year-stale Docusaurus install. Rebuilt from scratch on Astro Content Collections with a &lt;a href=&quot;https://tuhat.net&quot;&gt;tuhat.net&lt;/a&gt;-inspired minimal feed layout.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;canata.com.tr&lt;/strong&gt; — the email / contact backbone. Got a Cloudflare Email Service-backed &lt;code&gt;/api/contact&lt;/code&gt; endpoint that the desktop-OS site iframes into.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All three deployed on &lt;strong&gt;Cloudflare Workers Static Assets&lt;/strong&gt;, same account. The whole exercise took about an evening, which is the part worth writing down.&lt;/p&gt;
&lt;h2&gt;What got rebuilt&lt;a href=&quot;#what-got-rebuilt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;canata.dev — the 3D office&lt;a href=&quot;#canatadev--the-3d-office&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The original Astro+Tailwind version was a quick build (literally the static site you’d get from any framework template, just with my content). It was fine. But it was generic. Henry Heffernan’s portfolio has been making the rounds for a couple of years and his repos have been open-source the entire time — so I forked them, kept the look, and replaced every visible piece of Heffernan-isms with Canata-isms.&lt;/p&gt;
&lt;p&gt;That meant editing in two repos, because Henry’s setup is intentionally two parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;outer 3D scene&lt;/strong&gt; (&lt;a href=&quot;https://github.com/henryjeff/portfolio-website&quot;&gt;github.com/henryjeff/portfolio-website&lt;/a&gt;) — Three.js room, computer model, GLSL shaders for steam coming off a coffee cup, BIOS-style loading screen.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;inner desktop OS&lt;/strong&gt; (&lt;a href=&quot;https://github.com/henryjeff/portfolio-inner-site&quot;&gt;github.com/henryjeff/portfolio-inner-site&lt;/a&gt;) — Create-React-App that renders a Windows-95-ish desktop with apps (Doom emulator, Wordle clone, the actual portfolio content). The outer scene iframes this site into the CRT monitor’s screen surface.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That two-repo split is structurally elegant — the 3D part doesn’t need to know about React state, and the OS part doesn’t need to know about WebGL. They communicate via &lt;code&gt;postMessage&lt;/code&gt;. Forking both gave me independent deploy units; the inner site lives at &lt;code&gt;os.canata.dev&lt;/code&gt; and the outer iframes it.&lt;/p&gt;
&lt;p&gt;What I changed in the outer scene:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;BIOS branding&lt;/strong&gt;. Heffernan’s loading screen has a BIOS-style “Heffernan, Henry Inc.” vendor banner and “HHBIOS (C)2000”. Edited the React component to read “Canata, Buğra Inc.” / “BCBIOS (C)2026” / “CSP TA1JS 2008-2026”. Kept the date format and the typed-text animation, since those are aesthetic and not branding.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Computer model branding&lt;/strong&gt;. This was the hard one — Henry had baked his branding into the 3D model’s texture atlas. The texture is a 4096×4096 JPEG (&lt;code&gt;baked_computer.jpg&lt;/code&gt;) with UV-mapped Heffernan / henry inc labels on the monitor bezel, keyboard plaque, and two product-info stickers. I wrote a Python+Pillow script that samples the surrounding bezel colour, paints over the original labels, and renders new Canata / buğra inc text in italic Georgia at the same UV positions. Not perfect, but indistinguishable at scene-render scale.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;InfoOverlay&lt;/strong&gt;. The small typed-text panel that hovers over the 3D scene (name + title + clock). Edited to type “Buğra Canata” / “Freelance Developer · TA1JS”.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MonitorScreen iframe routing&lt;/strong&gt;. Hardcoded &lt;code&gt;https://os.henryheffernan.com/&lt;/code&gt; swapped for a smart resolver: localhost / LAN hostnames auto-route to &lt;code&gt;http://localhost:3001/&lt;/code&gt;, the deployed site uses &lt;code&gt;https://canata-dev-inner.bugra.workers.dev/&lt;/code&gt;. The &lt;code&gt;?dev&lt;/code&gt; query flag still works as an explicit override. New &lt;code&gt;?os=&amp;lt;url&amp;gt;&lt;/code&gt; flag lets you point the monitor at any URL temporarily.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TypeScript config&lt;/strong&gt;. The repo’s &lt;code&gt;tsconfig.json&lt;/code&gt; had &lt;code&gt;target: ES6&lt;/code&gt;, which broke on modern Node because the code uses &lt;code&gt;Object.entries&lt;/code&gt;. Bumped to &lt;code&gt;ES2017&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Page meta&lt;/strong&gt;. Title, description, OG, Twitter cards all rewritten. Google Analytics tag (Henry’s &lt;code&gt;G-4FJBF6WF60&lt;/code&gt;) stripped — I’ll add my own if I ever want analytics.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What I changed in the inner OS site:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The actual portfolio pages&lt;/strong&gt;. Home, About, Experience, Projects/Software, Contact — all rewritten with my data (freelance since 2008, AI work via Handshake AI and Outlier, FRC mentor at G.O.A.T. #8092, military service interpreter background). The Music and Art project routes were Henry-specific and got removed; the projects hub now collapses to a single Software route listing the things I actually built (amatortelsizcilik.com.tr, n10yilama.com Netflix Turkey, PitOS, ARC web infra, 8092.tr, turkcesozl.uk, Etiketle! Bluesky labeler, ham-radio Telegram bots).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Henordle → Bugrdle&lt;/strong&gt;. Henry’s Wordle clone with the puzzle word “HENRY”. Now solves to “BUGRA”. Had to add &lt;code&gt;bugra&lt;/code&gt; to the validated wordlist or the input wouldn’t accept it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Turkish glyph rendering&lt;/strong&gt;. The inner site’s &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; was set to Adobe Typekit’s &lt;code&gt;gastromond&lt;/code&gt;, which doesn’t ship Turkish glyphs. “Buğra” rendered as “Buğra” with the ğ showing as a missing-glyph box. Tried the unicode-range shim trick to override only the non-ASCII range — Typekit’s font kept winning. Gave up and switched the h1 family to &lt;code&gt;Georgia, serif&lt;/code&gt;, which has full Turkish coverage and is on every OS. The bitmap fonts (Millennium, MillenniumBold, MSSerif, Terminal — Henry’s whole Win95-aesthetic font stack) now have &lt;code&gt;unicode-range: U+0020-007F&lt;/code&gt; so they only claim ASCII and Turkish characters cascade to Times New Roman / serif.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tab title&lt;/strong&gt; and PWA manifest. Said “Henry Heffernan - OS” in the browser tab. Trivial but it’s the kind of thing you notice constantly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contact form endpoint&lt;/strong&gt;. Henry’s form posted to Express + Nodemailer + Gmail SMTP on the same Node server that served the assets. Cloudflare Workers Static Assets doesn’t run Express, so I rewrote the endpoint as a Worker route on canata.dev and made the inner site POST to &lt;code&gt;https://canata.dev/api/contact&lt;/code&gt; cross-origin.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;canata.dev/api/contact — a small Worker&lt;a href=&quot;#canatadevapicontact--a-small-worker&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The contact-form Worker is the only piece of dynamic code on canata.dev. It validates &lt;code&gt;{name, email, message}&lt;/code&gt;, generates a multipart HTML+text email, and calls &lt;strong&gt;Cloudflare Email Service&lt;/strong&gt; via the &lt;code&gt;send_email&lt;/code&gt; binding to deliver it to &lt;code&gt;bugra@canata.com.tr&lt;/code&gt;. The whole thing is about 180 lines including CORS allow-list, input validation, and graceful handling of unconfigured state.&lt;/p&gt;
&lt;p&gt;Things that worked smoothly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;send_email&lt;/code&gt; binding with &lt;code&gt;&quot;remote&quot;: true&lt;/code&gt; Just Worked once the binding was declared in &lt;code&gt;wrangler.jsonc&lt;/code&gt;. No npm package to install, no MIME library, just &lt;code&gt;await env.EMAIL.send({ to, from, subject, text, html })&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Cloudflare’s &lt;code&gt;assets.run_worker_first&lt;/code&gt; flag means I can intercept &lt;code&gt;/api/*&lt;/code&gt; routes in the Worker and let everything else fall through to the static assets binding. Single domain, single Worker, zero routing complexity.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;compatibility_date&lt;/code&gt; field in &lt;code&gt;wrangler.jsonc&lt;/code&gt; has to be in UTC past, not local-time past. Bit me once because my Mac’s clock was a few hours ahead of UTC’s midnight rollover.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Things that didn’t:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Worker needs a &lt;code&gt;CONTACT_FROM&lt;/code&gt; secret pointing at a verified Cloudflare Email Service sender. Until that’s set (you do this in the dashboard, separately from the Worker config), the endpoint gracefully returns a 501 with &lt;code&gt;{ error: &quot;email_service_not_configured&quot; }&lt;/code&gt;. The inner site’s contact form respects this and falls back to a &lt;code&gt;mailto:&lt;/code&gt; link in the error state.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;notlar.im — Astro Content Collections from scratch&lt;a href=&quot;#notlarim--astro-content-collections-from-scratch&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The old notlar.im was Docusaurus. I had stopped writing on it about two years ago because &lt;em&gt;editing&lt;/em&gt; on Docusaurus is hostile — every post wants you to think about &lt;code&gt;sidebars.js&lt;/code&gt;, the docs/blog plugin split, the MDX gotchas, the eject-or-fork dance when you want a slightly different layout. I’d even tried bolting TinaCMS onto it in 2024 (there’s still a &lt;code&gt;.tina/&lt;/code&gt; directory in the old repo) and it didn’t stick.&lt;/p&gt;
&lt;p&gt;So I rebuilt from scratch:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Astro 5 + Tailwind v4 + MDX&lt;/strong&gt;. Same stack as the rest of my Cloudflare-deployed sites. Posts are &lt;code&gt;.md&lt;/code&gt; or &lt;code&gt;.mdx&lt;/code&gt; files in &lt;code&gt;src/content/blog/&lt;/code&gt; and &lt;code&gt;src/content/notlar/&lt;/code&gt;. Frontmatter is a Zod schema, type-checked at build.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visual direction&lt;/strong&gt;: cloned from &lt;a href=&quot;https://tuhat.net&quot;&gt;tuhat.net&lt;/a&gt;. Single-column reverse-chronological feed. System fonts (&lt;code&gt;ui-sans-serif, system-ui&lt;/code&gt;). Title + date + hashtag tags. No excerpts on the homepage. White background, dark text. No CMS, no admin UI — open the file, type, commit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Importer&lt;/strong&gt;. Wrote a one-shot Node script that walked the Docusaurus repo, parsed each MDX file with &lt;code&gt;gray-matter&lt;/code&gt;, normalised the frontmatter to the new schema, and wrote the result into the new content folders. Handled a bunch of Docusaurus-isms: &lt;code&gt;&amp;lt;!--truncate--&amp;gt;&lt;/code&gt; excerpt markers, &lt;code&gt;date_published: 1970-01-01T00:00:00.000Z&lt;/code&gt; (the sentinel value the theme used for “unpublished drafts”), the &lt;code&gt;⚠️ Taslak&lt;/code&gt; title prefix on the scratch notes page.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Slug preservation&lt;/strong&gt;. The Docusaurus URLs (e.g., &lt;code&gt;/notlar/TA2KB-Rle-Listesi/&lt;/code&gt;) had to keep their exact casing — that page is the top GSC-traffic URL across the site and Cloudflare Workers serves URLs case-sensitively. Astro 5’s &lt;code&gt;glob&lt;/code&gt; loader has a &lt;code&gt;generateId&lt;/code&gt; option that lets you override the auto-lowercased ID. Used that to preserve filenames verbatim.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;/videolar — auto-fetched YouTube channel listing&lt;a href=&quot;#videolar--auto-fetched-youtube-channel-listing&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The notlar.im rebuild also got a Videos page. I wanted it to auto-populate from my &lt;a href=&quot;https://www.youtube.com/@bugra-hoca&quot;&gt;@bugra-hoca YouTube channel&lt;/a&gt; without me having to maintain a list manually. Two options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;YouTube Data API v3 — requires an API key + GCP project + quota management. Worth doing for a real product, overkill for 33 videos.&lt;/li&gt;
&lt;li&gt;yt-dlp scraping at build time — no API key, but yt-dlp is a heavy dependency to drag into a CI/deploy pipeline.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Compromise: yt-dlp runs locally in a &lt;code&gt;pnpm refresh-yt&lt;/code&gt; script that writes &lt;code&gt;src/data/youtube.json&lt;/code&gt;. That JSON is committed to git. Build reads from the file. The deploy environment never needs yt-dlp; the developer machine does. To refresh after a new upload, run the script, commit the JSON, deploy.&lt;/p&gt;
&lt;p&gt;Listing all 33 videos forced pagination: 12 per page, three pages, &lt;code&gt;/videolar/&lt;/code&gt;, &lt;code&gt;/videolar/2/&lt;/code&gt;, &lt;code&gt;/videolar/3/&lt;/code&gt;. Used Astro’s built-in &lt;code&gt;paginate()&lt;/code&gt; helper. Each entry has thumbnail (with a duration badge overlaid bottom-right), title, and upload date in Turkish locale formatting.&lt;/p&gt;
&lt;h3&gt;YZ / AI provenance label&lt;a href=&quot;#yz--ai-provenance-label&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This morning’s last addition before the bilingual switch: an explicit &lt;code&gt;ai: true&lt;/code&gt; frontmatter flag on posts produced or substantially assisted by AI. Renders as a small bordered badge — &lt;strong&gt;YZ&lt;/strong&gt; on Turkish pages, &lt;strong&gt;AI&lt;/strong&gt; on English — next to the post title both in the feed and on the detail page. Distinct from tags (different element, different styling) so the provenance can’t be confused with a topic label.&lt;/p&gt;
&lt;p&gt;Both this post and the Ender 3 / Klipper migration post are flagged &lt;code&gt;ai: true&lt;/code&gt;. The technical content is mine; the prose was drafted by Claude based on my notes and edited.&lt;/p&gt;
&lt;h2&gt;Architecture summary&lt;a href=&quot;#architecture-summary&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;canata.dev          → 3D office scene (Three.js + WebGL + React 17)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      Worker handles /api/contact via Cloudflare Email Service&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      Static assets bound to ./public&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      Custom domain on Cloudflare Workers&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;canata-dev-inner    → desktop-OS site (React 17 / CRA)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  .bugra.workers.dev  Iframed by the outer scene&apos;s CRT monitor&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      Static assets only (no Worker code)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;notlar.im           → personal blog (Astro 5 / Tailwind v4 / MDX)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      Bilingual TR/EN&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      Static assets only&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;canata.com.tr       → email destination&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      Cloudflare Email Routing forwards to my inbox&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Three sites, three audiences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;canata.dev&lt;/strong&gt; — developers, recruiters. Leads with the freelance-since-2008 + AI / Cloudflare narrative.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bugracanata.com.tr&lt;/strong&gt; — Turkish educators / school audience. Still on the old stack; that one’s the next rebuild.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;notlar.im&lt;/strong&gt; — personal blog, both languages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each Cloudflare Worker config is a single &lt;code&gt;wrangler.jsonc&lt;/code&gt;. No GitHub Actions, no CI; deploys happen from my laptop with &lt;code&gt;pnpm deploy&lt;/code&gt;. The whole thing is small enough that adding pipelines would slow me down more than help.&lt;/p&gt;
&lt;h2&gt;What this evening’s exercise was actually about&lt;a href=&quot;#what-this-evenings-exercise-was-actually-about&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Two things, mostly.&lt;/p&gt;
&lt;p&gt;The first: &lt;strong&gt;letting the editing experience drive the architecture instead of the other way around.&lt;/strong&gt; I’d been off notlar.im for two years because the editor’s friction was too high — and that was a Docusaurus-shaped problem, not a “I have nothing to say” problem. Switching to flat markdown files in a familiar Astro project re-enabled writing in a literal afternoon. The lesson generalises: if you’re not using a tool you built for yourself, the cause is probably the tool, not you.&lt;/p&gt;
&lt;p&gt;The second: &lt;strong&gt;build-time vs. runtime is a knob, not a religion.&lt;/strong&gt; The YouTube page could have been a runtime fetch with caching. The Cloudflare Email Service binding could have been a third-party SMTP API. Each runtime dependency you add is a new failure mode to monitor. The Cloudflare Workers model — static assets first, Worker code only for the few actually-dynamic endpoints — keeps the surface area small. After this evening I have one Worker endpoint to monitor (the contact form), three static deploys that can fail only at build time, and a YouTube list that refreshes when I tell it to.&lt;/p&gt;
&lt;p&gt;That feels like the right amount of complexity for a personal site.&lt;/p&gt;</content:encoded><category>meta</category><category>cloudflare</category><category>astro</category><category>3d-portfolio</category></item><item><title>Modernizing an Ender 3 v2 in 48 Hours: From OctoPrint to Klipper, Tailscale HTTPS, and Six Calibrations</title><link>https://notlar.im/en/blog/ender-3-v2-klipper-migration/</link><guid isPermaLink="true">https://notlar.im/en/blog/ender-3-v2-klipper-migration/</guid><description>A two-day weekend log of moving an Ender 3 v2 off Marlin + OctoPi onto Klipper + Mainsail + OrcaSlicer + Tailscale, plus every calibration that comes after.</description><pubDate>Tue, 26 May 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Two days, one printer, a lot of small gotchas. This is the log of moving a working-but-tired Ender 3 v2 setup off Marlin + OctoPi and onto Klipper + Mainsail + OrcaSlicer + Tailscale, then dialing in every calibration the printer needs to actually print well.&lt;/p&gt;
&lt;p&gt;I’m writing this partly as documentation for future-me and partly because every single step in this journey was Googled at some point — and several answers I needed didn’t exist anywhere on the internet in the form they should have.&lt;/p&gt;
&lt;h2&gt;The starting point&lt;a href=&quot;#the-starting-point&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The printer is a 2020 Ender 3 v2 that’s been quietly accumulating upgrades:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mainboard&lt;/strong&gt;: stock 4.2.2 swapped for a Creality 4.2.7 silent board (STM32F103, supports BLTouch natively).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BLTouch clone&lt;/strong&gt; (one of the cheap 3DTouch boards) for ABL.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Filament runout sensor&lt;/strong&gt; wired to the dedicated 3-pin header.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Minimus Snap&lt;/strong&gt; hotend shroud and ABL backplate by Rogue Designs — a popular Ender 3 v2 cooling mod.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hotend rebuild kit&lt;/strong&gt;: Micro Swiss MK8 plated copper heater block, titanium bimetal heatbreak, CHT-style triple-orifice 0.4 mm carbon nozzle (Bondtech CHT clone), silicone sock, Capricorn 2/4 mm Bowden tube, and a generic 100K NTC thermistor that replaced the stock EPCOS one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Creality aluminum dual-gear extruder&lt;/strong&gt; (the 1:1 dual-grip aluminum upgrade, not Bondtech).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Glass bed&lt;/strong&gt; held by binder clips.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The control side was &lt;strong&gt;OctoPi on a Raspberry Pi 3 Model B&lt;/strong&gt;, with the printer USB-connected. The Pi was also running a &lt;strong&gt;Tuya smart plug&lt;/strong&gt; for automated printer power on/off via the &lt;a href=&quot;https://github.com/ziirish/OctoPrint-TuyaSmartplug&quot;&gt;TuyaSmartplug OctoPrint plugin&lt;/a&gt;, and Telegram notifications via OctoPrint’s Telegram plugin. Marlin firmware on the mainboard.&lt;/p&gt;
&lt;p&gt;It worked. But it was slow, and OctoPrint’s age was showing.&lt;/p&gt;
&lt;h2&gt;Why migrate&lt;a href=&quot;#why-migrate&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Three reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Speed&lt;/strong&gt;. Marlin caps acceleration around 500 mm/s² without aggressive tuning. Klipper with input shaper routinely runs 4000–8000 mm/s² on the same hardware. That’s a real difference in print times.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Slicer integration&lt;/strong&gt;. OrcaSlicer talks to Moonraker much more cleanly than to OctoPrint, including thumbnail preview in Mainsail.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remote access&lt;/strong&gt;. OctoPrint’s authentication and webcam stack felt like 2019. I wanted proper Tailscale + HTTPS, and Moonraker handles that gracefully.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The plan: do it all in a weekend.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Day 1: stack migration&lt;a href=&quot;#day-1-stack-migration&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;Backup everything&lt;a href=&quot;#backup-everything&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Before touching the Pi, I tar’d the whole &lt;code&gt;~/.octoprint&lt;/code&gt; directory to my Mac:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ssh&lt;/span&gt;&lt;span&gt; bcanata@octoprint.local&lt;/span&gt;&lt;span&gt; &apos;tar -czf /tmp/octoprint-backup.tar.gz ~/.octoprint&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;scp&lt;/span&gt;&lt;span&gt; bcanata@octoprint.local:/tmp/octoprint-backup.tar.gz&lt;/span&gt;&lt;span&gt; ~/backups/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most importantly, I extracted the Tuya plug’s &lt;strong&gt;device ID, local key, and protocol version&lt;/strong&gt; from &lt;code&gt;~/.octoprint/config.yaml&lt;/code&gt;. Those are not recoverable later — pairing a Tuya device via the official cloud and extracting the local key is the most annoying single task in 3D printing, and OctoPrint had already done it years ago. Saving the YAML block was the difference between “5 minute fix later” and “a Saturday”.&lt;/p&gt;
&lt;h3&gt;Install Klipper + Moonraker + Mainsail&lt;a href=&quot;#install-klipper--moonraker--mainsail&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Klipper’s own &lt;code&gt;scripts/install-debian.sh&lt;/code&gt; still tries to create the Python virtualenv with &lt;code&gt;python2&lt;/code&gt;. On a current Raspberry Pi OS that’s broken. The workaround is to install dependencies via apt and then build the venv manually:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt-get&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;span&gt; virtualenv&lt;/span&gt;&lt;span&gt; python3-dev&lt;/span&gt;&lt;span&gt; libffi-dev&lt;/span&gt;&lt;span&gt; build-essential&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  libncurses-dev&lt;/span&gt;&lt;span&gt; libusb-dev&lt;/span&gt;&lt;span&gt; avrdude&lt;/span&gt;&lt;span&gt; gcc-avr&lt;/span&gt;&lt;span&gt; binutils-avr&lt;/span&gt;&lt;span&gt; avr-libc&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  stm32flash&lt;/span&gt;&lt;span&gt; dfu-util&lt;/span&gt;&lt;span&gt; libnewlib-arm-none-eabi&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  gcc-arm-none-eabi&lt;/span&gt;&lt;span&gt; binutils-arm-none-eabi&lt;/span&gt;&lt;span&gt; libusb-1.0&lt;/span&gt;&lt;span&gt; pkg-config&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;virtualenv&lt;/span&gt;&lt;span&gt; -p&lt;/span&gt;&lt;span&gt; python3&lt;/span&gt;&lt;span&gt; ~/klippy-env&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;~&lt;/span&gt;&lt;span&gt;/klippy-env/bin/pip install -r &lt;/span&gt;&lt;span&gt;~&lt;/span&gt;&lt;span&gt;/klipper/scripts/klippy-requirements.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then a systemd unit, &lt;code&gt;klipper.service&lt;/code&gt;, that runs the host process. Moonraker’s installer worked out of the box. Mainsail is just a static SPA — drop the zip into &lt;code&gt;/home/bcanata/mainsail&lt;/code&gt; and serve via nginx.&lt;/p&gt;
&lt;p&gt;The catch with nginx: OctoPi’s haproxy was already listening on port 80. I gave Mainsail port 81 initially, kept OctoPrint alive on 80, and switched ports later once I was sure the new stack worked.&lt;/p&gt;
&lt;h3&gt;Build and flash Klipper firmware for the 4.2.7&lt;a href=&quot;#build-and-flash-klipper-firmware-for-the-427&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The 4.2.7 uses an STM32F103, 28KiB Creality bootloader, USART1 serial communication. The &lt;code&gt;make menuconfig&lt;/code&gt; choices are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Micro-controller Architecture (STMicroelectronics STM32)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Processor model (STM32F103)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Bootloader offset (28KiB bootloader)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Clock Reference (8 MHz crystal)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Communication interface (Serial (on USART1 PA10/PA9))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Baud rate for serial port (250000)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The output is &lt;code&gt;out/klipper.bin&lt;/code&gt;. Creality’s bootloader flashes files named &lt;code&gt;firmware.bin&lt;/code&gt; placed on an SD card at the front of the LCD. Copy, insert, power on, wait 30 s, done.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cp&lt;/span&gt;&lt;span&gt; out/klipper.bin&lt;/span&gt;&lt;span&gt; /Volumes/SD/firmware.bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A subtle gotcha: the bootloader renames the file to &lt;code&gt;FIRMWARE.CUR&lt;/code&gt; after a successful flash. If your file is still &lt;code&gt;firmware.bin&lt;/code&gt; after, the flash didn’t happen. Most common cause is FAT32 cluster size — format 4 KiB clusters.&lt;/p&gt;
&lt;h3&gt;printer.cfg, the long version&lt;a href=&quot;#printercfg-the-long-version&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I started from the canonical &lt;code&gt;~/klipper/config/generic-creality-v4.2.7.cfg&lt;/code&gt; and layered on the BLTouch, filament sensor, bed mesh, and macros. The interesting Ender 3 v2 sections look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[board_pins]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;aliases:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  EXP1_1&lt;/span&gt;&lt;span&gt;=PC6,  &lt;/span&gt;&lt;span&gt;EXP1_3&lt;/span&gt;&lt;span&gt;=PB10, &lt;/span&gt;&lt;span&gt;EXP1_5&lt;/span&gt;&lt;span&gt;=PB14, &lt;/span&gt;&lt;span&gt;EXP1_7&lt;/span&gt;&lt;span&gt;=PB12, &lt;/span&gt;&lt;span&gt;EXP1_9&lt;/span&gt;&lt;span&gt;=&amp;lt;GND&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  EXP1_2&lt;/span&gt;&lt;span&gt;=PB2,  &lt;/span&gt;&lt;span&gt;EXP1_4&lt;/span&gt;&lt;span&gt;=PB11, &lt;/span&gt;&lt;span&gt;EXP1_6&lt;/span&gt;&lt;span&gt;=PB13, &lt;/span&gt;&lt;span&gt;EXP1_8&lt;/span&gt;&lt;span&gt;=PB15, &lt;/span&gt;&lt;span&gt;EXP1_10&lt;/span&gt;&lt;span&gt;=&amp;lt;5V&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  PROBE_IN&lt;/span&gt;&lt;span&gt;=PB0, &lt;/span&gt;&lt;span&gt;PROBE_OUT&lt;/span&gt;&lt;span&gt;=PB1, &lt;/span&gt;&lt;span&gt;FIL_RUNOUT&lt;/span&gt;&lt;span&gt;=PA4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[bltouch]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sensor_pin: ^PROBE_OUT&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;control_pin: PROBE_IN&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;x_offset: -45&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;y_offset: -10&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;z_offset: 2.0       &lt;/span&gt;&lt;span&gt;# placeholder — will be PROBE_CALIBRATE&apos;d later&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;speed: 3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sample_retract_dist: 3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;probe_with_touch_mode: false   &lt;/span&gt;&lt;span&gt;# KEY for BLTouch clones, see below&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;stow_on_each_sample: true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;samples: 3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;samples_result: median&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;samples_tolerance: 0.1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;samples_tolerance_retries: 3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Gotcha #1: the BLTouch clone trap&lt;a href=&quot;#gotcha-1-the-bltouch-clone-trap&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;After flashing, &lt;code&gt;QUERY_PROBE&lt;/code&gt; returned sane states, and pushing the deployed stylus by hand correctly flipped the probe from &lt;code&gt;open&lt;/code&gt; to &lt;code&gt;TRIGGERED&lt;/code&gt;. So wiring was right.&lt;/p&gt;
&lt;p&gt;Then I ran &lt;code&gt;G28&lt;/code&gt;. The toolhead went to safe_z_home (117.5, 117.5), started lowering Z, and &lt;strong&gt;never stopped&lt;/strong&gt;. The Z axis drove the nozzle down into the bed, racked up &lt;code&gt;position 374&lt;/code&gt; in Klipper’s tracker (well past &lt;code&gt;position_max: 250&lt;/code&gt;), and required a hardware power-cycle to recover.&lt;/p&gt;
&lt;p&gt;What happened: BLTouch v3 has a special “touch mode” that some Klipper users enable with &lt;code&gt;probe_with_touch_mode: true&lt;/code&gt;. Genuine v3s implement this correctly. &lt;strong&gt;Clones don’t.&lt;/strong&gt; They accept the command, but the trigger signal never gets propagated during the probe move. The stylus physically touches the bed, gets pushed up — and Klipper sees nothing.&lt;/p&gt;
&lt;p&gt;The fix is one line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;probe_with_touch_mode: false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;stow_on_each_sample: true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Plus &lt;code&gt;samples: 3, samples_result: median, samples_tolerance: 0.1&lt;/code&gt; to catch the occasional bad reading the clone still produces.&lt;/p&gt;
&lt;p&gt;If you have a 3DTouch, CR-Touch, or any BL-knockoff, those four lines are the difference between a working printer and a damaged bed.&lt;/p&gt;
&lt;h3&gt;Decommissioning OctoPrint&lt;a href=&quot;#decommissioning-octoprint&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Once Mainsail was confirmed working:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; systemctl&lt;/span&gt;&lt;span&gt; disable&lt;/span&gt;&lt;span&gt; --now&lt;/span&gt;&lt;span&gt; octoprint&lt;/span&gt;&lt;span&gt; haproxy&lt;/span&gt;&lt;span&gt; gencert&lt;/span&gt;&lt;span&gt; sshswitch&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; systemctl&lt;/span&gt;&lt;span&gt; disable&lt;/span&gt;&lt;span&gt; --now&lt;/span&gt;&lt;span&gt; bluetooth&lt;/span&gt;&lt;span&gt; hciuart&lt;/span&gt;&lt;span&gt; ModemManager&lt;/span&gt;&lt;span&gt; triggerhappy&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt-get&lt;/span&gt;&lt;span&gt; purge&lt;/span&gt;&lt;span&gt; haproxy&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; rm&lt;/span&gt;&lt;span&gt; -rf&lt;/span&gt;&lt;span&gt; /opt/octopi&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mv&lt;/span&gt;&lt;span&gt; ~/.octoprint&lt;/span&gt;&lt;span&gt; ~/.octoprint.removed-2026-05-24&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then moved Mainsail’s nginx from port 81 to port 80. Lost about 50 MB of RAM, freed 257 MB of disk, and the Pi felt noticeably snappier.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Day 2 morning: bed mesh, the binder-clip surprise&lt;a href=&quot;#day-2-morning-bed-mesh-the-binder-clip-surprise&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Klipper restarted clean. &lt;code&gt;G28&lt;/code&gt; worked. Time for &lt;code&gt;BED_MESH_CALIBRATE&lt;/code&gt; — a 5×5 grid, ~25 probe points.&lt;/p&gt;
&lt;p&gt;Result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;back  +0.122 +0.098 +0.018 -0.028 -0.060&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      +0.131 +0.069 +0.004 -0.009 -0.043&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      +0.129 +0.052 +0.033 +0.004 -0.113&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      +0.171 +0.096 +0.062 +0.016 +0.000&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;front +0.115 +0.079 +1.569 +0.009 -0.099&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        L                              R&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That &lt;strong&gt;+1.569 mm&lt;/strong&gt; in the bottom-middle was bizarre. 17× the variance of every other point. I assumed it was a clone probe glitch — bumped samples to 5 with tighter tolerance, re-ran. Same value.&lt;/p&gt;
&lt;p&gt;Turned out to be the &lt;strong&gt;binder clip&lt;/strong&gt; in the back-center holding the glass to the heatbed. The probe was hitting it. The clip’s metal arm extends about 15 mm into the bed area, well into my mesh range.&lt;/p&gt;
&lt;p&gt;The fix: shrink the mesh bounds. With probe &lt;code&gt;x_offset: -45&lt;/code&gt; and toolhead &lt;code&gt;position_max: 235&lt;/code&gt;, the max safe &lt;strong&gt;probe X&lt;/strong&gt; is 235 − 45 = 190. With clips at the back edge, probe Y caps at 200. So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[bed_mesh]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mesh_min: 20, 20&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mesh_max: 190, 200    &lt;/span&gt;&lt;span&gt;# NOT 220, NOT 235&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Ender 3 v2’s printable area is 220×220 mm, but the meshable area with clips is only 180×180. Klipper extrapolates the bicubic mesh out to the print area edges, which is fine.&lt;/p&gt;
&lt;h3&gt;Z-offset and the paper test&lt;a href=&quot;#z-offset-and-the-paper-test&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;PROBE_CALIBRATE&lt;/code&gt;, then in the manual probe mode:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;TESTZ Z=-1        # repeat ~5 times to drop near bed&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;TESTZ Z=-0.1      # fine&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;TESTZ Z=-0.025    # finer&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ACCEPT&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;SAVE_CONFIG&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Final value: &lt;code&gt;z_offset = 2.977&lt;/code&gt;. Later bumped to &lt;code&gt;3.077&lt;/code&gt; after a first-print babystep showed the original was slightly too low. Both values are normal for a BLTouch clone on a Minimus Snap mount.&lt;/p&gt;
&lt;h2&gt;Day 2 afternoon: PID, but with the right curve&lt;a href=&quot;#day-2-afternoon-pid-but-with-the-right-curve&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The hotend rebuild kit included a &lt;strong&gt;generic 100K NTC thermistor&lt;/strong&gt; to replace the stock EPCOS. I’d been running PID calibration with &lt;code&gt;sensor_type: EPCOS 100K B57560G104F&lt;/code&gt; (the default), but the physical thermistor was now a different curve. At room temperature the two curves are nearly identical, but they diverge significantly at print temperatures.&lt;/p&gt;
&lt;p&gt;Translation: my “210°C PID tune” was actually at something like 215°C or 205°C, and the PID values were off.&lt;/p&gt;
&lt;p&gt;Fix:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sensor_type: Generic 3950&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;max_temp: 280       &lt;/span&gt;&lt;span&gt;# Micro Swiss + Ti heatbreak + silicone sock can handle it&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then &lt;code&gt;PID_CALIBRATE HEATER=extruder TARGET=220&lt;/code&gt; (CHT-friendly target):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pid_Kp = 28.408&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pid_Ki = 2.059&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pid_Kd = 98.008&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the bed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;pid_Kp = 68.358&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pid_Ki = 1.313&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pid_Kd = 889.507&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Extruder calibration: 32% off&lt;a href=&quot;#extruder-calibration-32-off&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The classic test: mark filament 120 mm above the extruder inlet, command 100 mm of extrusion, measure how much actually moved.&lt;/p&gt;
&lt;p&gt;First pass result: &lt;strong&gt;52 mm of filament remained from the 120 mm mark&lt;/strong&gt;. That meant 68 mm extruded vs 100 mm commanded — 32% under-extrusion.&lt;/p&gt;
&lt;p&gt;My first instinct was mechanical fault (gear slipping, filament jam, tension off). Then I remembered: the user has the &lt;strong&gt;Creality aluminum dual-gear extruder&lt;/strong&gt;, not stock. Different drive hob, different gear circumference.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;new_rotation_distance = old × (actual / commanded) = 33.500 × 0.68 = 22.78&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Updated &lt;code&gt;rotation_distance: 22.78&lt;/code&gt;, re-ran the test. Second pass: 20.3 mm remaining. &lt;strong&gt;99.7 mm extruded vs 100 mm commanded — 0.3% accuracy.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Most online configs assume the stock Creality MK8 extruder with &lt;code&gt;rotation_distance: 33.5&lt;/code&gt;. If you have any aftermarket extruder, you have to recalibrate from scratch. The “20% extrusion error from new tube/extruder/nozzle” thing is real.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Input shaper with an MPU-6050&lt;a href=&quot;#input-shaper-with-an-mpu-6050&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The ADXL345 is the community-standard accelerometer for Klipper input shaping, but the printer owner had a &lt;strong&gt;GY-521 / MPU-6050&lt;/strong&gt; breakout already. Klipper’s &lt;code&gt;mpu9250&lt;/code&gt; driver supports the MPU-6050 (despite the name) via the same I2C bus.&lt;/p&gt;
&lt;p&gt;Wiring is dead simple — 4 wires:&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;MPU-6050&lt;/th&gt;&lt;th&gt;Pi physical pin&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;VCC&lt;/td&gt;&lt;td&gt;1 (3.3 V — &lt;em&gt;not&lt;/em&gt; 5 V, the chip is 3.3 V only)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;GND&lt;/td&gt;&lt;td&gt;6&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SDA&lt;/td&gt;&lt;td&gt;3 (GPIO 2 / I2C1 SDA)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SCL&lt;/td&gt;&lt;td&gt;5 (GPIO 3 / I2C1 SCL)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Software setup is more involved:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enable I2C: &lt;code&gt;sudo raspi-config nonint do_i2c 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add user to groups: &lt;code&gt;sudo usermod -a -G i2c,gpio,spi $USER&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Build a Linux MCU target of Klipper itself: &lt;code&gt;make menuconfig&lt;/code&gt; → Linux process. Copy &lt;code&gt;out/klipper.elf&lt;/code&gt; to &lt;code&gt;/usr/local/bin/klipper_mcu&lt;/code&gt; and write a systemd unit that runs it on boot. This creates &lt;code&gt;/tmp/klipper_host_mcu&lt;/code&gt;, a UDS that Klipper’s main host process can talk to as a secondary MCU.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pip install numpy&lt;/code&gt; into the klippy venv (resonance math needs it).&lt;/li&gt;
&lt;li&gt;Add to &lt;code&gt;printer.cfg&lt;/code&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[mcu rpi]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;serial: /tmp/klipper_host_mcu&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[mpu9250]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;i2c_mcu: rpi&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;i2c_bus: i2c.1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[resonance_tester]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;accel_chip: mpu9250&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;probe_points:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    117.5, 117.5, 20&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the sensor on the toolhead (X test), run &lt;code&gt;SHAPER_CALIBRATE AXIS=X&lt;/code&gt;. Move sensor to the bed for the Y test, repeat. The printer makes loud chirping noises for ~3 minutes per axis as it rings through frequencies 5–130 Hz.&lt;/p&gt;
&lt;p&gt;Results:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;X: mzv @ 78.6 Hz, 0.1% residual vibration  (allows max_accel 18200)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Y: ei  @ 51.2 Hz, 0.0% residual vibration  (allows max_accel 4800)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;new max_accel = min(18200, 4800) = 4800 mm/s²&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That &lt;strong&gt;78.6 Hz on X&lt;/strong&gt; is unusually high for an Ender 3 v2 (typical is 35–50 Hz). The lighter Micro Swiss + CHT toolhead explains it — less mass → higher natural frequency → more available headroom.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;max_accel&lt;/code&gt; went from 3000 to 4800. 60% improvement, capped by the bed’s mass on Y as expected for a bed-slinger.&lt;/p&gt;
&lt;p&gt;After calibration, &lt;strong&gt;you don’t need the sensor anymore.&lt;/strong&gt; The shaper frequencies are baked into &lt;code&gt;printer.cfg&lt;/code&gt;. Klipper applies the math to every move based on the saved values. Re-run only after mechanical changes (new hotend, new bed surface, retensioned belts).&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Tuya plug, the OctoPrint replacement&lt;a href=&quot;#tuya-plug-the-octoprint-replacement&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The OctoPrint Tuya plugin had to be replaced. Moonraker’s &lt;code&gt;[power]&lt;/code&gt; module supports a bunch of device types — &lt;code&gt;tplink_smartplug&lt;/code&gt;, &lt;code&gt;tasmota&lt;/code&gt;, &lt;code&gt;mqtt&lt;/code&gt;, &lt;code&gt;homeassistant&lt;/code&gt;, &lt;code&gt;http&lt;/code&gt;, etc. — but &lt;strong&gt;not Tuya&lt;/strong&gt; natively.&lt;/p&gt;
&lt;p&gt;The cleanest solution is to run a tiny &lt;strong&gt;HTTP bridge service&lt;/strong&gt; on the Pi that exposes &lt;code&gt;/on&lt;/code&gt;, &lt;code&gt;/off&lt;/code&gt;, and &lt;code&gt;/state&lt;/code&gt; endpoints, talks to the Tuya plug locally via the &lt;a href=&quot;https://github.com/jasonacox/tinytuya&quot;&gt;tinytuya&lt;/a&gt; library, and then point Moonraker’s &lt;code&gt;[power] type: http&lt;/code&gt; at that bridge.&lt;/p&gt;
&lt;p&gt;About 100 lines of Python:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; http.server, json, threading, time, tinytuya&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PLUG&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; tinytuya.OutletDevice(&lt;/span&gt;&lt;span&gt;DEV_ID&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;IP&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;LOCAL_KEY&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PLUG&lt;/span&gt;&lt;span&gt;.set_version(&lt;/span&gt;&lt;span&gt;3.3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;_lock &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; threading.Lock()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;_cache &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt;&quot;value&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;None&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;ts&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;0.0&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; query_state&lt;/span&gt;&lt;span&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; _cache[&lt;/span&gt;&lt;span&gt;&quot;value&quot;&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;is&lt;/span&gt;&lt;span&gt; not&lt;/span&gt;&lt;span&gt; None&lt;/span&gt;&lt;span&gt; and&lt;/span&gt;&lt;span&gt; time.monotonic() &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; _cache[&lt;/span&gt;&lt;span&gt;&quot;ts&quot;&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; 3.0&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; _cache[&lt;/span&gt;&lt;span&gt;&quot;value&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    with&lt;/span&gt;&lt;span&gt; _lock:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        status &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; _call_with_retries(&lt;/span&gt;&lt;span&gt;lambda&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;PLUG&lt;/span&gt;&lt;span&gt;.status())&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    on &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; bool&lt;/span&gt;&lt;span&gt;(status[&lt;/span&gt;&lt;span&gt;&quot;dps&quot;&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    _cache[&lt;/span&gt;&lt;span&gt;&quot;value&quot;&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; on&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    _cache[&lt;/span&gt;&lt;span&gt;&quot;ts&quot;&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; time.monotonic()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; on&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The cache and retry-with-backoff are necessary because &lt;strong&gt;Tuya plugs serialize TCP connections and reject rapid-fire requests&lt;/strong&gt;. Moonraker pings the status URL during init and got &lt;code&gt;Err 901: Network Error: Unable to Connect&lt;/code&gt;. Adding a 3-second response cache and exponential backoff on retries fixed it.&lt;/p&gt;
&lt;p&gt;Moonraker side:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[power tuya_plug]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;type: http&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;on_url: http://127.0.0.1:7126/on&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;off_url: http://127.0.0.1:7126/off&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;status_url: http://127.0.0.1:7126/state&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;response_template: {% if &lt;/span&gt;&lt;span&gt;&quot;on&quot;&lt;/span&gt;&lt;span&gt; in http_request.last_response().text %}on{% else %}off{% endif %}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;on_when_job_queued: True&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;locked_while_printing: True&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;restart_klipper_when_powered: True&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;restart_delay: 8&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;bound_services: klipper&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Two more landmines&lt;/strong&gt; for anyone doing this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Moonraker’s config parser chokes on Jinja &lt;code&gt;{{ }}&lt;/code&gt; syntax&lt;/strong&gt; because it conflicts with its own &lt;code&gt;${}&lt;/code&gt; interpolation. Use &lt;code&gt;{% if %}...{% endif %}&lt;/code&gt; blocks instead, which output raw text.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The template variable is &lt;code&gt;http_request.last_response().text&lt;/code&gt;, not &lt;code&gt;http_response&lt;/code&gt;.&lt;/strong&gt; The Moonraker docs example used to be ambiguous about this. If your &lt;code&gt;response_template&lt;/code&gt; evaluates against &lt;code&gt;http_response&lt;/code&gt;, that’s an undefined Jinja variable, and the template always evaluates to “off” — even when the plug is actually on.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I lost an hour to each of those.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Tailscale and HTTPS via Let’s Encrypt&lt;a href=&quot;#tailscale-and-https-via-lets-encrypt&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I wanted to control the printer from anywhere — phone on cellular, laptop at work — without exposing it to the public internet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tailscale on the Pi&lt;/strong&gt; handles the VPN side. &lt;code&gt;tailscale up --ssh&lt;/code&gt; on the Pi adds it to my tailnet, makes it reachable via its 100.x.x.x IP, and enables Tailscale SSH (no password auth required from tailnet members).&lt;/p&gt;
&lt;p&gt;But that gives you HTTP at &lt;code&gt;http://100.x.x.x/&lt;/code&gt;. Safari hates bare IPs with WebSocket. iOS/iPadOS browsers refuse some “secure context” APIs over plain HTTP. The right answer is &lt;strong&gt;HTTPS with a real cert&lt;/strong&gt; — which Tailscale provides for free:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enable “HTTPS Certificates” in the Tailscale admin console (one toggle).&lt;/li&gt;
&lt;li&gt;On the Pi: &lt;code&gt;sudo tailscale cert octoprint-ev.tailnet-f1f8.ts.net&lt;/code&gt;. Pulls a real Let’s Encrypt cert valid for 90 days.&lt;/li&gt;
&lt;li&gt;nginx vhost listening on 443 with that cert, redirect 80 → 443.&lt;/li&gt;
&lt;li&gt;Systemd timer twice a day to re-run &lt;code&gt;tailscale cert&lt;/code&gt; (no-op until close to expiry, otherwise refreshes the cert).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now &lt;code&gt;https://octoprint-ev.tailnet-f1f8.ts.net/&lt;/code&gt; loads Mainsail with a green padlock from anywhere I have Tailscale.&lt;/p&gt;
&lt;h3&gt;One CORS pothole&lt;a href=&quot;#one-cors-pothole&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Mainsail loaded fine over HTTPS. But the browser’s developer console showed dozens of WebSocket errors:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;WebSocket connection to &apos;wss://octoprint-ev.tailnet-f1f8.ts.net/websocket&apos; failed&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The cause: Moonraker’s &lt;code&gt;cors_domains&lt;/code&gt; whitelist didn’t include the new hostname. Added &lt;code&gt;*.ts.net&lt;/code&gt; to the list, restarted Moonraker, errors gone. WebSocket connections from any tailnet hostname now allowed.&lt;/p&gt;
&lt;p&gt;For direct API calls (not through Mainsail), there’s also &lt;code&gt;[authorization] trusted_clients&lt;/code&gt;. Adding &lt;code&gt;100.64.0.0/10&lt;/code&gt; (the Tailscale CGNAT range) makes API calls from any tailnet IP unauthenticated. Safe because only my own devices are on the tailnet.&lt;/p&gt;
&lt;h3&gt;Webcam: Safari hates MJPEG&lt;a href=&quot;#webcam-safari-hates-mjpeg&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The default Mainsail webcam service is &lt;strong&gt;mjpegstreamer&lt;/strong&gt;, which serves &lt;code&gt;multipart/x-mixed-replace&lt;/code&gt; MJPEG streams. Chrome and Firefox render them. Safari doesn’t.&lt;/p&gt;
&lt;p&gt;Camera-streamer (the modern replacement for mjpg-streamer) also serves &lt;strong&gt;WebRTC&lt;/strong&gt; and &lt;strong&gt;HLS&lt;/strong&gt;, both of which Safari supports natively. Switching the Mainsail webcam config to &lt;code&gt;service: webrtc-camerastreamer&lt;/code&gt; with stream URL &lt;code&gt;/webcam/webrtc&lt;/code&gt; made the camera show up reliably in every browser.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;OrcaSlicer integration&lt;a href=&quot;#orcaslicer-integration&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;OrcaSlicer talks to Moonraker over HTTPS using the printer profile’s &lt;code&gt;print_host&lt;/code&gt; field. Three lessons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Put &lt;code&gt;https://&lt;/code&gt; in the &lt;code&gt;print_host&lt;/code&gt; field&lt;/strong&gt;, not just the hostname. Otherwise OrcaSlicer tries &lt;code&gt;http://&lt;/code&gt;, gets a 301 redirect, tries to follow it with a rewind of the upload buffer, and dies with &lt;strong&gt;curl Error 65: “Cannot rewind mime/post data”&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Profile changes require an OrcaSlicer restart.&lt;/strong&gt; The app caches the profile JSON at startup and ignores file changes until you quit and reopen.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OrcaCloud login creates a new user directory&lt;/strong&gt; under &lt;code&gt;~/Library/Application Support/OrcaSlicer/user/&amp;lt;your-cloud-id&amp;gt;/&lt;/code&gt; and Orca then ignores &lt;code&gt;user/default/&lt;/code&gt;. If your profiles “disappear” after logging in, copy them from &lt;code&gt;default/&lt;/code&gt; to the new cloud user dir manually.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the Ender 3 v2 + Klipper setup I created:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;printer profile&lt;/strong&gt; pointing at the Tailscale HTTPS host, with &lt;code&gt;gcode_flavor: klipper&lt;/code&gt;, custom &lt;code&gt;PRINT_START&lt;/code&gt;/&lt;code&gt;PRINT_END&lt;/code&gt; macros (one line each, just calls the Klipper macro), thumbnails enabled, and &lt;code&gt;machine_max_acceleration_*: 4800&lt;/code&gt; to match Klipper.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;filament profile&lt;/strong&gt; “Generic PLA - CHT hotend” with &lt;code&gt;filament_max_volumetric_speed: 20 mm³/s&lt;/code&gt; (conservative; can bump after a Max Volumetric Speed test).&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;process profile&lt;/strong&gt; “0.20mm Klipper Fast” with reasonable speeds (outer wall 50, inner 120, infill 150, travel 200) and accelerations matching the input shaper’s headroom.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Calibration tests, in order&lt;a href=&quot;#calibration-tests-in-order&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Each test produces one number that goes into a config file. Each catches a different class of problem.&lt;/p&gt;


















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Test&lt;/th&gt;&lt;th&gt;Result&lt;/th&gt;&lt;th&gt;What it dialed in&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;PROBE_CALIBRATE&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;z_offset = &lt;strong&gt;3.077&lt;/strong&gt; mm&lt;/td&gt;&lt;td&gt;The exact distance the BLTouch trigger point sits above the nozzle&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;PID_CALIBRATE extruder&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Kp 28.408 / Ki 2.059 / Kd 98.008&lt;/td&gt;&lt;td&gt;Stable hotend temperature with the new copper block + NTC thermistor&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;PID_CALIBRATE heater_bed&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Kp 68.358 / Ki 1.313 / Kd 889.507&lt;/td&gt;&lt;td&gt;Stable bed temperature&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Rotation distance&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;22.78 (was 33.500)&lt;/td&gt;&lt;td&gt;Extruder gear → filament displacement ratio. Off by 32% because of the dual-gear extruder.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;SHAPER_CALIBRATE AXIS=X&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;mzv @ 78.6 Hz&lt;/td&gt;&lt;td&gt;X-axis ringing compensation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;SHAPER_CALIBRATE AXIS=Y&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;ei @ 51.2 Hz&lt;/td&gt;&lt;td&gt;Y-axis ringing compensation (the limiter)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;OrcaSlicer Flow Rate Pass 1&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;0 modifier → 0.98 unchanged&lt;/td&gt;&lt;td&gt;Per-filament flow calibration&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;OrcaSlicer Pressure Advance Tower&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;0.030&lt;/td&gt;&lt;td&gt;Nozzle pressure ramp-up at speed changes&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The flow rate test came back perfect — “0” was the cleanest of the nine printed squares, meaning the existing 0.98 flow_ratio was already correct. That was a satisfying anticlimax.&lt;/p&gt;
&lt;p&gt;PA was less crisp; the seam test showed an oddly uniform tower with isolated blob artifacts at two specific PA values. Best read was &lt;strong&gt;wide acceptable range, locked in at 0.030 conservative&lt;/strong&gt;. PA tuning at 50 mm/s outer-wall speeds doesn’t show dramatic differences anyway — you can revisit after pushing speeds higher.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;The filament sensor pause loop&lt;a href=&quot;#the-filament-sensor-pause-loop&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Halfway through the flow rate calibration print, the runout sensor triggered, the print paused, the runout_gcode tried to call &lt;code&gt;M600&lt;/code&gt;, and Klipper threw:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Unknown command: &quot;M600&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Two problems revealed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Klipper doesn’t ship with &lt;code&gt;M600&lt;/code&gt;&lt;/strong&gt; — it’s a Marlin filament-change G-code. Some slicers emit it. I had referenced it in my &lt;code&gt;runout_gcode&lt;/code&gt; macro assuming it existed. Fix: defined an &lt;code&gt;[gcode_macro M600]&lt;/code&gt; that aliases to &lt;code&gt;PAUSE&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The sensor was triggering falsely.&lt;/strong&gt; Filament was still loaded. The microswitch in the runout sensor was chattering during bed-slinger Y moves — vibration-induced contact bounces that read as a brief disconnect. Killed the print until the sensor decided to stop seeing nothing.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Live-disabled via &lt;code&gt;SET_FILAMENT_SENSOR SENSOR=runout ENABLE=0&lt;/code&gt; to finish the print, then permanently set &lt;code&gt;pause_on_runout: False&lt;/code&gt; in printer.cfg. The sensor stays wired and queryable — I’ll re-enable after physically inspecting the microswitch.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Where we are now&lt;a href=&quot;#where-we-are-now&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Forty-eight hours after starting, the printer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Runs Klipper on the 4.2.7 board with full BLTouch + filament sensor + mesh compensation.&lt;/li&gt;
&lt;li&gt;Is reachable at &lt;strong&gt;&lt;a href=&quot;https://octoprint-ev.tailnet-f1f8.ts.net/&quot;&gt;https://octoprint-ev.tailnet-f1f8.ts.net/&lt;/a&gt;&lt;/strong&gt; from any device on my tailnet, with a real Let’s Encrypt cert.&lt;/li&gt;
&lt;li&gt;Auto-powers on via the Tuya plug when a print is queued; auto-powers off 60 seconds after print completion.&lt;/li&gt;
&lt;li&gt;Sends Telegram notifications via &lt;a href=&quot;https://github.com/nlef/moonraker-telegram-bot&quot;&gt;moonraker-telegram-bot&lt;/a&gt; using the same bot token and chat ID the OctoPrint plugin used.&lt;/li&gt;
&lt;li&gt;Live webcam in Mainsail via WebRTC, works in Safari.&lt;/li&gt;
&lt;li&gt;Inputs shaped, max_accel at 4800, flow ratio dialed, pressure advance set.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first real test print (a 30 mm calibration cube) came out fine after I added a &lt;strong&gt;prime line&lt;/strong&gt; to the &lt;code&gt;PRINT_START&lt;/code&gt; macro — the stock Marlin macro had one, the Klipper version I’d written didn’t, and the very first layer of the very first print showed missing extrusion in a few spots because the nozzle wasn’t fully primed.&lt;/p&gt;
&lt;p&gt;That’s been the pattern of this whole migration: &lt;strong&gt;every step works once you find the one thing the standard tutorials don’t mention.&lt;/strong&gt; Hopefully this document is one less thing future-me has to discover the hard way.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;TL;DR for anyone doing the same migration&lt;a href=&quot;#tldr-for-anyone-doing-the-same-migration&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you’re an Ender 3 v2 owner thinking about leaving OctoPrint, here’s the &lt;strong&gt;short version&lt;/strong&gt; of the pitfalls:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;BLTouch clones need &lt;code&gt;probe_with_touch_mode: false&lt;/code&gt;&lt;/strong&gt;, period. If your Z homing crashes, this is it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The OrcaSlicer &lt;code&gt;print_host&lt;/code&gt; field needs the &lt;code&gt;https://&lt;/code&gt; prefix&lt;/strong&gt; if your nginx redirects HTTP → HTTPS. Otherwise: curl Error 65.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Moonraker’s &lt;code&gt;cors_domains&lt;/code&gt; must include the Tailscale hostname&lt;/strong&gt; for WebSockets to work over HTTPS.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Moonraker Jinja template variable is &lt;code&gt;http_request.last_response().text&lt;/code&gt;&lt;/strong&gt;, not &lt;code&gt;http_response&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don’t blindly &lt;code&gt;scp&lt;/code&gt; printer.cfg from your laptop to the Pi.&lt;/strong&gt; SAVE_CONFIG appends to the file on the Pi; overwriting wipes your bed mesh and PID values. Always pull → edit → push.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Calibrate &lt;code&gt;rotation_distance&lt;/code&gt; from scratch if you have an aftermarket extruder.&lt;/strong&gt; The 33.5 in every tutorial only applies to the stock Creality MK8 plastic extruder.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Re-run PID_CALIBRATE after swapping a thermistor.&lt;/strong&gt; The default &lt;code&gt;EPCOS 100K B57560G104F&lt;/code&gt; and generic &lt;code&gt;Generic 3950&lt;/code&gt; curves are similar at room temperature and diverge at print temperatures. Your PID values are tuned to the wrong target temperature if the sensor_type doesn’t match what’s actually in the heater block.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Klipper’s &lt;code&gt;SCREWS_TILT_CALCULATE&lt;/code&gt; is better than Marlin’s bed-level assist.&lt;/strong&gt; Use it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MPU-6050 works fine for input shaper.&lt;/strong&gt; ADXL345 is preferred but not necessary. 1 kHz sample rate is enough for the 30–80 Hz resonances of a stock-frame Ender.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailscale’s free HTTPS certs make remote printing actually pleasant.&lt;/strong&gt; Stop port-forwarding. Stop putting OctoPrint on the open internet.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you only do one thing from this list: enable input shaper. Going from 3000 to 4800 mm/s² alone shaves an hour off a four-hour print, with no visible quality loss. Combined with the volumetric headroom from the CHT nozzle, you’re looking at 2× faster prints out of a $200 printer.&lt;/p&gt;
&lt;p&gt;That’s the upgrade I should have done years ago.&lt;/p&gt;</content:encoded><category>3d-printing</category><category>klipper</category><category>ender-3</category><category>homelab</category></item><item><title>Amazing Websites Few People Know About</title><link>https://notlar.im/en/blog/amazing-lesser-known-websites-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/amazing-lesser-known-websites-en/</guid><description>A continuation of my Ekşi Sözlük list, moved from there to notlar.im — a collection of useful websites few people know about.</description><pubDate>Wed, 04 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The version on Ekşi Sözlük (a Turkish collaborative dictionary site) turned into garbage, so let’s continue here.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://notebooklm.google/&quot;&gt;notebooklm.google&lt;/a&gt; — Google’s AI-powered notebook. You can add PDFs and other files, and when you ask it something it answers with citations to your sources.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fccid.io/&quot;&gt;fccid.io&lt;/a&gt; — A site collecting the licensing records of the FCC, the US Federal Communications Commission. From the documents submitted for devices approved for sale, you can even see photos of a device’s internals.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://free-for.dev/&quot;&gt;free-for.dev&lt;/a&gt; — Lists free resources for developers.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://app.recraft.ai/&quot;&gt;recraft.ai&lt;/a&gt; — A vector-generation app. It creates the logo you describe as a vector, and you can export it as SVG.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.foldnfly.com/&quot;&gt;foldnfly.com&lt;/a&gt; — Instructions for folding paper airplanes in different designs.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.onlinedoctranslator.com/en/translationform&quot;&gt;onlinedoctranslator.com&lt;/a&gt; — Translates PDF, DOC and similar files online, powered by Google Translate.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://secondlifestorage.com/index.php?pages/cell-database/&quot;&gt;secondlifestorage.com cell database&lt;/a&gt; — A database of 18650 batteries. Helps you figure out which battery is which model.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://standardebooks.org/&quot;&gt;standardebooks.org&lt;/a&gt; — Collects and publishes e-books that are out of copyright.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://domainr.com/&quot;&gt;domainr.com&lt;/a&gt; — A domain search tool that also shows domain-hack style short names.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tld-list.com/&quot;&gt;tld-list.com&lt;/a&gt; — Shows which registrars sell/renew each TLD at the cheapest price.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://elevenlabs.io/&quot;&gt;elevenlabs.io&lt;/a&gt; — Converts text to speech with AI. Supports Turkish too.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lookscanned.io/scan&quot;&gt;lookscanned.io&lt;/a&gt; — Makes an uploaded document look like it went through a scanner. Handy for making files signed on a tablet look “scanned”.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://annas-archive.org/&quot;&gt;annas-archive.org&lt;/a&gt; — An e-book site mirroring Sci-Hub, LibGen, Z-Library and the like.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://geospy.web.app/&quot;&gt;geospy.web.app&lt;/a&gt; — Uses AI to guess the location where a photo was taken.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://whatsmyname.app/&quot;&gt;whatsmyname.app&lt;/a&gt; — Finds social media accounts registered under the username you type.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://noadexchange.com/&quot;&gt;noadexchange.com&lt;/a&gt; — A Warmshowers-style site. You host guests Airbnb-style and earn credits, then use those credits to stay in other cities and countries. There’s a one-time $75 cleaning fee, and that goes to the host.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://htmldocs.com/&quot;&gt;htmldocs.com&lt;/a&gt; — Lets you generate PDFs with HTML. There’s an API service too; you can assign variables to certain parts of the PDF and generate dynamic PDFs.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.archivebuttons.com/&quot;&gt;archivebuttons.com&lt;/a&gt; — Gathers the paywall-bypassing services under one roof.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nearbywiki.org/&quot;&gt;nearbywiki.org&lt;/a&gt; — Shows the locations of Wikipedia pages on a map. Useful for finding places worth seeing wherever you go.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://punchsalad.com/ssl-certificate-generator/&quot;&gt;punchsalad.com SSL generator&lt;/a&gt; — A Let’s Encrypt certificate generator. Works for free.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.libble.eu/&quot;&gt;libble.eu&lt;/a&gt; — An archive of user manuals.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pfpmaker.com/&quot;&gt;pfpmaker.com&lt;/a&gt; — A profile picture generator.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.reddit-soccerstreams.com/&quot;&gt;reddit-soccerstreams.com&lt;/a&gt; — Lists links to football match streams.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://maps.nimbo.earth/&quot;&gt;maps.nimbo.earth&lt;/a&gt; — A map service updated monthly. Gives you 60,000 free credits.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.imagetotext.io/photo-translate&quot;&gt;imagetotext.io photo-translate&lt;/a&gt; — Translates text from photos.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.flightlist.io/&quot;&gt;flightlist.io&lt;/a&gt; — A flight search engine.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://v0.dev/&quot;&gt;v0.dev&lt;/a&gt; — Vercel’s AI interface-design app.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linkpreview.xyz/&quot;&gt;linkpreview.xyz&lt;/a&gt; — A link-preview viewer for developers. Lets you check how a link will look on WhatsApp, Twitter, etc.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blocks.md/&quot;&gt;blocks.md&lt;/a&gt; — A Typeform-alternative form builder. Turns Markdown into forms.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>bookmarks</category><category>internet</category></item><item><title>Useful macOS Apps</title><link>https://notlar.im/en/blog/useful-macos-apps-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/useful-macos-apps-en/</guid><description>macOS apps I use and find useful, plus sites for cracked versions.</description><pubDate>Mon, 13 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;macOS apps I use and find useful.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://reederapp.com/&quot;&gt;Reeder&lt;/a&gt; — an RSS reader, also available on iOS devices.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tableplus.com/&quot;&gt;TablePlus&lt;/a&gt; — a database management app that supports a whole bunch of databases. The free version allows 2 open tabs, which is usually enough.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://upscayl.org/&quot;&gt;Upscayl&lt;/a&gt; — an open-source (AI-based) image upscaler.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Sites for cracked versions&lt;a href=&quot;#sites-for-cracked-versions&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://xmac.app/&quot;&gt;xmac.app&lt;/a&gt; — this one is really good; direct one-click downloads, no ads.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cmacked.com/&quot;&gt;cmacked.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.torrentmac.net/&quot;&gt;torrentmac.net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nmac.to/&quot;&gt;nmac.to&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://appstorrent.ru&quot;&gt;appstorrent.ru&lt;/a&gt; — this one is also quite good; the comments sometimes have useful notes.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://macked.app/&quot;&gt;macked.app&lt;/a&gt; — just found this one; it’s in Chinese.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>macos</category><category>software</category></item><item><title>Kimsufi: A Cheap Dedicated Server Rental Service</title><link>https://notlar.im/en/blog/kimsufi-review-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/kimsufi-review-en/</guid><description>My experience with Kimsufi, the budget dedicated hosting company running on older OVH servers that I&apos;ve been using since 2014.</description><pubDate>Fri, 26 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A hosting company that offers service on older servers within OVH.&lt;/p&gt;
&lt;p&gt;I’ve been using the KS-1 and KS-2 plans since roughly 2014. Pricing is 5 and 10 euros. I set up &lt;a href=&quot;https://caprover.com/&quot;&gt;Caprover&lt;/a&gt; to run a seedbox and handle my odd bits and pieces. They give you a 100 Mbit connection with no bandwidth cap. And you don’t share it with the rest of the rack — it’s all yours. They don’t hassle you about what you do on the server with “fair use” clauses and the like.&lt;/p&gt;
&lt;p&gt;That said, customer support is slow. In these 10 years I’ve only needed them once or twice, for billing.&lt;/p&gt;
&lt;p&gt;You can track which servers are in stock at &lt;a href=&quot;https://checkservers.ovh/&quot;&gt;checkservers.ovh&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>self-hosting</category></item><item><title>Useful GitHub Repos</title><link>https://notlar.im/en/blog/useful-github-repos-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/useful-github-repos-en/</guid><description>GitHub repos I&apos;ve spotted here and there, starred, and found useful for my own work.</description><pubDate>Sun, 21 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;More precisely, GitHub repos I’ve spotted here and there that could be useful for my own work. I drop the ones I’ve starred in here and write a short description.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/YS-L/csvlens&quot;&gt;YS-L/csvlens&lt;/a&gt; — a command-line CSV viewer.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/wagoodman/dive&quot;&gt;wagoodman/dive&lt;/a&gt; — lets you inspect Docker images layer by layer.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pocketbase/pocketbase&quot;&gt;pocketbase/pocketbase&lt;/a&gt; (&lt;a href=&quot;https://pocketbase.io/&quot;&gt;site&lt;/a&gt;) — a legendary package written in Go. With a single click it gives you a ready-made backend with an admin panel: database, file storage, user authentication and so on. You can hook up whatever you like through its JSON API.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bcanata/awesome-stars/&quot;&gt;bcanata/awesome-stars&lt;/a&gt; — turns out there’s such a thing as an “awesome-stars” repo; it generates and publishes a list of the repos I’ve starred.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>software</category><category>github</category></item><item><title>Amatör Telsiz Röle: An Android App</title><link>https://notlar.im/en/blog/amateur-radio-repeater-app-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/amateur-radio-repeater-app-en/</guid><description>Development notes on the Android app I built with React Native + Expo as an alternative to amatortelsizcilik.com.tr and @telsizbot.</description><pubDate>Wed, 03 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;An Android app available &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.tr.amatortelsizcilik&quot;&gt;on the Google Play Store&lt;/a&gt; — the name means “amateur radio repeater” in Turkish. Built with React Native on Expo. It uses the same database as amatortelsizcilik.com.tr and the &lt;a href=&quot;https://t.me/telsizbot&quot;&gt;@telsizbot&lt;/a&gt; bot on Telegram. For now it lists VHF, UHF and crossband repeaters.&lt;/p&gt;
&lt;p&gt;Initially it displayed things as a simple table. The 29 March 2024 update added a dark mode and viewing repeaters on a map.&lt;/p&gt;
&lt;h2&gt;Suggestions received and to-dos&lt;a href=&quot;#suggestions-received-and-to-dos&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; Add filtering and search to the repeater list.&lt;/li&gt;
&lt;li&gt; Swipe gestures instead of next/previous page buttons.&lt;/li&gt;
&lt;li&gt; Dark mode will follow the phone’s setting automatically.&lt;/li&gt;
&lt;li&gt; Add a repeater detail page. Tapping a repeater will show the rest of its details and its location.&lt;/li&gt;
&lt;li&gt; Report-an-error + submit-a-new-repeater buttons on the repeater detail pages.&lt;/li&gt;
&lt;li&gt; Callsign lookup via QRZ could be added.&lt;/li&gt;
&lt;li&gt; Move the database into SQLite so it works offline.&lt;/li&gt;
&lt;li&gt; An iOS version could be made. Requires buying a developer account.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Issues&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; Location apparently isn’t updating — I think it saves a fixed one to the list.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3 April 2024 update&lt;a href=&quot;#3-april-2024-update&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I removed the SQLite database — it was causing problems. For now the app fetches the data from the Laravel-powered amatortelsizcilik.com.tr API and caches it for 24 hours. There were also some minor design updates.&lt;/p&gt;</content:encoded><category>amateur-radio</category><category>software</category></item><item><title>Amateur Radio: A Hobby, Not an Earthquake Plan</title><link>https://notlar.im/en/blog/amateur-radio-intro-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/amateur-radio-intro-en/</guid><description>A caution about the post-earthquake rush into the hobby, the difference between PMR and amateur radios, and how to actually get started — a long introductory post.</description><pubDate>Fri, 29 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After earthquakes and other natural disasters, people flock to amateur radio as a sort of plan B. To be honest, when I first got the itch, that was my intention too. Once you actually get into it, you realize it’s a hobby — and an expensive one at that.&lt;/p&gt;
&lt;p&gt;TA1ANW here, coming to you, folks.&lt;/p&gt;
&lt;h2&gt;Turkey’s earthquake-radio myth&lt;a href=&quot;#turkeys-earthquake-radio-myth&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Because TRAC (Turkey’s amateur radio society) and ham operators were so active during the 1999 earthquake in particular, amateur radio in Turkey has become deeply intertwined with the idea of search and rescue. Considering that GSM communication was still pretty much in its infancy in 1999, amateur radio came to the rescue after the infrastructure collapsed. As a continuation of that era, most search-and-rescue teams still steer their members toward getting an amateur radio license.&lt;/p&gt;
&lt;p&gt;But the hobby doesn’t really have much to do with earthquakes or disasters anymore. Sure, amateur radio can be somewhat useful as a backup system if modern communications hiccup, but in Turkey it is definitely not some earthquake communication method.&lt;/p&gt;
&lt;p&gt;Amateur radio is people trying to communicate without a specific “provider”, mostly using equipment they built themselves or can keep running on their own. It’s a hobby where you try to reach the farthest distance and the most people that way. When getting into it, your main goal should be “I’m going to make contacts with lots of people, in lots of locations.” So if your goal is “I’m buying this for earthquakes”, you’ll be disappointed — don’t.&lt;/p&gt;
&lt;h2&gt;”Let me buy a radio for earthquakes” — do I need a license?&lt;a href=&quot;#let-me-buy-a-radio-for-earthquakes--do-i-need-a-license&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We can split radios into two groups: PMR and amateur radios.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PMR radios&lt;/strong&gt;, by design, have a fixed antenna that can’t be removed, and they don’t require an amateur radio license.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amateur radios&lt;/strong&gt; are usually the ones where you can enter a “frequency” — they require an amateur radio license.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you’re only thinking of it as a fallback “in case the phones go down”, a PMR radio suits you better. (When buying one, there’s also an option called DMR — that’s not it, watch out.)&lt;/p&gt;
&lt;p&gt;It gives you relatively short-range communication. It outputs 0.5 watts. The device has 16 separate channels, meaning technically 16 separate conversations can happen in the area around you. Say you bought one for your kid and one for your spouse: set them to the same channel and you can talk on that channel within the same area.&lt;/p&gt;
&lt;p&gt;But don’t forget this: if someone else talks on that channel at that moment, if everyone uses it at once, you won’t be able to get through. If there are 10–15 other families who bought the same radio and use the same channel, technically there will be chaos at that moment. That’s why neither a PMR radio nor an amateur radio is a mobile-phone alternative — just a distant fallback that covers one limited need.&lt;/p&gt;
&lt;p&gt;You can think of the usable range as roughly your own neighborhood, but there’s no fixed “X kilometers” definition. You can also think of it like sound or light — the distance they reach drops when they hit obstacles. Sunlight, say, will reflect off whatever it hits; radio signals have similar technical characteristics.&lt;/p&gt;
&lt;p&gt;The only sensible disaster-related use is this: if you’re saying “I’m going to join search-and-rescue operations”, then buy one. These people mostly use their organizations’ frequencies too, and organize their SAR work there. For example, during the forest fires in the summer of 2021, the search-and-rescue teams in the region were very helpful.&lt;/p&gt;
&lt;p&gt;And unless you have an official duty, you can’t keep those organizations’ frequencies in your radio, you can’t listen to official agencies’ frequencies, and you can’t contact official agencies over the radio. Plenty of people in Turkey try to pull off things they shouldn’t with a “nothing will happen anyway” mentality — and even if law enforcement doesn’t track it down, we as the amateur radio community do, and we report it to the relevant units.&lt;/p&gt;
&lt;p&gt;In short:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If you don’t have an amateur radio license and just want a backup → buy a PMR radio.&lt;/li&gt;
&lt;li&gt;If you don’t have an amateur radio license but want to get one → get your license first, then buy an amateur device.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It is not a device to buy thinking “if there’s an earthquake I’ll reach the police or the army from under the rubble” — it doesn’t serve that function and it can’t.&lt;/p&gt;
&lt;h2&gt;I want to become a ham&lt;a href=&quot;#i-want-to-become-a-ham&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let me start with the word “amateur”. Beginners usually read “amateur” as something like “novice”. The amateur/professional distinction is about whether you do the thing as a profession, whether you earn money from it.&lt;/p&gt;
&lt;p&gt;An amateur footballer is someone whose profession isn’t football and who doesn’t earn money from it; a professional footballer is someone who earns money from it. Playing in the third division or being bad doesn’t change that. And “professional” doesn’t mean doing the job very well either — it means doing it for money or as a profession.&lt;/p&gt;
&lt;p&gt;That’s the difference between an amateur/professional fisherman, an amateur/professional driver, an amateur/professional photographer, and so on.&lt;/p&gt;
&lt;p&gt;As for the second part: in Turkish we distinguish between “telsiz” (a two-way radio) and “radyo” (a broadcast receiver), but the device is actually a radio either way. The term “radio operator” is used a lot in the community, because what we actually do is send and receive radio signals. In Turkish, the device that can transmit got named “telsiz” (literally “wireless”), while the one that can only listen got named “radyo”.&lt;/p&gt;
&lt;p&gt;Why do we do this? Because it’s a hobby. We learn electronics and radio frequency. We meet lots of different people from lots of different places. It’s a broad hobby in scope, too — I, for instance, have mostly done listening; I get more enjoyment out of RF and the projects built on top of it. I know the devices I use.&lt;/p&gt;
&lt;p&gt;We’ve all watched television; the terrestrial antennas we use, satellite receivers, FM radios, phones, garage remotes, tire pressure sensors — every one of them is a radio receiver/transmitter. While digging into those is what excites me, someone else finds decoding and listening to a digital radio transmission more exciting.&lt;/p&gt;
&lt;p&gt;There are specific frequencies allocated to us; we listen and transmit within those ranges and try to make contacts. In Turkey these ranges are set by the &lt;strong&gt;Information and Communication Technologies Authority (BTK, the Turkish telecoms regulator)&lt;/strong&gt; and announced as the “National Frequency Plan”. The body responsible for amateur radio affairs is the &lt;strong&gt;Directorate General of Coastal Safety&lt;/strong&gt;. The Amateur Radio Operations Service, established within it, handles all the paperwork and procedures that concern us.&lt;/p&gt;
&lt;h2&gt;The license process in a nutshell&lt;a href=&quot;#the-license-process-in-a-nutshell&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I’ll go through the details of these procedures later, but in short:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You apply for the amateur radio certificate via e-Devlet (Turkey’s e-government portal).&lt;/li&gt;
&lt;li&gt;You pay the exam fee.&lt;/li&gt;
&lt;li&gt;You sit the exam on a date set by the Ministry of National Education, at e-exam centers (not online).&lt;/li&gt;
&lt;li&gt;If you pass the exam, you pay the certificate fee and pick yourself a callsign.&lt;/li&gt;
&lt;li&gt;Once your certificate is issued and you own a callsign like &lt;code&gt;TA1ANW&lt;/code&gt;, you can start operating.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As I said, first I wanted to answer those asking “what is amateur radio, why do we do it, what do we do?”; later we’ll look at the fees and procedures in detail. Let this stand here as a primer for people who apply without knowing what they’re getting into.&lt;/p&gt;
&lt;h2&gt;Amateur radio repeater map&lt;a href=&quot;#amateur-radio-repeater-map&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An old &lt;a href=&quot;https://www.google.com/maps/d/u/0/edit?mid=1UHlUTLve_UIglBSCRWq9d2orKAjO4Xzt&amp;amp;usp=sharing&quot;&gt;Google My Maps repeater map&lt;/a&gt; — shared as locations; I drew on it when adding location data to &lt;a href=&quot;https://amatortelsizcilik.com.tr&quot;&gt;amatortelsizcilik.com.tr&lt;/a&gt; and &lt;a href=&quot;https://t.me/telsizbot&quot;&gt;@telsizbot&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also developed an Android app as an alternative to amatortelsizcilik.com.tr and @telsizbot — &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.tr.amatortelsizcilik&quot;&gt;amatör telsiz röle&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>amateur-radio</category></item><item><title>Useful 3D Printing Projects</title><link>https://notlar.im/en/blog/useful-3d-prints-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/useful-3d-prints-en/</guid><description>Small but life-saving things I&apos;ve printed for myself, plus the places to download 3D models.</description><pubDate>Mon, 25 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Designs I’ve printed for myself and found useful.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Side grip parts for the Logitech MX Anywhere 2S.&lt;/strong&gt; The &lt;a href=&quot;https://www.thingiverse.com/thing:6119699&quot;&gt;soft side pieces&lt;/a&gt; of the mouse I use. The originals deteriorated in the sun and came off; I printed replacements in TPU.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A quick-to-print whistle that sounds good&lt;/strong&gt; — &lt;a href=&quot;https://www.thingiverse.com/thing:3130078&quot;&gt;Thingiverse #3130078&lt;/a&gt;. I’ve printed it in both ABS and PLA.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Magnetic SD / micro-SD card case&lt;/strong&gt; — &lt;a href=&quot;https://www.printables.com/model/464786-slim-magnetic-sd-micro-sd-card-case&quot;&gt;Printables #464786&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Holder for two batteries + two SD cards for the Canon M50&lt;/strong&gt; — &lt;a href=&quot;https://www.thingiverse.com/thing:3566796&quot;&gt;Thingiverse #3566796&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Two-battery holder for the Canon M50&lt;/strong&gt; — &lt;a href=&quot;https://www.thingiverse.com/thing:5403046&quot;&gt;Thingiverse #5403046&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hot shoe cover for the Canon M50&lt;/strong&gt; — &lt;a href=&quot;https://www.printables.com/model/226558-hot-shoe-cover-minimalistic-internal-flash-working&quot;&gt;Printables #226558&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trophy set&lt;/strong&gt; — a two-part &lt;a href=&quot;https://www.thingiverse.com/thing:5248363&quot;&gt;trophy set&lt;/a&gt; made of a base and a top piece. I print these for my students.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Websites where you can find 3D printing projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.myminifactory.com/&quot;&gt;myminifactory.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.thingiverse.com/&quot;&gt;thingiverse.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cults3d.com/en&quot;&gt;cults3d.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://free3d.com/tr/&quot;&gt;free3d.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.stlfinder.com/&quot;&gt;stlfinder.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.yeggi.com/&quot;&gt;yeggi.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.prusaprinters.org/&quot;&gt;prusaprinters.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>3d-printing</category></item><item><title>Greenote GSC50 Cordless Vacuum Review</title><link>https://notlar.im/en/blog/greenote-gsc50-review-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/greenote-gsc50-review-en/</guid><description>The Greenote GSC50 cordless vacuum I bought from Amazon Turkey — price, shipping and what&apos;s in the box.</description><pubDate>Mon, 05 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A cordless vacuum model from Greenote. I bought it from Amazon &lt;a href=&quot;https://amazon.com.tr/dp/B08T5WSLZL&quot;&gt;via this link&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With shipping it came to 3,938.62 TL in total. It was delivered within 10 days. I’ll also write a detailed review with pictures.&lt;/p&gt;
&lt;h2&gt;What’s in the box&lt;a href=&quot;#whats-in-the-box&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Battery unit and body&lt;/li&gt;
&lt;li&gt;Motor and dust bin&lt;/li&gt;
&lt;li&gt;Aluminium tube&lt;/li&gt;
&lt;li&gt;Carpet brush head&lt;/li&gt;
&lt;li&gt;Long nozzle&lt;/li&gt;
&lt;li&gt;Dusting brush&lt;/li&gt;
&lt;li&gt;Cleaning brush&lt;/li&gt;
&lt;li&gt;Charger&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>hardware</category></item><item><title>Blog Posts Worth Reading</title><link>https://notlar.im/en/blog/recommended-blog-posts-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/recommended-blog-posts-en/</guid><description>Blog posts I&apos;ve come across here and there that are a joy to read and worth recommending to others.</description><pubDate>Tue, 09 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Blog posts I’ve come across here and there — ones worth reading, ones I’ve read and liked, ones I want to read.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sive.rs/com&quot;&gt;sive.rs/com&lt;/a&gt; — explains how to download TLD zone files through ICANN’s CZDS system and filter out the unregistered domains.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://halityesil.com/php/phpde-kod-nasil-yazilmaz-baslica-hatalar-ve-ipuclari/&quot;&gt;halityesil.com — How not to write PHP code&lt;/a&gt; — a nice article (in Turkish) about common mistakes in PHP.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki-power.com/en/%E6%90%AD%E5%BB%BA%E5%B1%9E%E4%BA%8E%E8%87%AA%E5%B7%B1%E7%9A%84HomeLab/&quot;&gt;wiki-power.com — Building a HomeLab&lt;/a&gt; — a wiki that collects everything in one place, similar to notlar.im. This page and the ones that follow cover self-hosting.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.haschek.at/2019/the-curious-case-of-the-RasPi-in-our-network.html&quot;&gt;blog.haschek.at — The curious case of the RasPi&lt;/a&gt; — he found a Raspberry Pi in the server room and, by following the clues, tracked down the person who planted it. An interesting story.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>bookmarks</category></item><item><title>Lonely Planet Travel Guides</title><link>https://notlar.im/en/blog/lonely-planet-guides-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/lonely-planet-guides-en/</guid><description>A short note on the Lonely Planet series, which publishes travel guides for many countries.</description><pubDate>Thu, 28 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A series of travel guides covering many countries — perhaps among the most successful in the field. I learned quite a lot even from their Turkey guide. They’ve written excellent write-ups for archaeological sites here that have no guide or signage of their own.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.com.tr/Lonely-Planet-Turkey-Travel-Guide-dp-178657800X/dp/178657800X/ref=dp_ob_title_bk&quot;&gt;Lonely Planet Turkey — Amazon Türkiye&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unfortunately, because of the exchange rate the price here in Turkey has gone through the roof; you can get the e-book versions from Z-Library.&lt;/p&gt;</content:encoded><category>books</category><category>travel</category></item><item><title>Logitech MX Anywhere 2S Review</title><link>https://notlar.im/en/blog/logitech-mx-anywhere-2s-review-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/logitech-mx-anywhere-2s-review-en/</guid><description>A look at Logitech&apos;s MX Anywhere 2S wireless mouse after two years of daily use.</description><pubDate>Tue, 26 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Logitech’s mouse that works both over Bluetooth and with its own Unifying USB receiver. Between Bluetooth and USB it can pair with a total of 3 devices. There’s a tiny button on the bottom with 1-2-3 indicator lights — that’s how you switch between them.&lt;/p&gt;
&lt;p&gt;It’s been about 2 years now, and I use it daily. Its only problem: the side pieces — right where you grip it in your hand — swelled up and peeled off. I solved that by &lt;a href=&quot;https://www.thingiverse.com/thing:6119699&quot;&gt;printing replacements in TPU on a 3D printer&lt;/a&gt;. Details are in the &lt;a href=&quot;/en/blog/useful-3d-prints-en&quot;&gt;useful 3D print projects&lt;/a&gt; post.&lt;/p&gt;</content:encoded><category>hardware</category></item><item><title>Quansheng UV-K5</title><link>https://notlar.im/en/blog/quansheng-uv-k5-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/quansheng-uv-k5-en/</guid><description>Notes and resources on Quansheng&apos;s UV-K5 handheld radio.</description><pubDate>Tue, 05 Sep 2023 22:09:36 GMT</pubDate><content:encoded>&lt;p&gt;I came across this radio on YouTube around February–March 2023. At that time it was on sale on Amazon US. Later that channel ran out of stock. On 29 May I ordered one &lt;a href=&quot;https://www.aliexpress.com/item/1005005442225028.html&quot;&gt;via Aliexpress&lt;/a&gt;. With the upfront tax included it came to 854 TL. It was delivered on 5 June.&lt;/p&gt;
&lt;p&gt;The radio’s most important advantage is that its firmware password has been cracked and can be regenerated. That means many people doing open-source work on its firmware can develop software that adds new features to the radio.&lt;/p&gt;</content:encoded><category>amateur-radio</category></item><item><title>Cables Used in Amateur Radio</title><link>https://notlar.im/en/blog/amateur-radio-cables-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/amateur-radio-cables-en/</guid><description>A short note on the cable types used in amateur radio stations.</description><pubDate>Sun, 05 Sep 2021 15:21:38 GMT</pubDate><content:encoded>&lt;p&gt;The reference image for this post is no longer available.&lt;/p&gt;</content:encoded></item><item><title>mmm.page</title><link>https://notlar.im/en/blog/mmm-page-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/mmm-page-en/</guid><description>mmm.page — fast, easy, drag-and-drop personal website builder</description><pubDate>Thu, 13 May 2021 21:13:22 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://build.mmm.page&quot;&gt;mmm.page&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://static.mmm.page/image/preview_800x419.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://build.mmm.page&quot;&gt;mmm.page&lt;/a&gt; is a simple tool for designing and publishing a personal website. You can quickly build a personal site by drag-and-dropping every element onto the page and positioning it.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&quot;https://mmm.page/bc.main&quot;&gt;https://mmm.page/bc.main&lt;/a&gt; for the personal page I built for myself as an example.&lt;/p&gt;</content:encoded><category>bookmarks</category></item><item><title>Self-Hosting</title><link>https://notlar.im/en/blog/self-hosting-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/self-hosting-en/</guid><description>What is self-hosting? How to use Caprover to make Docker easier? Install, configure, what to run.</description><pubDate>Thu, 13 May 2021 20:57:53 GMT</pubDate><content:encoded>&lt;h3&gt;What is self-hosting?&lt;a href=&quot;#what-is-self-hosting&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Running, hosting, and serving the various services we use on the internet on your own machine — that’s what we call &lt;em&gt;self-hosting&lt;/em&gt;. Instead of using &lt;em&gt;Google Keep&lt;/em&gt; as a note-taking app, &lt;em&gt;Google Photos&lt;/em&gt; to host photos, &lt;em&gt;LastPass&lt;/em&gt; as a password manager, etc., you host the &lt;em&gt;usually open-source&lt;/em&gt; equivalent applications on a server you own or rent.&lt;/p&gt;
&lt;h3&gt;Why?&lt;a href=&quot;#why&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I started doing this about 12–13 years ago. Back then I had a web server on &lt;em&gt;cPanel&lt;/em&gt;. I started installing small apps there. For example I installed and started using &lt;em&gt;Piwik&lt;/em&gt; (today called &lt;em&gt;Matomo&lt;/em&gt;) to do what &lt;em&gt;Google Analytics&lt;/em&gt; does. The cPanel server could only host PHP apps, and since it was shared, resource usage was limited.&lt;/p&gt;
&lt;p&gt;So especially for torrent stuff, I started using &lt;em&gt;&lt;a href=&quot;https://put.io/&quot;&gt;Put.io&lt;/a&gt;&lt;/em&gt;, which was popular at the time and gave free service for a long while. When that service ended its promotional period and raised prices, I looked for an alternative. My first goal was a server that could do the torrent download/upload work that’s not possible on PHP. For that I used cheaper VPS (Virtual Private Server) options. These also fundamentally give you a slice on virtualisation software like &lt;em&gt;VirtualBox&lt;/em&gt; or &lt;em&gt;VMware Workstation&lt;/em&gt;, so resources are still limited and shared.&lt;/p&gt;
&lt;p&gt;After using VPSs like this for a long time, I noticed the torrent clients I connected to were generally hosted on &lt;em&gt;OVH&lt;/em&gt;. While researching I came across an OVH-affiliated company called &lt;em&gt;&lt;a href=&quot;https://www.kimsufi.com/en/&quot;&gt;Kimsufi&lt;/a&gt;&lt;/em&gt;. Kimsufi generally serves older servers with limited customer support. So they offer — still, as far as I know — the cheapest &lt;em&gt;dedicated&lt;/em&gt; servers (an entire physical server is yours). At the time of writing this I’m still using Kimsufi’s KS-3 plan at $9.99/month (or €7.99).&lt;/p&gt;
&lt;h3&gt;How to use it&lt;a href=&quot;#how-to-use-it&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When I first set up my server, I installed every app on a &lt;em&gt;Linux&lt;/em&gt; distribution myself. The downside: app updates and maintenance became a big problem. Two apps might depend on different versions of &lt;em&gt;Python&lt;/em&gt; and conflict with each other. When one app has an issue, all your services are affected. Restarting a service tied to one app affects another. You end up needing to reboot the system more.&lt;/p&gt;
&lt;p&gt;Then I came across software that lets you bulk-install these services. With them, you install a Linux distribution like &lt;em&gt;Ubuntu&lt;/em&gt;, and post-install you can deploy every app you need without configuration hassle. Let me mention them first.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A footnote: to learn about and follow self-hosting developments, follow the &lt;a href=&quot;https://github.com/topics/selfhosted&quot;&gt;[selfhosted]-tagged packages&lt;/a&gt; on GitHub and the &lt;a href=&quot;https://www.reddit.com/r/selfhosted/&quot;&gt;r/selfhosted&lt;/a&gt; subreddit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;For a long time I used &lt;em&gt;&lt;a href=&quot;https://github.com/QuickBox/QB&quot;&gt;QuickBox&lt;/a&gt;&lt;/em&gt;. This app aims to build a &lt;em&gt;seedbox&lt;/em&gt; — a torrent send/receive server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://cache.amefs.net/wp-content/uploads/2018/12/05114417/Quickbox_Pro.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;QuickBox panel&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;After install it gives you a URL where you can see server details. From there you can install various apps you need. If this is your first time setting up something like this, the simple install and minimal touch make it a good fit.&lt;/p&gt;
&lt;p&gt;But after using QuickBox for 4–5 years, I started running into problems when I needed apps that QuickBox didn’t include. It supports the apps listed &lt;a href=&quot;https://github.com/QuickBox/QB&quot;&gt;here&lt;/a&gt; and you can install them easily; outside that, installing and running something else is hard — it wasn’t built for that. As I mentioned at the start, installing your own password manager, file manager, photo manager gets hard.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;After my server configuration broke during one of these issues, while looking for an alternative I used &lt;a href=&quot;https://github.com/Cloudbox/Cloudbox&quot;&gt;&lt;em&gt;Cloudbox&lt;/em&gt;&lt;/a&gt;. It uses &lt;em&gt;Ansible&lt;/em&gt; to automate app installation, and builds your server automatically on &lt;em&gt;Docker&lt;/em&gt; containers. The downside was that its ready-made packages were mostly oriented at seedbox-building. Docker was a convenience, but the absence of a UI for managing Docker containers and the server meant doing everything from the shell — a real disadvantage.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are several services in this space; check the &lt;a href=&quot;https://github.com/awesome-selfhosted/awesome-selfhosted#self-hosting-solutions&quot;&gt;&lt;em&gt;Self-hosting Solutions&lt;/em&gt;&lt;/a&gt; section of the &lt;a href=&quot;https://github.com/awesome-selfhosted/awesome-selfhosted&quot;&gt;&lt;em&gt;awesome-selfhosted&lt;/em&gt;&lt;/a&gt; repo on GitHub. I also briefly tried &lt;a href=&quot;https://yunohost.org/#/&quot;&gt;YunoHost&lt;/a&gt; from this list — it works well when you stick to apps in its own store, but as soon as you want to run your own Docker-hosted apps it can be finicky.&lt;/p&gt;
&lt;h3&gt;What I’m using now&lt;a href=&quot;#what-im-using-now&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://caprover.com/img/screenshot.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;CapRover (formerly CaptainDuckDuck)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The umbrella app I landed on is &lt;a href=&quot;https://caprover.com/&quot;&gt;&lt;em&gt;Caprover&lt;/em&gt;&lt;/a&gt;. Previously named &lt;em&gt;CaptainDuckDuck&lt;/em&gt;, it later got renamed Caprover. It positions itself as a self-hostable alternative to &lt;a href=&quot;https://www.heroku.com/&quot;&gt;&lt;em&gt;Heroku&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A small detour on Docker (I’ll write a separate post about it later). What solved the application-version-conflict problem I hit on QuickBox was Docker. Fundamentally, it runs the app you want inside pre-built tiny virtual computers. By keeping only the “data” persistent, you can move, update, and run the app in multiple places. The application’s core files can’t be damaged or corrupted. Backups become much easier.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There’s a Caprover demo to play with &lt;a href=&quot;https://captain.server.demo.caprover.com/&quot;&gt;here&lt;/a&gt; (password: &lt;strong&gt;captain42&lt;/strong&gt;). You can create your own Docker container or pick apps from its constantly-updated own app store. When installing apps from the store there’s almost zero friction; when installing another Docker image, the UI is still very easy. You can also create your own app store on GitHub and use that, and you can &lt;a href=&quot;https://github.com/caprover/one-click-apps/&quot;&gt;contribute&lt;/a&gt; to Caprover’s official store. The store apps are defined via Docker-Compose-style &lt;em&gt;YAML&lt;/em&gt; files.&lt;/p&gt;
&lt;p&gt;Without a tool like Caprover, hosting Docker containers yourself means you have to handle port forwarding yourself. Say you have two web services. Both need ports 80 and 443. You can only bind those ports to one container at a time outside Docker. Caprover’s &lt;em&gt;letsencrypt&lt;/em&gt; and &lt;em&gt;nginx&lt;/em&gt; containers handle this automatically for you, auto-generate &lt;em&gt;xyz.yourdomain.com&lt;/em&gt; style subdomains, and one-click let you serve them over &lt;em&gt;https&lt;/em&gt; using your own &lt;em&gt;Let’s Encrypt&lt;/em&gt; certificate.&lt;/p&gt;
&lt;p&gt;It also lets you, with a bit more skill, build a &lt;em&gt;docker cluster&lt;/em&gt; and host your services across multiple servers when one isn’t enough. Especially via Docker Hub, I can find an incredible range of apps and run them in minutes. Backup is also easy through the same UI.&lt;/p&gt;
&lt;h3&gt;What can I run?&lt;a href=&quot;#what-can-i-run&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Below I’ll list Docker-based apps I’ve tried on Caprover. You can run most of them outside Docker too, but for the reasons above Docker was much more convenient. The &lt;a href=&quot;https://github.com/awesome-selfhosted/awesome-selfhosted&quot;&gt;awesome-selfhosted&lt;/a&gt; repo mentioned earlier has a much more comprehensive list — here I’ll mostly cover services I’ve actually tried myself.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://hub.docker.com/r/archivebox/archivebox&quot;&gt;archivebox&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/homelab.BfVBhkeC_1PeBsv.webp&quot; alt=&quot;&quot; width=&quot;3195&quot; height=&quot;1839&quot; /&gt;
&lt;em&gt;archivebox UI&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Not in Caprover’s app store; I installed from Docker Hub. Works like &lt;a href=&quot;http://web.archive.org/&quot;&gt;web.archive.org&lt;/a&gt; — lets you snapshot a site at a given date. Saves the page as HTML, PDF, plain text, etc. — protects against deletion. I also save important bookmarks here to protect them from going away.&lt;/p&gt;
&lt;p&gt;Set &lt;em&gt;ALLOW_ROOT = true&lt;/em&gt; as an &lt;em&gt;Environment&lt;/em&gt; value, and bind the container’s /data folder to a persistent folder.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/dani-garcia/bitwarden_rs&quot;&gt;&lt;strong&gt;bitwarden_rs&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/bitwarden-hero.CbNB6tsZ_8VVNz.webp&quot; alt=&quot;&quot; width=&quot;779&quot; height=&quot;465&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The open-source password manager &lt;a href=&quot;https://bitwarden.com/&quot;&gt;&lt;em&gt;Bitwarden&lt;/em&gt;&lt;/a&gt; ported to &lt;em&gt;Rust&lt;/em&gt; to require fewer resources. Stores your passwords securely without handing them to someone else. If you want others to use it too, you can leave signups open. When &lt;em&gt;LastPass&lt;/em&gt; started restricting its plans I deleted my account there and moved here. You can easily import backups from other password managers.&lt;/p&gt;
&lt;p&gt;After first install, even though it’s not in &lt;em&gt;Environment&lt;/em&gt; by default, setting &lt;em&gt;SIGNUPS_ALLOWED&lt;/em&gt; to &lt;em&gt;false&lt;/em&gt; blocks new signups. Also if you set &lt;em&gt;ADMIN_TOKEN&lt;/em&gt; to a 48-character base64 value (generate with &lt;code&gt;openssl rand -base64 48&lt;/code&gt;), you can log into the admin panel at &lt;em&gt;&lt;a href=&quot;https://bitwarden.youraddress/admin&quot;&gt;https://bitwarden.youraddress/admin&lt;/a&gt;&lt;/em&gt;. Bind /data to a persistent folder again.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/_/ghost&quot;&gt;Ghost&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Caprover has it as a one-click app, but the &lt;em&gt;bitnami&lt;/em&gt; image bundled there is on Ghost 3. I installed Docker’s own &lt;a href=&quot;https://hub.docker.com/_/ghost&quot;&gt;official image&lt;/a&gt; myself. The blog you’re reading runs on it.&lt;/p&gt;
&lt;p&gt;For install, just add a &lt;em&gt;url&lt;/em&gt; value in &lt;em&gt;Environment&lt;/em&gt;. They recommend using an external database; I added &lt;em&gt;database__client, database__connection__host&lt;/em&gt;, &lt;em&gt;database__connection__user&lt;/em&gt;, &lt;em&gt;database__connection__password&lt;/em&gt;, and &lt;em&gt;database__connection__database&lt;/em&gt; values.&lt;/p&gt;
&lt;p&gt;To keep changes from being wiped, also bind &lt;em&gt;/var/lib/ghost/content&lt;/em&gt; to a persistent folder.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/radhifadlillah/shiori&quot;&gt;shiori&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/shiori-cover.ojj3FhId_kEiFj.webp&quot; alt=&quot;&quot; width=&quot;1930&quot; height=&quot;945&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Shiori is a bookmark manager, written as an alternative to &lt;a href=&quot;https://getpocket.com/&quot;&gt;Pocket&lt;/a&gt;. Not in Caprover’s store; I installed from Docker Hub. I was looking for something to categorise my bookmarks and build an archive, but this didn’t quite meet my expectations.&lt;/p&gt;
&lt;p&gt;Set &lt;em&gt;Environment&lt;/em&gt; &lt;em&gt;SHIORI_DIR&lt;/em&gt; to &lt;em&gt;/data&lt;/em&gt; and bind &lt;em&gt;/data&lt;/em&gt; to a persistent folder.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/sabrsorensen/alpine-cloudplow&quot;&gt;cloudplow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cloudplow is another Docker image I installed myself that isn’t in Caprover’s built-in apps. It runs on the command line, no GUI. Periodically scans rtorrent’s completed-downloads folder and uses rclone (a file-transfer tool that talks to many cloud providers) to push files to the cloud. In my setup it one-way mirrors rtorrent’s completed folder to my Google Drive, so I can grab downloads from there.&lt;/p&gt;
&lt;p&gt;Both rclone and cloudplow ship inside this image. Configuration depends on your rtorrent install.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cdr/code-server&quot;&gt;Visual Studio Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A browser-based version of VS Code. Install from Caprover’s apps and use it directly.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/linuxserver/Heimdall&quot;&gt;heimdall&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/selfhosted-reddit.BJJ5wFR2_UgA5g.webp&quot; alt=&quot;&quot; width=&quot;1366&quot; height=&quot;703&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You’ve installed all these apps — how do you find them? That’s where &lt;em&gt;Heimdall&lt;/em&gt; comes in. You register the apps you host on Docker into it and use it as a homepage or panel. It also pulls upload/download rates from apps like rtorrent.&lt;/p&gt;
&lt;p&gt;Not in Caprover’s built-in apps, but you can pull the &lt;em&gt;linuxserver/heimdall&lt;/em&gt; image from Docker Hub. The only requirement is binding /config to a persistent folder so info isn’t lost on restart.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/amir20/dozzle&quot;&gt;dozzle&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/amir20/dozzle/master/docs/.vitepress/theme/media/poster-light.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;dozzle UI&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Dozzle lets you view logs from running Docker containers. Caprover’s UI can do this too, but Dozzle is purpose-built for it and does it very well.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/filebrowser/filebrowser&quot;&gt;filebrowser&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/5447088/50716739-ebd26700-107a-11e9-9817-14230c53efd2.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A really good app for managing the folders you persistently bind to Docker containers. Like a cloud storage service: file compression, playing video files from the browser, file sharing. You can create multiple users with different permissions.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/analogic/poste.io/&quot;&gt;analogic/poste.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The mail server included in Caprover’s built-in apps. Useful both for letting your Caprover-hosted containers send mail and for running your own email server.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;mail.yourdomain.com&lt;/em&gt; subdomain is all you need; Caprover handles the rest. For me though it used too much CPU even when idle for reasons I couldn’t pin down, so I stopped using it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/alexta69/metube&quot;&gt;metube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/9530250/141615206-5a065cd4-e814-4ed3-bc09-0e98c43873ef.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Metube UI&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A Docker image that adds a GUI to the famous youtube-dl package. Lets you download YouTube videos in one click. The only requirement is binding the container’s /downloads folder to wherever you want to save the videos.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Beyond these images, some other Docker containers I actively use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pgweb&lt;/li&gt;
&lt;li&gt;plex&lt;/li&gt;
&lt;li&gt;portainer&lt;/li&gt;
&lt;li&gt;rapidleech&lt;/li&gt;
&lt;li&gt;rutorrent&lt;/li&gt;
&lt;li&gt;shaarli&lt;/li&gt;
&lt;li&gt;swirl&lt;/li&gt;
&lt;li&gt;ttrss&lt;/li&gt;
&lt;li&gt;wallabag&lt;/li&gt;
&lt;li&gt;pottava/docker-webui&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>internet</category></item><item><title>Ray.so</title><link>https://notlar.im/en/blog/ray-so-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/ray-so-en/</guid><description>Generates pretty screenshots of your code snippets.</description><pubDate>Fri, 07 May 2021 23:45:35 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://ray.so/&quot;&gt;Ray.so&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ray-so-v2-c6p4l6o9o-raycastapp.vercel.app/_next/static/media/cover-photo.331cb248.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Ray.so lets you generate visually nice image files from code snippets — for sharing on social media and similar. Paste the code, pick the language, tweak the settings, then save as PNG or SVG.&lt;/p&gt;</content:encoded><category>bookmarks</category></item><item><title>Bike Touring Tips</title><link>https://notlar.im/en/blog/bike-touring-tips-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/bike-touring-tips-en/</guid><description>A few small tips for people thinking about going on a bike tour.</description><pubDate>Fri, 30 Apr 2021 22:02:41 GMT</pubDate><content:encoded>&lt;p&gt;Came across a nice article and saved it. They had good suggestions for what’s called &lt;em&gt;bikepacking&lt;/em&gt; — touring with light luggage, medium-length trips. I’m not translating one-to-one; sometimes I add comments in parentheses. The source link is at the bottom for anyone who wants the original.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Oven bags protect against water better than trash bags or zipper bags inside your panniers, and they’re lighter. (I find zipper bags more practical though — especially the quality ones are watertight.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Wet wipes are very useful on tours. (You can clean the bike, your clothes, your shoes. If you can’t shower, you can wipe under your armpits, your sides.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spare spokes can be taped to the chainstay or seat tube. Remember to mark which wheel and which side they belong to.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Photocopy your passport, driver’s licence and ID, laminate them in PVC and put them on the seat tube or top tube. If your bike is stolen and the serial number is erased, this can help identify it. If your passport is lost, you’ll have less international bureaucracy. (You can also do this off-tour. There may be issues if the ID is found, but you can put a document inside the seat tube laminated in PVC saying the bike belongs to you, and report it to police in case of theft — helps with bike identification.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In an area where cyclists are common, a spare inner tube a few inches smaller than yours can be enough to limp to a real shop. (You can also tie a knot in the punctured section of your tube and use it. Worst case, stuff the tire with straw or whatever so the walls don’t fold and slowly proceed to the nearest bike shop.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://images-na.ssl-images-amazon.com/images/I/71GertcTbTL.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;A locking pliers like this saves you from carrying many different tools. Since it locks onto the nut, you can apply more force than with a regular wrench. (Even just the wrench+pliers function alone saves space.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Powder your spare inner tube before installing — it prevents pinch flats. (Sometimes the tube gets pinched between rim and tire and bursts; this is the easiest prevention.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cut the long ends of straps and melt the ends to save a small amount of weight. Not much, but if you have ten straps it adds up to about as much as a titanium kettle. (Small on tour, but consider you’ll be carrying it for kilometres. That’s why they cut toothbrush handles, trim straps, throw away every unnecessary item.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you’re outside at night and afraid of meeting wildlife, sing while setting up camp. (Didn’t ring true to me.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A 32 mm or smaller, foldable, high-TPI cyclocross tyre takes up about as much space as an apple. Less than carrying a big Marathon. You can swap back to your normal tyre at the next bike shop.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If your screws keep loosening from vibration, wrap a piece of string around the head and dip it in superglue before installing. (Works. Or you can heat the screw thoroughly with a lighter and install it that way.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://m.media-amazon.com/images/I/51249iN5GGL.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A few zip ties can substitute for a rear rack or handlebar bag mounting bracket for at least 1000 km. One of the most useful repair kits there is. (Zip ties really are one of the most useful things. Every cyclist should have a few in their saddle bag.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://www.guneyav.com.tr/jel-reso-yakiti-200gr-kamp-mutfagi-yerli-uretim-27900reso-18290-23-B.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Petroleum jelly mixed with cotton makes a great fire starter. (We don’t really see petroleum jelly here; what we call “réchaud fuel” (gel fuel) works well.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To start a fire, take a piece of bark and split one end into thin slivers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build your first aid kit around the problems you’re likely to actually encounter.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://bodywrappers.com/img/lg/701-071_5.jpg&quot;&gt;These&lt;/a&gt; kinds of pants exist. They said they’re very useful against insects and wind, and very light. Useful as a long-pants alternative especially in summer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A windbreaker also helps against bugs. Nylon makes it hard for them to bite through.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Merino wool won’t turn your body odour into bad smell. The fibres are antibacterial. You can just rinse it in water to get rid of salt and let it dry. I also wear wool cycling shorts and socks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pharmacies sell earplugs. A whole pack is about the size of a lipstick. Useful when camping near traffic.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Source your screws from any hardware shop. Pick stainless steel to avoid corrosion. Small hardware shops often have more selection than big box stores.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Place your sleeping bag on grass, sand, or pine needles for extra comfort. For extra winter insulation, put foam on top of branches. Picking the camp site well also helps insulation. (You can also use bubble wrap as a mat — easy to get at supermarkets, lightweight, easy to carry, throw it away when it gets bad and grab a new one.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fleece earns its weight. Doubles as a pillow.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To pop a blister: heat a needle tip with fire, prick the blister, dab neosporin, cover. Don’t peel the skin off unless you want infection.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A curved needle makes sewing a torn tyre sidewall much easier. Saves you from riding without a tyre after the tear.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If your Achilles tendon or knees hurt, do stretches frequently. Take a local yoga class to learn a few moves for your problem areas. Do them at every break. (Most parks here have outdoor fitness equipment.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t ride focused on your next meal or rest stop. Remind yourself to take a break and stretch from time to time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hide spare cables inside your handlebars. When you remove the bar-ends, they’ll be there when you need them.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://medias.apidura.com/2016/01/Full_Frame_Pack_Large_Straight_On_Bike.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Don’t use panniers. Frame bags have a better capacity-to-weight ratio and are easier to ride with. You also don’t have to balance load and don’t need to repair racks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can use a banknote to back a slashed tyre.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://patineto.smugmug.com/photos/47412788-M.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;An old used bar tape protects the chainstay better than a neoprene protector, with less weight.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PET bottles inside frame bags don’t fall on rough roads, are lighter than other bottles, and stay cold longer. Wrapped in a T-shirt they stay cold most of the day. To repair a punctured bottle, use tent repair tape.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pizza covers your tour food needs — lots of calories, protein, salt, vegetables. Available almost everywhere and cheap.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Peanut butter is calorie-dense and fits in your bottle cage.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tennis ball cans also fit in your bottle cage. You can carry protein bars, a windbreaker, a spare tyre, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stickers make your bike look less cool and reduce theft risk while also protecting the frame from scratches.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cover exposed velcro with old velcro so it doesn’t damage your stuff over time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t carry camp shoes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t carry a camp chair.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t carry a clothesline.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t carry a ground cloth.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t carry a magnesium fire starter.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t carry a mini tripod. Stack rocks instead.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t carry a bowl, cup, glass, pan, plate. A &lt;a href=&quot;https://www.rei.com/media/product/781530&quot;&gt;combined spoon-fork utensil&lt;/a&gt; and a kettle will get the job done.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t carry a stuff sack.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t carry any spare anything other than a tyre.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t carry the fear of not having something with you. Everything is available almost everywhere. If it isn’t, you probably don’t need it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Before the tour, and again in the middle of it, get a good mechanic to true your wheels — or learn to true them yourself. You don’t need to carry extra spokes; a well-trued wheel won’t give you trouble. If it does, it probably isn’t a problem a spoke alone can fix. (Spokes — there’s a good comment about this. Hit a pothole, a spoke breaks, the wheel’s true can suddenly go. If you have one on hand and can replace + true, you’re fine. But keep riding on a bent aluminium rim and it can fold somewhere — at which point there’s no repair.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Safety glasses are cheaper than sunglasses and protect against flying stones and dust.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;T-shirts are lighter than cycling jerseys.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Any numbness in any part of your body should be read as a warning that your saddle height, saddle angle, bar height, or stem length needs to change. Numbness can lead to serious problems.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A light-coloured, transparent dry-bag becomes a lantern when you put your bike light inside it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;http://road.cc/sites/default/files/cropped/preview_500/images/Bontrager%20Race%20Lite%20Aero%20Clip-On%20Aerobar/Bontrager%20Race%20Lite%20Aero%20Clip-On%20Aerobar%20-%20mounted%202.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Aerobars give you multiple hand positions versus a standard dropbar or flat bar. They’re an advantage on open windy stretches.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Front and rear wheels wear at different rates. But swapping them mid-tour isn’t useful, because front-wheel traction matters much more than rear-wheel traction. Instead, fit a more durable, harder rear tyre and a softer front, so both wear at the same rate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On long climbs, push yourself back on the saddle a few centimetres to work different leg muscles.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Throughout the day, stand up every 10 minutes to relieve circulation in your legs and back.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change your habits. If your happiness doesn’t depend on coffee, hot food, sleep, warmth, being dry, being alone, being with others, going fast, knowing where you are — you open yourself to adventure. “Type-two fun” is the knowledge that a bad experience is a good story and makes you stronger.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a bit of lemon juice to your bottles. Lemon juice is antibacterial, keeps the bottles clean, masks plastic-bottle smell or metallic taste. Also prevents scurvy. One lemon will do for four days of water.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stay alert. An injury extends your tour longer than any short cut shortens it. Train yourself to take short power-naps before the tour.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make the zips on your rain jacket, clothes, frame bag, and other items longer. That way you can open them with gloves on.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To save time, brush your teeth on the bike. Spray the toothpaste out as if someone said something interesting while your mouth was full. This stops animals from eating the toothpaste and getting sick. You also don’t need to rinse — your mouth returns to normal in a few minutes. You can also spit on car windshields, because cars are coffins. Just kidding — don’t do the last one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you learn to sew, small tears won’t grow with time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pet shops give away sturdy, measured cups for measuring food. Grab one and use it for measuring oats, ramen, coffee, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In hot weather, wool T-shirts are better than rain jackets. The most breathable rain jacket will heat you up and make you sweat within minutes. Wool stays dry.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Wear your wet clothes inside your sleeping bag at night. Body heat will evaporate the moisture. Not sure about down, but it works on synthetics.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Black clothes beat white in hot weather because sweat evaporates faster. Don’t believe me, Google it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Smile and wave at vehicles that disrespect you. Waving and smiling defuse conflicts before they start.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use nail polish for touch-up paint. Also protects steel frames from corrosion. You can always find a colour matching your frame, and it lasts.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Put reflectors on your vest and bags rather than the bike. That way you can remove reflective items and camp stealthily.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hobby/craft shops sell compartmented plastic boxes. Useful for carrying fire starters, small tape rolls, earphones, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A bit of local honey from the area you’re touring will acclimate your immune system to local pollens and reduce allergies. Honey is also nature’s energy gel.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Every time it rains, or every week in winter, remove your seatpost and apply a fresh layer of grease. Aluminium and steel can weld themselves together over time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Wear gloves even if you don’t need them. Your hands hit the ground first whenever you fall.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Eat before you’re hungry.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Drink before you’re thirsty.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can refill your travel toothpaste tube with regular toothpaste.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lithium batteries are lighter, last longer, and work better with electronics like GPS and cameras. Less waste too.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If there’s an item you really love, don’t take it on tour. T-shirts get holes, bags tear, bikes get scratched. Buy used online for cheap and treat everything as disposable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Screenshotting directions on your phone uses less battery and works in cell-service-dead areas.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Eat salty food to replace lost electrolytes and make sure you get enough protein each meal.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Learn about wildlife. Learn what to do if a brown bear charges, how to hang your food, how to take a photo of the snake that bit you (so the hospital knows which antivenom). It saves lives. The more you know about each animal’s behaviour, the less likely you’ll find yourself in bad situations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Saddle sores happen to everyone eventually. Keep your butt clean by frequent wash-and-dry. If you have saddle sores, cut a donut-shaped pad from leather to relieve the area. Apply neosporin and it’ll be gone in 1-2 days. Don’t neglect them or you’ll end up with infection by tour end.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use zip ties to keep saddle bags from sliding.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you’re stealth-camping and a car is approaching, freeze in place. Drivers focus on movement; staying still makes you invisible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If chased by dogs, keep moving at a steady but slow pace and shout NO firmly and suddenly. Most dog owners use that command. If they get close, pour water from your bottle on them. (You can also stop and put your bike between you and the dogs. Dogs will give up at the edge of their territory.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t fear people, but don’t tell strangers exactly where you’re going or where you’ll camp. Trust your instincts and other cyclists. People you meet can also lead you to amazing adventures.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When parked, lacing a piece of velcro between your wheel and frame prevents the bike from falling or sliding. Also makes it harder for someone to grab and run.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Source: &lt;a href=&quot;http://bikepacker.com/bikepacking-lifehacks/&quot;&gt;http://bikepacker.com/bikepacking-lifehacks/&lt;/a&gt;&lt;/p&gt;</content:encoded><category>cycling</category></item><item><title>swimlanes.io — easy flow diagrams</title><link>https://notlar.im/en/blog/swimlanes-io-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/swimlanes-io-en/</guid><description>Build flow diagrams quickly using Markdown.</description><pubDate>Wed, 28 Apr 2021 20:29:48 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://swimlanes.io/&quot;&gt;Swimlanes.io&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Swimlanes.io is a free service that lets you build flow diagrams by writing &lt;em&gt;Markdown&lt;/em&gt;. The site greets you with a sample diagram when you first open it. Handy for presentations, teaching, or just explaining how something works.&lt;/p&gt;</content:encoded><category>bookmarks</category></item><item><title>Bike Lanes</title><link>https://notlar.im/en/blog/bike-lanes-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/bike-lanes-en/</guid><description>Bike lanes — history, types, comparisons.</description><pubDate>Sat, 24 Apr 2021 23:28:06 GMT</pubDate><content:encoded>&lt;p&gt;Bike lanes are one of the most-discussed topics among cyclists, even non-cyclists. Everyone has an opinion on whether they should exist, and if so what they should look like. I’d looked at this earlier in &lt;a href=&quot;https://www.bisikletforum.com/konu/bisiklet-yolu-kullanisli-mi-gerekli-mi-yapilmali-mi.153258/&quot;&gt;a Bisikletforum thread “Are bike lanes useful, necessary, should they be built?”&lt;/a&gt;. Two years later I wanted to write something more organised here. This will also be this blog’s first post.&lt;/p&gt;
&lt;h3&gt;”Everywhere in Europe is a bike lane”&lt;a href=&quot;#everywhere-in-europe-is-a-bike-lane&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is the popular line in every cycling debate:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“I want to ride a bike but there’s no bike lane — Europe has bike lanes everywhere apparently.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So nobody in Europe was cycling, then one day someone said “let’s build bike lanes” and all of Europe started riding? According to &lt;a href=&quot;https://www.theguardian.com/cities/2015/may/05/amsterdam-bicycle-capital-world-transport-cycling-kindermoord&quot;&gt;a Guardian article&lt;/a&gt;, if we take Amsterdam as an example, its bicycle use rate — close to 100% in the early 1900s — began dropping critically in the 50s and 60s as purchasing power rose. As a result, accident rates climbed. In 1971, 3,300 fatal traffic accidents occurred. More than 400 children lost their lives in traffic accidents. In response, the best-known protest campaign — &lt;strong&gt;Stop de Kindermoord&lt;/strong&gt; &lt;em&gt;(Stop the Child Murders)&lt;/em&gt; — was organised.&lt;/p&gt;
&lt;p&gt;A mother who joined the protest, &lt;strong&gt;van Putten&lt;/strong&gt;, said: “The city was torn down to make way for cars. We weren’t happy with the changes happening in society — they affected our lives. The streets no longer belonged to the people who lived on them, but to the big traffic flows. That made me very angry.”&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Stop de Kindermoord&lt;/em&gt; activists kept going with civil disobedience: blocking accident-prone intersections with tables, hosting meals on roads, reclaiming streets from cars. Lawmakers gave them meetings; they met the Prime Minister. The result: &lt;em&gt;Stop de Kindermoord&lt;/em&gt; was absorbed into the municipality, and the chosen solution was &lt;strong&gt;woonerf&lt;/strong&gt; — paved streets with speed bumps forcing cars to go slowly.&lt;/p&gt;
&lt;p&gt;Two years after Stop de Kindermoord formed, a second group emerged — &lt;em&gt;First Only Real Dutch Cyclists’ Union&lt;/em&gt;. They drew attention with megaphone protests, three-wheeled bikes, and painting unofficial “rogue” bike lanes on streets at night with coloured paint. A group member, Tom Godefrooij, said: &lt;em&gt;“We could have been caught by police, but we’d get newspaper and politician attention, and eventually our bike lane. Even in the 70s there were politicians who knew that focusing on cars would cause problems.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The 1973 oil crisis quadrupled oil prices. The Dutch government, to enforce energy saving and offer a new lifestyle, launched &lt;strong&gt;“Car-Free Sundays”&lt;/strong&gt;. Children could enjoy streets again without cars. During one of these car-free Sundays, a cyclist named &lt;em&gt;Maartje van Putten&lt;/em&gt; and her companions rode their bikes through a tunnel where cyclists were not permitted — and their ride ended at the police station.&lt;/p&gt;
&lt;p&gt;Toward the end of the 1980s, after years of protest, politicians realised a car-centric transport plan wasn’t realistic and switched to a bicycle-centric one. The process started with bright red, highly visible bike lanes painted on roads; by 2019 Amsterdam had over 35,000 km of bike lanes.&lt;/p&gt;
&lt;h3&gt;So what about Turkey?&lt;a href=&quot;#so-what-about-turkey&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Don’t we have bike lanes? Of course we do. But unfortunately each of these lanes has advantages and disadvantages. Before going through them one by one, let’s talk about the most pressing disadvantage of having a bike lane somewhere:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TURKISH ROAD TRAFFIC CODE, Article 66 — The following rules apply to bicycle, motorised bicycle, and motorcycle riders. (a) If a separate bike lane exists, bicycles and motorised bicycles &lt;strong&gt;are prohibited from riding on the motor road&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Because of this article, if there’s a bike-designated section on a road, riding on the motor road becomes a violation. No matter how unusable, bad, or dangerous the bike lane is — when you share the road with motor vehicles, you are in violation. This is the first legal loophole we should object to as cyclists.&lt;/p&gt;
&lt;h3&gt;Bike lanes integrated with pedestrian paths / coastal walks&lt;a href=&quot;#bike-lanes-integrated-with-pedestrian-paths--coastal-walks&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The Büyükçekmece Municipality claims this is Istanbul’s first bike lane — and it’s an example of this style. As you can see in the photo, it’s continually invaded by pedestrians and creates hazards. Either you constantly warn pedestrians, or — as also visible in the photo — you ignore the rules and squeeze through gaps. Definitely not suitable for road cycling or training. Specific to Büyükçekmece: because non-grip paint was used, it gets dangerously slippery when wet, adding extra risk. Still, fine for a cyclist out on a short outing on an empty coast, maybe on a rental bike.&lt;/p&gt;
&lt;p&gt;A better example is the bike lane on Izmir Kordon. But here too — because there’s no physical barrier separating pedestrians from cyclists — a pedestrian can suddenly jump into your path. And pedestrians walking through without noticing/knowing/caring about the bike lane create hazards: you end up with the problem of &lt;em&gt;having to warn everyone in order to ride&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;Bike lanes painted off from the motor road&lt;a href=&quot;#bike-lanes-painted-off-from-the-motor-road&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The bike lanes referred to in “Europe has bike lanes everywhere” are mostly like this:&lt;/p&gt;
&lt;p&gt;The bike lane above is in Zeytinburnu, which was &lt;a href=&quot;https://www.youtube.com/watch?v=3D4LqDqc4Go&quot;&gt;in the news for becoming a barbeque parking area&lt;/a&gt;. If this had been a two-lane motor road, even short stops would have provoked other drivers and the parked vehicle would have been reported and towed. As is, since the lane reads as &lt;strong&gt;“already belonging to bikes”&lt;/strong&gt; it’s easily declared a parking area. Through the &lt;em&gt;Bisikletliler Derneği&lt;/em&gt; (Cyclists’ Association)‘s efforts, the Mobile EDS application was implemented and the area was temporarily cleared, but it’s not a permanent solution.&lt;/p&gt;
&lt;p&gt;Stopping/parking is the main problem with this bike lane style. Also, when there are shops on the right side, either people park on the bike lane to unload goods, or they park outside the lane but unload goods &lt;em&gt;over&lt;/em&gt; the lane. Still, if a bike lane has to be built, this is the most useful and lowest-cost option.&lt;/p&gt;
&lt;p&gt;Another hazard with this style: drivers or passengers in vehicles parked alongside opening their doors without looking. Door-strikes are among the most common cyclist accidents.&lt;/p&gt;
&lt;p&gt;Another problem is when the bike lane runs both directions on only one side of the road. If a vehicle parks in the lane this way, a cyclist trying to continue is forced into the lane of oncoming traffic. A very bad example of this was built in Riva — removed after public outcry. On a highway with a 90 km/h speed limit, a cyclist coming from the opposite direction could meet cars unable to take the corner without violating the bike lane, leading to serious crashes.&lt;/p&gt;
&lt;h3&gt;Bike lanes separated from the road with various barriers&lt;a href=&quot;#bike-lanes-separated-from-the-road-with-various-barriers&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is one of the more popular types here. Unfortunately, the &lt;em&gt;General Directorate of Highways&lt;/em&gt; and local governments — with terrific optimism — built these to prevent cars from entering the bike lane using plastic bollards which (as visible in the photo) never work. Even iron bollards built for the same purpose &lt;a href=&quot;https://canakkalegundem.net/2018/03/02/sok-tak-duba/&quot;&gt;get ripped out by shopkeepers or residents to park cars&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The only configuration in this category that actually blocks cars is one with concrete or large plastic barriers. Of course, in that case it’s still hard to solve the motorcycle and moto-courier issue — they take over the pedestrian sidewalks anyway.&lt;/p&gt;
&lt;h3&gt;Is the problem the absence of bike lanes? Is the solution building more?&lt;a href=&quot;#is-the-problem-the-absence-of-bike-lanes-is-the-solution-building-more&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This part of the post is more subjective — speaking as a cyclist who’s been pedalling in Istanbul traffic for a while and uses the bike for transport: &lt;em&gt;I think no!&lt;/em&gt; You can build bike lanes, you can install steel barriers between cars and bikes — the problem is that people don’t respect bicycles, and you’re powerless against that. The law gives you some rights. Dedicated bike lanes are built for you. But when a car or pedestrian violates them, no authority will protect your rights or enforce those laws except yourself. It’s not your job to explain to dozens of parked-on-the-bike-lane drivers that they’re violating the law and wait for them to fix it. Even when you photograph and report the violations, &lt;a href=&quot;https://www.sabah.com.tr/teknokulis/haberler/2016/01/20/trafikte-whatsapptan-ihbar-donemi-kisa-surdu&quot;&gt;no enforcement has been applied since 2016 because of a legal gap&lt;/a&gt;. What would happen if you parked your bike in front of cars? The reverse doesn’t happen when a car parks in front of your bike. What if a pedestrian walked down a motor road pushing a stroller? They can easily do that in the bike lane and won’t even consider it wrong.&lt;/p&gt;
&lt;p&gt;To go back to the beginning of the post: when similar problems happened in Amsterdam, the residents’ demand wasn’t &lt;strong&gt;isolating bicycles and pedestrians from cars&lt;/strong&gt; — it was &lt;strong&gt;isolating cars from the city&lt;/strong&gt;. The real problem is the assumption that cars are more important than bikes. Take the “1.5 metres of clearance when passing” rule most cycling groups advocate for. Our request to authorities shouldn’t be “&lt;em&gt;let’s add such a rule&lt;/em&gt;” so much as how they will defend the rule once it exists. There’s no point in local government building kilometres of bike lanes if the municipal worker dumps sand in the lane, a car parks there, a pedestrian walks down it.&lt;/p&gt;
&lt;p&gt;Unfortunately this is the root of the differences between us and the countries we usually look up to. In Chicago, parking in a bike lane is a $150 fine — and &lt;a href=&quot;https://blockclubchicago.org/2018/07/24/site-dedicated-to-shaming-cars-parked-in-bike-lanes-gets-city-ticketing-agencys-attention/&quot;&gt;in 2015 it was issued 2,816 times, in 2016 2,766 times, in 2017 3,460 times&lt;/a&gt;. In Turkey it’s a daily problem every cyclist faces with no resolution path.&lt;/p&gt;
&lt;h3&gt;So what’s the proposed solution?&lt;a href=&quot;#so-whats-the-proposed-solution&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Cycling is a mode of transport, and isolating it from motor traffic is a futile effort. But lowering speed limits especially within cities, dedicating bike-specific lanes on high-speed/intercity roads, defending cyclists’ rights rather than seeing the bike as inferior to the car and a child’s toy — that’s the solution we need. Turkey already has cities with cycling culture, and in those places &lt;strong&gt;without needing to isolate bikes from cars&lt;/strong&gt; bicycle transport has worked for years. When our request from city leaders becomes “let me go with my bike” instead of “let me go with my car”, “let me park my bike” instead of “let me park my car” — cycling-based transport will start to develop.&lt;/p&gt;
&lt;p&gt;What do you think? Drop your views in the comments and contribute to this shared thinking.&lt;/p&gt;</content:encoded><category>cycling</category></item><item><title>Education — Web 2.0 Apps</title><link>https://notlar.im/en/blog/education-web-2-0-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/education-web-2-0-en/</guid><description>A list of education-related phone and web apps. I update this from time to time.</description><pubDate>Sat, 24 Apr 2021 23:21:58 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;A list of education-related phone, web, and desktop apps. I update this from time to time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://duolingo.com/&quot;&gt;Duolingo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kahoot.com/schools-u/&quot;&gt;Kahoot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.classdojo.com/&quot;&gt;ClassDojo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://get.plickers.com/&quot;&gt;Plickers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.pixton.com/&quot;&gt;Pixton&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://storybird.com/&quot;&gt;Storybird&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://animoto.com/&quot;&gt;Animoto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://scratch.mit.edu/&quot;&gt;Scratch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://classroom.google.com/&quot;&gt;Google Classroom&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.voscreen.com/&quot;&gt;Voscreen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.flippity.net/&quot;&gt;Flippity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mindmeister.com/&quot;&gt;Mindmeister&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://quizizz.com/&quot;&gt;Quizizz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hotpot.uvic.ca/&quot;&gt;Hot Potatoes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://prezi.com/&quot;&gt;Prezi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://quizlet.com/&quot;&gt;Quizlet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://preview.pitch.com/&quot;&gt;Pitch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Learning Platforms&lt;a href=&quot;#learning-platforms&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Coursera&lt;/li&gt;
&lt;li&gt;CourseHero&lt;/li&gt;
&lt;li&gt;English Central&lt;/li&gt;
&lt;li&gt;Khan Academy&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;YouTube Channels&lt;a href=&quot;#youtube-channels&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TEDEd&lt;/li&gt;
&lt;li&gt;Learn English with TV Series&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>education</category></item><item><title>1 Year Free Seed4.Me VPN</title><link>https://notlar.im/en/blog/seed4me-vpn-promo-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/seed4me-vpn-promo-en/</guid><description>A 1-year free VPN promotion from Seed4.Me</description><pubDate>Sat, 24 Apr 2021 23:21:24 GMT</pubDate><content:encoded>&lt;p&gt;NOTE: &lt;em&gt;No longer valid&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When you sign up for Seed4.me VPN with the code &lt;strong&gt;SHARE21&lt;/strong&gt; you get a 1-year free VPN subscription. The service works on many platforms and many countries.&lt;/p&gt;
&lt;p&gt;To sign up, you can use &lt;a href=&quot;https://seed4.me/users/register?gift=SHARE21&quot;&gt;https://seed4.me/users/register?gift=SHARE21&lt;/a&gt; directly. After confirming the email they send you, install the client for your operating system and start using it.&lt;/p&gt;
&lt;p&gt;If you want a bit more anonymity at signup, you can use a &lt;a href=&quot;https://temp-mail.org/tr/&quot;&gt;temporary mail service&lt;/a&gt; and avoid giving personal information. But keep in mind that the majority of those services log connection details — don’t do anything that would put you in legal trouble, and don’t use it for sensitive things like credit-card purchases.&lt;/p&gt;</content:encoded><category>internet</category></item><item><title>SponsorBlock — YouTube Sponsor-Skipping Extension</title><link>https://notlar.im/en/blog/sponsorblock-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/sponsorblock-en/</guid><description>SponsorBlock — extension that skips sponsored segments inside YouTube videos.</description><pubDate>Sat, 24 Apr 2021 23:09:37 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://sponsor.ajay.app/&quot;&gt;SponsorBlock&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://sponsor.ajay.app/LogoSponsorBlockSimple256px.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://sponsor.ajay.app/&quot;&gt;SponsorBlock&lt;/a&gt; skips the sponsor segments inside the YouTube videos you watch. The sponsor segments are marked by other users who already watched the video, and when you get to that timestamp, the video automatically jumps over the relevant part.&lt;/p&gt;
&lt;p&gt;The extension is available in many environments, including &lt;a href=&quot;https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone&quot;&gt;Google Chrome&lt;/a&gt;, &lt;a href=&quot;https://addons.mozilla.org/addon/sponsorblock?src=external-website&quot;&gt;Mozilla Firefox&lt;/a&gt;, &lt;a href=&quot;https://github.com/ajayyy/SponsorBlock/wiki/Edge&quot;&gt;Microsoft Edge&lt;/a&gt;, &lt;a href=&quot;https://github.com/ajayyy/SponsorBlock/wiki/Opera&quot;&gt;Opera&lt;/a&gt;, and &lt;a href=&quot;https://github.com/ajayyy/SponsorBlock/wiki/Android&quot;&gt;Android&lt;/a&gt;. Third-party builds for other devices are listed on their site too.&lt;/p&gt;
&lt;p&gt;At the time of writing they reported a total of &lt;strong&gt;1,282,217&lt;/strong&gt; sponsored segments blocked. Combined with a regular ad blocker, this gives you a near-complete ad block.&lt;/p&gt;</content:encoded><category>bookmarks</category></item><item><title>Popular Public Torrent Sites</title><link>https://notlar.im/en/blog/popular-torrent-sites-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/popular-torrent-sites-en/</guid><description>A list of popular public torrent sites by what they&apos;re known for.</description><pubDate>Fri, 23 Apr 2021 21:01:45 GMT</pubDate><content:encoded>&lt;p&gt;A list of popular public torrent sites grouped by what they’re best at.&lt;/p&gt;
&lt;h3&gt;1) &lt;a href=&quot;https://thepiratebay10.org/&quot;&gt;The Pirate Bay&lt;/a&gt; — most-used in general&lt;a href=&quot;#1-the-pirate-bay--most-used-in-general&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The Pirate Bay is one of the most-known and most-comprehensive torrent sites. It’s been the subject of many legal cases over the years; shut down, reopened. Today it’s still online via several alternative domains.&lt;/p&gt;
&lt;h3&gt;2) &lt;a href=&quot;https://rarbg.to/index70.php&quot;&gt;RARBG&lt;/a&gt; — best for new releases and 4K&lt;a href=&quot;#2-rarbg--best-for-new-releases-and-4k&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Another site that gets blocked from time to time. Content is moderated and approved, so you’re less likely to run into Pirate-Bay-style surprises.&lt;/p&gt;
&lt;h3&gt;3) &lt;a href=&quot;https://1337x.to/&quot;&gt;1337x&lt;/a&gt; — best for software / apps&lt;a href=&quot;#3-1337x--best-for-software--apps&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Founded in 2007 but became popular especially in 2018 when several other torrent sites shut down. Banned from Google search results so you can’t reach it via Google. Note: their ads can be NSFW, not ideal for the office or for children’s machines.&lt;/p&gt;
&lt;h3&gt;4) &lt;a href=&quot;https://www.torlock.com/movies/1/size/desc.html&quot;&gt;Torlock&lt;/a&gt; — one of the better ones for ebooks and anime&lt;a href=&quot;#4-torlock--one-of-the-better-ones-for-ebooks-and-anime&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A site with a clean UI and a rich ebook/anime catalogue. Some torrents you can’t find elsewhere show up here. Worth noting Torlock also goes a bit overboard with ads.&lt;/p&gt;
&lt;h3&gt;5) &lt;a href=&quot;https://torrentz2eu.org/&quot;&gt;Torrentz2&lt;/a&gt; — strong on music&lt;a href=&quot;#5-torrentz2--strong-on-music&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Torrentz2 has a particularly good music album catalogue. Simple UI.&lt;/p&gt;
&lt;h3&gt;6) &lt;a href=&quot;https://zooqle.com/&quot;&gt;Zoogle&lt;/a&gt; — strong on games&lt;a href=&quot;#6-zoogle--strong-on-games&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One of the newer torrent sites; mostly known for games but you can find movies and series too.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Worth noting that while these sites are pretty good for international content, they’re a bit thin on Turkish content. The main reason is that Turkish rights-holders monitor these channels closely and send takedown requests.&lt;/p&gt;</content:encoded><category>internet</category></item><item><title>backgroundremoverai.com</title><link>https://notlar.im/en/blog/backgroundremoverai-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/backgroundremoverai-en/</guid><description>Remove the background from photos</description><pubDate>Wed, 21 Apr 2021 17:01:07 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://backgroundremoverai.com/&quot;&gt;backgroundremoverai.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://backgroundremoverai.com/static/backgroundremover.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A web app that removes the background from your photos using machine learning. It works pretty well compared to its alternatives. Turkish language support too.&lt;/p&gt;</content:encoded><category>bookmarks</category></item><item><title>Timeline of Mathematics</title><link>https://notlar.im/en/blog/timeline-of-mathematics-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/timeline-of-mathematics-en/</guid><description>Famous people and events in the history of mathematics on a single timeline.</description><pubDate>Wed, 21 Apr 2021 17:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://mathigon.org/timeline&quot;&gt;Timeline of Mathematics – Mathigon&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mathigon.org/images/og-tile/timeline.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A timeline view of famous mathematicians and key events in the history of mathematics.&lt;/p&gt;</content:encoded><category>bookmarks</category></item><item><title>Piranha 7653 Bluetooth Mouse Review</title><link>https://notlar.im/en/blog/piranha-7653-bluetooth-mouse-review-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/piranha-7653-bluetooth-mouse-review-en/</guid><description>I bought this product when it appeared in the 13 August 2020 A101 Aktüel catalogue for 24.95 TL, thanks to its low price.</description><pubDate>Tue, 20 Apr 2021 01:55:46 GMT</pubDate><content:encoded>&lt;figure&gt;&lt;img src=&quot;https://miro.medium.com/max/395/0*95t6nd46-hLls5sx.jpg&quot; alt=&quot;&quot; /&gt;&lt;/figure&gt;
&lt;p&gt;This product appeared in the &lt;strong&gt;13 August 2020&lt;/strong&gt; Aktüel catalogue of A101 (a Turkish discount store chain; Aktüel is its weekly deals flyer) for &lt;strong&gt;24.95 TL&lt;/strong&gt;, and I bought it because of the low price. You can watch the video review I made on YouTube here:&lt;/p&gt;
&lt;figure&gt;&lt;iframe src=&quot;https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQAHMZOBjlIU%3Ffeature%3Doembed&amp;amp;display_name=YouTube&amp;amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQAHMZOBjlIU&amp;amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FQAHMZOBjlIU%2Fhqdefault.jpg&amp;amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;amp;type=text%2Fhtml&amp;amp;schema=youtube&quot;&gt;&lt;/iframe&gt;&lt;/figure&gt;
&lt;p&gt;The product looks nice on the outside. It also sits ergonomically in the hand for an everyday mouse. It weighs &lt;strong&gt;48 grams&lt;/strong&gt; without batteries and &lt;strong&gt;70 grams&lt;/strong&gt; with them — you could call it a light mouse. It runs on two &lt;strong&gt;AAA&lt;/strong&gt; batteries, which don’t come in the box. There’s no USB receiver; it works over Bluetooth only. There’s no information about which Bluetooth version it uses, and so on.&lt;/p&gt;
&lt;p&gt;The only thing inside is a sheet of paper explaining usage and warranty information. On first use, you apparently need to switch it off and on with the power button and then do the pairing. It shows up among Bluetooth devices under the name &lt;strong&gt;Piranha-7653&lt;/strong&gt;, and to pair you just need to select it. From then on, if you want to connect it to a new device, you have to hold the DPI button down for 3 seconds.&lt;/p&gt;
&lt;p&gt;The mouse has a scroll wheel and a middle button you use by pressing the wheel. But the middle button is very stiff and loud. The on/off switch on the bottom is hard to toggle even with a fingernail — I had to use a pin. To save battery I used to switch off my previous mice when I was done, but with this one that doesn’t look very feasible. I’ll add a note here about how long the batteries last with it constantly on like this.&lt;/p&gt;
&lt;p&gt;The mouse’s shell probably belongs to another, previously designed product. There’s an empty, unused USB receiver compartment.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Pros: &lt;strong&gt;The price is right.&lt;/strong&gt; For what you’d pay for a regular mouse anyway, you get a &lt;strong&gt;Bluetooth&lt;/strong&gt; mouse. New computers have few USB ports as it is, so one of your USB ports stays free. When needed, you can also pair it with tablets, phones, smart TVs and similar devices. &lt;strong&gt;Nice design. Light.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Cons: &lt;strong&gt;The middle button is stiff.&lt;/strong&gt; The clicks and so on give the impression that you’re not using a very, very good mouse. &lt;strong&gt;No USB receiver&lt;/strong&gt;. &lt;strong&gt;The on/off button is really bad&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My notes after using it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Another friend who bought the product reported that his on/off button was fine. Apparently mine just had this problem.&lt;/li&gt;
&lt;li&gt;Turns out the device has a module from a company called Yichip inside.&lt;/li&gt;
&lt;li&gt;It uses a Bluetooth LE (Low Energy) connection. It may not connect to devices that don’t support Bluetooth LE; I haven’t had a chance to test that yet.&lt;/li&gt;
&lt;li&gt;There’s no battery level indicator feature.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>bugra-hoca-youtube</category></item><item><title>How to Become an Amateur Radio Operator?</title><link>https://notlar.im/en/blog/how-to-become-a-ham-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/how-to-become-a-ham-en/</guid><description>My amateur radio exam experience — exam and certificate fees, the application process, and tips for preparing.</description><pubDate>Tue, 20 Apr 2021 01:39:15 GMT</pubDate><content:encoded>&lt;div&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/TK1Y28xmuCc?feature=oembed&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;To get the Amateur Radio Certificate I’d been interested in for a while, I sat Turkey’s Amateur Radio Exam. The exam fee is 115 TL, and after the 2021 price increase the amateur radio certificate (license) fee is 75 TL for students and 150 TL for non-students. In this video I gathered the step-by-step details of the exam — how to get the certificate, what to watch out for — together with the new exam process information announced in November 2020. You can use it as a tidy visual resource for your application.&lt;/p&gt;
&lt;p&gt;You can access all the required documents here:&lt;/p&gt;
&lt;figure&gt;&lt;a href=&quot;https://drive.google.com/drive/u/1/folders/15jUcbOLXaDCIkY2Ntg4uaQbG8kleCLaS&quot;&gt;&lt;div&gt;&lt;div&gt;Amateur Radio – Google Drive&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;img src=&quot;https://ssl.gstatic.com/images/branding/product/1x/drive_2020q4_32dp.png&quot; /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;img src=&quot;https://drive-thirdparty.googleusercontent.com/128/type/application/pdf&quot; /&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;Wishing everyone drawn to this hobby a quick and easy ride through the process — 73.&lt;/p&gt;</content:encoded><category>amateur-radio</category><category>bugra-hoca-youtube</category></item><item><title>TYT TH-UV88 In-Depth Review - Guide</title><link>https://notlar.im/en/blog/tyt-th-uv88-review-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/tyt-th-uv88-review-en/</guid><description>My video review (in Turkish) of the UV88, one of TYT&apos;s popular models.</description><pubDate>Tue, 20 Apr 2021 01:35:37 GMT</pubDate><content:encoded>&lt;div&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/edT2QSPNcUE?feature=oembed&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;My video review (in Turkish) of the UV88, one of TYT’s popular models.&lt;/p&gt;
&lt;h3&gt;IMPORTANT WARNING&lt;a href=&quot;#important-warning&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If a firmware update from your computer gets interrupted halfway and throws an error, do &lt;strong&gt;NOT TURN THE RADIO OFF&lt;/strong&gt;. Close the program you were using to flash the firmware and start it again. There’s a button labelled “Reset” — press it to reset the half-finished firmware flash. If you power the radio off before the update completes, your radio will be “bricked” and become unusable. In that case you would have to replace the radio’s memory chip.&lt;/p&gt;</content:encoded><category>amateur-radio</category><category>bugra-hoca-youtube</category></item><item><title>Asus N53SN Power Board Repair</title><link>https://notlar.im/en/blog/asus-n53sn-power-board-repair-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/asus-n53sn-power-board-repair-en/</guid><description>A timelapse video I shot while replacing the power board of my Asus N53SN laptop. It&apos;s not very detailed, but it should give you an idea of the process.</description><pubDate>Tue, 20 Apr 2021 01:31:54 GMT</pubDate><content:encoded>&lt;div&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/CWt-SGA4GZk?feature=oembed&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;A timelapse video I shot while replacing the power board of my Asus N53SN laptop. It’s not very detailed, but it should give you an idea of the process.&lt;/p&gt;</content:encoded><category>bugra-hoca-youtube</category></item><item><title>offsideornot.com</title><link>https://notlar.im/en/blog/offsideornot-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/offsideornot-en/</guid><description>A site that tests your offside-spotting skills against real VAR decisions — offsideornot.com.</description><pubDate>Tue, 20 Apr 2021 01:13:23 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://offsideornot.com/&quot;&gt;Offside or Not&lt;/a&gt;
&lt;img src=&quot;https://offsideornot.com/images/cover.png&quot; alt=&quot;&quot; /&gt;
&lt;a href=&quot;https://offsideornot.com/&quot;&gt;Offsideornot&lt;/a&gt; shows you various football positions and asks you to predict whether they’re offside or not, then compares your guess against actual VAR decisions. A test of your offside-spotting skills.&lt;/p&gt;</content:encoded><category>bookmarks</category></item><item><title>reddit - shopping subreddit</title><link>https://notlar.im/en/blog/reddit-shoppingbay-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/reddit-shoppingbay-en/</guid><description>A short bookmark note on r/shoppingbay, a subreddit where account trading goes on.</description><pubDate>Mon, 19 Apr 2021 22:43:05 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.reddit.com/r/shoppingbay/&quot;&gt;https://www.reddit.com/r/shoppingbay/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A subreddit where you can get hold of and use certain (usually illegally obtained) accounts — Netflix and the like — from Reddit. It used to live at r/redditbay, but I believe that one was shut down, again over the illegal sales.&lt;/p&gt;</content:encoded><category>bookmarks</category></item><item><title>noat.cards</title><link>https://notlar.im/en/blog/noat-cards-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/noat-cards-en/</guid><description>The site I used as a Quizlet and Anki alternative for making flashcards (now shut down).</description><pubDate>Mon, 12 Apr 2021 23:23:11 GMT</pubDate><content:encoded>&lt;p&gt;It was an open-source, free flashcard platform — an alternative to &lt;strong&gt;Quizlet&lt;/strong&gt; and &lt;strong&gt;Anki&lt;/strong&gt;. It ran in the browser and let you create flashcards for studying.&lt;/p&gt;
&lt;p&gt;The service shut down some time after this post was written — &lt;code&gt;noat.cards&lt;/code&gt; is no longer reachable. It stays listed here as a resource I used in the past.&lt;/p&gt;</content:encoded><category>bookmarks</category></item><item><title>RemoveBackground.app</title><link>https://notlar.im/en/blog/removebackground-app-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/removebackground-app-en/</guid><description>Remove the Background from Your Photos</description><pubDate>Mon, 12 Apr 2021 23:08:34 GMT</pubDate><content:encoded>&lt;figure&gt;&lt;a href=&quot;https://removebackground.app/&quot;&gt;&lt;div&gt;&lt;div&gt;RemoveBackground.app&lt;/div&gt;&lt;div&gt;Remove background from images quickly using machine learning. We offer the ability bulk remove background from images as well, and an API.&lt;/div&gt;&lt;div&gt;&lt;img src=&quot;https://removebackground.app/static/removebackground.png&quot; /&gt;&lt;span&gt;RemoveBackground.app&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;img src=&quot;https://removebackground.app/static/removebackground.png&quot; /&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;An app that removes the background from your photos using machine learning. It works remarkably well compared to the alternatives. It even has Turkish language support.&lt;/p&gt;</content:encoded><category>bookmarks</category></item><item><title>Cycling During Coronavirus</title><link>https://notlar.im/en/blog/cycling-during-covid-en/</link><guid isPermaLink="true">https://notlar.im/en/blog/cycling-during-covid-en/</guid><description>Is cycling healthy and safe during the pandemic? A short summary of expert answers from Bicycling.com.</description><pubDate>Mon, 12 Apr 2021 22:57:38 GMT</pubDate><content:encoded>&lt;p&gt;With coronavirus dominating our lives and #StayHome appeals being broadcast, cyclists are suffering from being stuck indoors. So is cycling healthy and safe these days? &lt;a href=&quot;https://www.bicycling.com/news/a31469228/cycling-during-coronavirus/&quot;&gt;An article on Bicycling.org&lt;/a&gt; lists Dr. David Nieman’s and Dr. Brian Labus’s answers to the questions on our minds.&lt;/p&gt;
&lt;h3&gt;Is it safe to ride a bike outside?&lt;a href=&quot;#is-it-safe-to-ride-a-bike-outside&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Yes, when transmission is the issue, being outside is better than being inside. When people gather and someone coughs or sneezes, the droplets from their mouth land on objects people touch, then people touch their faces. The best plan right now is to ride alone and enjoy being outside.&lt;/p&gt;
&lt;p&gt;Also, people fear getting sick from cold-weather riding — that’s not accurate; there’s no data showing cold-weather rides give you any airborne illness. 30–60 minutes of moderate activity can strengthen your immune system. While you’re doing it, make sure to follow any quarantine or personal isolation that applies in your region. And if you’re sick and at risk of spreading the virus, please stay home.&lt;/p&gt;
&lt;p&gt;If you’re in quarantine, do bodyweight exercises where you are, or work with a trainer — provided you’re not sick. If you have general flu or COVID-19 or a fever, some people mistakenly think you can “sweat the illness out”. This is not true. The opposite, in fact.&lt;/p&gt;
&lt;h3&gt;Can I ride during #StayHome / isolation?&lt;a href=&quot;#can-i-ride-during-stayhome--isolation&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;On 19 March California (and 13 March in Turkey) started a stay-at-home campaign. The public was asked to stay home until the next announcement and keep as much distance from others as possible. But the situation in San Francisco (and Turkey) doesn’t block people from going outside alone for things like cycling, running, walking. They’re only asked to maintain social distance, stay at least 2 metres away from others, and avoid moving around in groups. In short: you can exercise, but stay tuned to public health announcements first.&lt;/p&gt;
&lt;h3&gt;Should I avoid group activities?&lt;a href=&quot;#should-i-avoid-group-activities&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As of 18 March, the US Cycling Federation recommended cancelling races and group rides through 3 May (the Turkish Cycling Federation also postponed its associated races to a later date).&lt;/p&gt;
&lt;h3&gt;Is spitting while riding a health risk right now?&lt;a href=&quot;#is-spitting-while-riding-a-health-risk-right-now&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Doctors say transmission of COVID-19 via saliva is possible. COVID-19 spreads when someone coughs or sneezes, and those droplets reach the eyes, nose, or mouth of nearby people. Saliva can contain nasal discharge or material from the lungs alongside the spit itself. Same goes for cyclists clearing their noses while riding.&lt;/p&gt;
&lt;h3&gt;How long does COVID-19 last on clothing?&lt;a href=&quot;#how-long-does-covid-19-last-on-clothing&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Experts don’t have a unanimous view yet on transmission from surfaces like clothing. But the WHO’s position is that the virus can survive between a few hours and a few days. If saliva lands on your clothes, change as fast as possible while avoiding touching the affected area, then wash your hands. To disinfect clothes, wash at high temperature and tumble-dry at high temperature.&lt;/p&gt;
&lt;h3&gt;Should I avoid touching things outdoors?&lt;a href=&quot;#should-i-avoid-touching-things-outdoors&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.cdc.gov/coronavirus/2019-ncov/index.html&quot;&gt;Recent data&lt;/a&gt; suggests the new coronavirus doesn’t last long on outdoor objects when exposed to sunlight (UV). Generally, the virus is found only in small amounts on outdoor objects. But if an infected person coughs or sneezes into their hand and then touches a crosswalk button, and you touch it right after, transmission becomes possible.&lt;/p&gt;
&lt;h3&gt;Does the virus spread through sweat?&lt;a href=&quot;#does-the-virus-spread-through-sweat&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Per CDC, the virus does not spread through sweat — it spreads through droplets from coughing and sneezing to people within 2 metres.&lt;/p&gt;
&lt;h3&gt;Can I spread the disease before symptoms appear?&lt;a href=&quot;#can-i-spread-the-disease-before-symptoms-appear&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;That’s another aspect of coronavirus that isn’t fully understood yet. Probably, in the period just before symptoms appear, you can already spread it. Once you start coughing or sneezing, you become naturally more contagious. Social distancing is the only solution for now. Experts are still working on how long the virus survives on surfaces, and the core problem is that it’s extremely contagious, easily transmitted through coughing and sneezing, and can be spread by people who don’t realise they’re sick. That’s why washing hands and not touching your face is so important.&lt;/p&gt;
&lt;h3&gt;After exercise, does my immune system weaken or strengthen?&lt;a href=&quot;#after-exercise-does-my-immune-system-weaken-or-strengthen&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When your glycogen stores are depleted, your body doesn’t function normally. After a hard ride or race, if you’re exposed to someone with the flu or coronavirus, your immune system is essentially down. Plus, the mental and physical stress of a long ride can increase your chance of getting sick. Dr. Nieman’s view: cyclists should avoid long, intense rides and training. During this period, cyclists should think about being healthy, not about being in form. But this doesn’t mean stop cycling or exercising entirely. There’s a strong link between regular exercise and a strong immune system.&lt;/p&gt;
&lt;h3&gt;Is it safe to go to the gym?&lt;a href=&quot;#is-it-safe-to-go-to-the-gym&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Most countries and cities are taking steps to prevent the virus spreading. In many places, gyms — which could easily spread the virus — have been temporarily closed as a precaution. Working out at home during this period may be the best way to maintain fitness and health. Many closed gyms also offer online classes you can stream. Also, wherever you exercise, don’t forget to wash your hands regularly after exercise and to wipe down all your equipment.&lt;/p&gt;
&lt;h3&gt;If we use shared/rental bikes, what extra precautions can we take?&lt;a href=&quot;#if-we-use-sharedrental-bikes-what-extra-precautions-can-we-take&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If a sick person used the bike right before you, they may have left virus on the handlebars. Wiping the bars with antibacterial wipes before riding will prevent exposure to many viruses and bacteria. According to CDC, while it’s not the primary transmission route, you can catch COVID-19 by touching a contaminated surface and then your mouth, nose, or eyes. Generally, if you use gloves and disinfect the bars before riding, shared bikes seem OK. Still wash your hands right after and avoid touching your face.&lt;/p&gt;
&lt;h3&gt;My race isn’t cancelled — should I go?&lt;a href=&quot;#my-race-isnt-cancelled--should-i-go&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You may be wondering what to do about the race you’ve been preparing for for ages. Short answer: don’t go. CDC recommends cancelling all events of 50+ people for the next 8 weeks.&lt;/p&gt;
&lt;h3&gt;My race got cancelled but there are other group rides. Can I go?&lt;a href=&quot;#my-race-got-cancelled-but-there-are-other-group-rides-can-i-go&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In place of cancelled events, group rides or informal races may pop up. But &lt;em&gt;any&lt;/em&gt; event where people gather carries transmission risk. In general: be selective with your interactions, wash your hands, avoid direct contact, don’t touch your face. And remember — beyond coronavirus, the regular flu is also out there.&lt;/p&gt;</content:encoded><category>cycling</category></item></channel></rss>