In Praise of OliveTin

olivetin

In a world of complex internal tools, OliveTin bridges the gap between raw CLI and usable web UI with just yaml config.

Server Admin Panel

I used admin panels like CockPit, Ajenti, etc to provide simple web UI for non-developers to provide access to services. Developing custom widgets is time consuming and requires programming skills as well.

With OliveTin, I can provide web UI directly with just yaml config. This saves a lot of time and effort. It also provides a clean UI as it starts from scratch.

Backend Driven UI

For existing python scripts, I often use tools like Streamlit, NiceGUI, etc to create web UIs. Organizing the UI components for multiple scripts is time consuming.

OliveTin can provide web UI directly python scripts and they can be organized in groups with just yaml config.

Mobile Friendly

To do a simple deployment on mobile, I need to open an app that supports ssh, ssh into the server, navigate to a directory, run a script to deploy.

OliveTin provides a "Deploy" button on mobile browser which is way convenient.

Authentication

olivetin-oauth2

OliveTin provides authentication(local users, OAuth2, JWT, etc), authorization(ACLs) & accounting(logs) out of the box. With just yaml config, we can secure the web UI.

Conclusion

There are hundreds of other features provided by OliveTin like scheduling, file uploads, webhooks, etc.

If you ever want to provide a simple web UI for scripts with low code or no code, give OliveTin a try!

Remote Access to k3d/k3s Kubernetes cluster

Introduction

We learnt how to deploy kubernetes cluster anywhere with a single k3d command. By default, k3d cluster is accessible only from the host machine.

Remote Access

k3d-remote-access

Create new cluster with

$ k3d cluster create cloud-k8s \
  --api-port 6443:6443@loadbalancer \
  --k3s-arg "--tls-san=<remote-ip>@server:*"
  • --api-port 6443:6443@loadbalancer maps port 6443 on the host machine to the cluster's API server load balancer. This can be changed (e.g., 8080:6443) if 6443 is taken on the host.

  • --k3s-arg "--tls-san=..." adds the host's public IP to the certificate, preventing SSL errors later.

  • Ensure remote server firewall allows incoming traffic on the chosen port (e.g., 6443 or 8080). To verify, run telnet <remote-ip> 6443 from local machine.

On the remote server, get kubeconfig:

$ k3d kubeconfig get cloud-k8s
---
apiVersion: v1
clusters:
- cluster:
    server: https://0.0.0.0:6443
  name: k3d-rk
   ... # truncated for brevity

Copy this kubeconfig, replace 0.0.0.0 with the remote server's public IP.

Open Free Lens, paste this config and connect to the remote k3d cluster.

k3d-remote-access

Conclusion

You can use your favorite Kubernetes tools (kubectl, FreeLens, k9s, etc.) to manage the remote k8s cluster.

Setup Tailscale App Connector in 3 easy steps

Problem Statement

In the earlier post, we have seen how to route specific websites to an exit node using a SOCKS proxy & browser extension(or a PAC file).

With this approach, when we need to work on multiple computers, we need to setup the SOCKS proxy & browser extension individually.

Instead we can use Tailscale's App Connectors to route specific websites through selected nodes.

Tailscale docs are too complicated for this App connectors. Here is a simplified version of the steps.

Tailscale - App Connectors

Note: There is no need for publicly reachable IP address for the Tailscale node which is used as App Connector. (Thanks Chris Smith for pointing it out. Tailscale docs are misleading in this regard.)

  • In the Tailscale admin console, go to the "Access control" section & add tagOwners.
    "tagOwners": {
        "tag:home-connector": [
            "autogroup:member",
        ],
    },

tailscale app connector acl

  • Use any Linux machine (it doesn't need static IP) to setup the App Connector. Install Tailscale on it. Advertise it as an app connector.
$ sudo tailscale up --advertise-tags=tag:home-connector --accept-routes

Enable IP forwarding on the machine. If your Linux system has a /etc/sysctl.d directory, run

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

Otherwise, run

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf
  • From the Tailscale admin console, create a new app connector.

tailscale app connector

In the "Target" field, we can select any existing app or we can use custom target so that we can route our desired websites. For now, I am adding ip.me domain so that we can verify if the traffic is routed through the connector.

  • From the "Machines" page, select the device and approve the requested subnets.

tailscale app connector subnet

From browser, lets visit 2ip.io to see our device ip address. Next, lets visit ip.me to ensure we are seeing the connector's IP as this domain will be served by app connector.

tailscale app connector verify

Conclusion

We can use App Connectors to route specific websites through a Tailscale node without needing to setup SOCKS proxy or browser extensions on each device.

TailScale - Use Exit Node for Specific Websites only

Problem

Tailscale1 provides zero-config mesh VPN built on top of Wiregaurd.

It provides an option to use an exit node for routing all traffic through it. But it can't route only specific domains through the exit node.

Tailscale Exit Node Option

Solution

Setup a SOCKS proxy using ssh command line tool.

ssh -D 1080 -f -C -q -N user@exit-node-ip

-D 1080 : Specifies the local port to listen on for SOCKS connections.

-f : Requests ssh to go to background just before command execution.

-C : Enables compression.

-q : Quiet mode.

-N : Do not execute remote commands.

Once it is started, we can use ZeroOmega2 browser extension to route specific domains through the SOCKS proxy.

ZeroOmega Config

In the auto switch profile, we can setup specific domains which needs to be directed to the proxy. For all other domains, it will use the direct connection.

This works only for the browser where the extension is installed.

To apply this at the system level, we can use pac file and update the system proxy settings to use the pac file.

Conclusion

Tailscale provides app connector feature to route specific apps through the exit node, but it is needs publicly reachable IPs & Linux based OS for now.

Setting up SOCKS proxy & using a browser extension or PAC file is much easy & straight forward solution to route specific domains through Tailscale exit node.

MacBook - Natural Scrolling for Mouse

Problem

If we connect a mouse to macOS, the scrolling direction changes to "unnatural" for the mouse. This is because macOS has a single setting for natural scrolling that applies to both trackpad and mouse.

macos mouse settings

Solution

To have natural scrolling for both trackpad and mouse, we can use third-party tools like UnnaturalScrollWheels.

If we already use Karabiner-Elements, we can use it to set natural scrolling for mouse separately.

Open Karabiner-Elements and go to the "Devices" tab, select your mouse, and click on "Open mouse settings".

Karabiner-Elements Devices Tab

In the mouse settings, check the "Flip mouse vertical wheel" option.

Karabiner-Elements Devices Tab

Now, both trackpad and mouse will have natural scrolling.

Mutual Funds - Behind the scenes

As investors, we buy mutual funds from fund houses, platforms, or from distributors. But have you ever wondered what happens behind the scenes? How do these funds operate, and what processes are involved in managing them? In this post, we'll explore the behind-the-scenes operations of mutual funds.

Structure of a Mutual Fund

Mutual Fund Structure

In India, mutual funds have 3-tier structure consisting of the Sponsor, the Trust & the Asset Management Company (AMC).

  • The sponsor establishes the mutual fund and is responsible for its operations.

  • The trust & trustees are responsible for safeguarding investor interests, supervising the AMC's operations, and ensuring compliance with regulations. Custodians are appointed to hold the securities of the mutual fund and ensure their safekeeping.

  • AMC is the core entity responsible for the day-to-day management of the mutual fund.

The legal seperation of Trust & AMC ensures that the interests of investors are protected, and the fund's assets are managed independently.

All AMCs are registered with the Securities and Exchange Board of India (SEBI) and the list is available on the SEBI website.

We can look at SBI MF details from AMFI to understand the structure better.

Mutual Fund Structure

Mutual Fund Transactions

Mutual Fund Transactions

RIA: Investors can use RIA (Registered Investment Advisor) platforms like Groww, Zerodha Coin, to invest in direct mutual funds.

MFD Alternatively, they can also buy regular mutual funds through distributors like NJWealth, PhonePhe etc.

TEP: To process these transactions, Trading & Execution Platforms like BSE Star MF, NSE MFSS, etc are available. These platforms facilitate the buying and selling of mutual fund units, ensuring that transactions are executed efficiently and accurately.

RTA: RTA(Registrar and Transfer Agent) plays a crucial role in maintaining investor records, processing transactions, and ensuring compliance with regulatory requirements.

Investors can also buy mutual funds directly from the fund house's website or through their mobile app.

These mutual funds can be stored in Demat account or in physical form as account statements. It depends on the platform or fund house you choose to invest with.

Conclusion

This post provided a brief overview of the behind-the-scenes operations of mutual funds in India.

Setup Raspberry Pi without Monitor & Keyboard

Requirements

  • Raspberry Pi (any model)
  • MicroSD card (8GB or larger)
  • Power supply

Setup

Download & install Raspberry Pi Imager from here.

![Raspberry Pi Imager]

After installation, connect SD Card to Computer, and start installation process.

In the config step, setup WiFi credentials and enable ssh server as well.

![Raspberry Pi Imager]

Once the installation is complete, insert the SD card into the Raspberry Pi and power it on.

Find the IP Address

You can find the IP address of your Raspberry Pi by checking your router's connected devices list or using a network scanning tool like nmap or arp.

arp -an

# or using nmap
nmap -sn

Once you have the IP address, you can SSH into the Raspberry Pi.

ssh pi@<IP_ADDRESS>

Conclusion

When we don't have a monitor and/or keyboard, this process allows us to set up a Raspberry Pi headlessly. This is particularly useful for projects where the Pi will be used as a server or in a remote location.

Raycast replaced 10 macOS apps

Since I started using Raycast, I have replaced many macOS apps with it. Here is a list of those apps and their Raycast equivalents.

Espanso

Instead of using Espanso for text expansion, I now use Raycast's built-in text snippets feature.

Hotkey

I used to use Hotkey to assign keyboard shortcuts to various actions. Now, I use Raycast's built-in hotkeys feature to achieve the same functionality.

Fly Cut

I used to use Fly Cut for clipboard management, but now I rely on Raycast's clipboard history feature to access my clipboard items quickly.

FinderGO

I used to use FinderGO to quickly navigate to specific folders in Finder. Now, I use Raycast's built-in file navigation feature to achieve the same functionality.

Rectangle

To move and resize windows, I used to use Rectangle. Now, I use Raycast's built-in window management feature to achieve the same functionality.

Textbar

Instead of using Textbar to copy TOTP for two-factor authentication, I now use Raycast's extension "One Time Password" to generate and copy TOTP codes directly.

Caffenate

To prevent my Mac from sleeping, instead of using Caffenate, I now use Raycast's built-in "Caffeinate" command to keep my Mac awake.

Calculator

Instead of using Python prompt for basic arithmetic calculations, I now use Raycast's built-in calculator feature to perform quick calculations. This is super convenient and saves me from opening a separate calculator app.

Hammer Spoon (partially)

To assign shortcuts to browser urls, shell scripts, and other actions, I used to use Hammer Spoon. Now, I use Raycast's built-in scripting capabilities to create custom commands and assign shortcuts to them.

Terminal (partially)

For things like killing processes, installing packages, and running shell commands, I used to rely on Terminal. Now, I use Raycast's built-in terminal integration to run shell commands directly from the Raycast interface.

Conclusion

With Raycast, I have been able to streamline my workflow by replacing multiple macOS apps with its powerful features.

Migrating from Nginx to Caddy

When deploying web apps in production, a web server is essential for serving static files, handling reverse proxying, and managing SSL/TLS certificates.

I have been using Nginx for a long time, but I have recently switched to Caddy as it provides automatic HTTPS by default. In addition, Caddy has a simpler configuration syntax and is easier to set up for basic use cases.

Nginx vs Caddy

To illustrate the differences, here are some examples of how to configure a simple web server in both Nginx and Caddy.

Nginx Configuration
server {
    listen 80;
    server_name avilpage.com;

    location / {
        root /var/www/html;
        index index.html index.htm;
    }

    location /api {
        proxy_pass http://localhost:3000;
    }
}

With Nginx, you need to manually handle SSL/TLS certificates, which can be cumbersome. You typically use tools like Certbot to obtain and renew certificates.

Caddy Configuration
avilpage.com {
    root * /var/www/html
    file_server

    reverse_proxy /api localhost:3000
}

Caddy automatically manages SSL/TLS certificates for you, so you don't need to worry about obtaining or renewing them. It also provides default redirection from HTTP to HTTPS, making it easier to secure your site.

Conclusion

Caddy's automatic HTTPS and simpler configuration syntax make it a compelling choice for web servers, especially for those who want to get started quickly without dealing with the complexities of SSL/TLS management.

Python UV in 100 seconds

UV is a fast Python package manager that replaces tools like pip, pyenv, virtualenv, etc.

Install uv

# On macOS and Linux.
curl -LsSf https://astral.sh/uv/install.sh | sh
# On Windows.
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Installing Python

uv python list

uv python install 3.13

This makes it easy to install and manage multiple versions of Python on your system without needing of pyenv.

Using UV with existing requirements.txt

uv venv --seed -p 3.13

source .venv/bin/activate

uv pip install -r requirements.txt

This is way faster than using any other tool to create virtual environments.

Managing virtual environments

uv init -p 3.13 --name demo

uv add pandas

This creates a new virtual environment named demo with Python 3.13 and adds the pandas package to it.

Runs scripts with inline dependencies

# /// script
# requires-python = ">=3.13"
# dependencies = [
#     "requests",
# ]
# ///
import requests

print(requests.get("https://avilpage.com"))
uv run script.py

uvx

Similar to pipx, it can install and run Python applications in isolated environments.

uv tool install glances

uv tool run glances

# shortcut
uvx glances

Conclusion

UV speeds up Python development by providing a fast package manager, virtual environment management, and inline dependency management. It is a great alternative to traditional tools like pip, pyenv, and virtualenv.