<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Avil Page</title><link>https://avilpage.com/</link><description>Avil Page - Personal &amp; tech blog by Pandikunta Anand Reddy (aka Chillar Anand)</description><atom:link href="https://avilpage.com/rss.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><lastBuildDate>Sat, 28 Mar 2026 08:55:04 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Build/Deploy Full Stack Web Apps with only Config</title><link>https://avilpage.com/2026/03/config-first-tools.html</link><dc:creator>Anand Reddy Pandikunta</dc:creator><description>&lt;blockquote&gt;
&lt;p&gt;The best code is the code you don't have to write&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Config First Tools&lt;/h4&gt;
&lt;p&gt;Any tool that provides first class support for configuration files can be considered a Config First Tool. 
These tools allow developers to setup/build/deploy applications by writing configuration files instead of writing code.&lt;/p&gt;
&lt;p&gt;In DevOps world, tools like Terraform, Ansible, and Kubernetes are examples of Config First Tools. 
These kinds of tools are not that popular in the web development world.&lt;/p&gt;
&lt;p&gt;In this article, lets see how we can build a full stack web application using only configuration files.&lt;/p&gt;
&lt;h4&gt;Todo - Web App&lt;/h4&gt;
&lt;p&gt;A simple backend API that allows users to manage todo lists.
A simple frontend that uses the backend API.
A simple script to deploy the backend and frontend applications.&lt;/p&gt;
&lt;h4&gt;Backend API&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://pocketbase.io/"&gt;PocketBase&lt;/a&gt; is a backend API that provides a simple way to create and manage databases, authentication, and file storage.
It is a great tool for building simple backend APIs without writing any code.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;brew&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;pocketbase
$&lt;span class="w"&gt; &lt;/span&gt;pocketbase&lt;span class="w"&gt; &lt;/span&gt;serve
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can create a collection called &lt;code&gt;Todo&lt;/code&gt; with required fields and pocketbase will automatically generate the API for us.&lt;/p&gt;
&lt;p&gt;&lt;img alt="config-first-tools" src="https://avilpage.com/images/config-first-tools-backend.png"&gt;&lt;/p&gt;
&lt;h4&gt;Frontend&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://lowdefy.com/"&gt;Lowdefy&lt;/a&gt; is a config first tool that allows us to build web applications using yaml config.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;npm&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;lowdefy
$&lt;span class="w"&gt; &lt;/span&gt;lowdefy&lt;span class="w"&gt; &lt;/span&gt;init
$&lt;span class="w"&gt; &lt;/span&gt;lowdefy&lt;span class="w"&gt; &lt;/span&gt;dev
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For basic crud apps, instead of us writing the boilerplate config, we can ask an AI agent to write the config for us.&lt;/p&gt;
&lt;h4&gt;Deployment&lt;/h4&gt;
&lt;p&gt;For deployment, we can use Ansible to deploy both the backend and frontend applications. Here also we can just AI agent to write the playbook for us.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;ansible
$&lt;span class="w"&gt; &lt;/span&gt;ansible-playbook&lt;span class="w"&gt; &lt;/span&gt;deploy.yml
&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;OliveTin&lt;/h4&gt;
&lt;p&gt;&lt;img alt="config-first-tools" src="https://avilpage.com/images/config-first-tools-devops.png"&gt;&lt;/p&gt;
&lt;p&gt;Even though we can use ansible to deploy the applications, it is not that convenient to run ansible playbooks on mobile.
&lt;a href="https://www.olivetin.app"&gt;OliveTin&lt;/a&gt; is a config first tool that allows us to create web UIs for our scripts.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ToDo&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;App"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;popupOnStart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;execution-dialog&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;shell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;ansible-playbook deploy.yml&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;6000&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"🤖"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can create a simple web UI for our deployment script with just 5 lines.&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;For quick prototyping and simple applications, config first tools can be a great choice as they allow us to build applications without writing any code.
They also allow us to focus on the application logic rather than the implementation details.&lt;/p&gt;
&lt;p&gt;With the rise of AI, it is much easy to maintain 500 lines of config than 5000 lines of code.&lt;/p&gt;</description><category>ai</category><category>devops</category><category>web development</category><guid>https://avilpage.com/2026/03/config-first-tools.html</guid><pubDate>Sat, 28 Mar 2026 06:17:29 GMT</pubDate></item><item><title>Talk: Classify Billion base pairs per Second</title><link>https://avilpage.com/2026/02/classify-billion-base-pairs-per-second.html</link><dc:creator>Anand Reddy Pandikunta</dc:creator><description>&lt;p&gt;During 25th Feb 2026, a &lt;a href="https://www.meetup.com/bangpypers/events/311155506"&gt;joint meetup&lt;/a&gt; was hosted by BangPypers &amp;amp; SciPy India. &lt;/p&gt;
&lt;p&gt;There was a slot for lightning talk &amp;amp; I gave a talk on Kraken2 performance optimisations titled as "Classify billion base pairs per second".&lt;/p&gt;
&lt;p&gt;Since it was a lightning talk, I didn't had time to polish the slides. During the talk, I briefly covered:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is metagenomics?&lt;/li&gt;
&lt;li&gt;Overview of open source classification tools &lt;/li&gt;
&lt;li&gt;Brief intro to Kraken2&lt;/li&gt;
&lt;li&gt;Performance optimizations in Kraken2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Few years back, I wrote a series of posts on &lt;a href="https://avilpage.com/2024/07/mastering-kraken2-initial-runs.html"&gt;Mastering Kraken2&lt;/a&gt; where I covered all the optimizations in detail.
If you want to dig deeper into the topic, you can check out the series.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://avilpage.com/images/anand-talk-kraken.png" alt="Anand's talk on Kraken" width="600"&gt;&lt;/p&gt;</description><category>talks</category><guid>https://avilpage.com/2026/02/classify-billion-base-pairs-per-second.html</guid><pubDate>Sat, 28 Feb 2026 01:27:43 GMT</pubDate></item><item><title>In Praise of OliveTin</title><link>https://avilpage.com/2026/01/in-praise-of-olivetin.html</link><dc:creator>Anand Reddy Pandikunta</dc:creator><description>&lt;p&gt;&lt;img alt="olivetin" src="https://avilpage.com/images/olivetin.png"&gt;&lt;/p&gt;
&lt;p&gt;In a world of complex internal tools, &lt;a href="https://www.olivetin.app"&gt;OliveTin&lt;/a&gt; bridges the gap between raw CLI and usable web UI with just yaml config.&lt;/p&gt;
&lt;h4&gt;Server Admin Panel&lt;/h4&gt;
&lt;p&gt;I used admin panels like &lt;a href="https://avilpage.com/2024/12/install-cockpit-on-remote-linux-vm.html"&gt;CockPit&lt;/a&gt;, 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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;Backend Driven UI&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;OliveTin can provide web UI directly python scripts and they can be organized in groups with just yaml config.&lt;/p&gt;
&lt;h4&gt;Mobile Friendly&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;OliveTin provides a "Deploy" button on mobile browser which is way convenient.&lt;/p&gt;
&lt;h4&gt;Authentication&lt;/h4&gt;
&lt;p&gt;&lt;img alt="olivetin-oauth2" src="https://avilpage.com/images/olivetin-oauth2.png"&gt;&lt;/p&gt;
&lt;p&gt;OliveTin provides authentication(local users, OAuth2, JWT, etc), authorization(ACLs) &amp;amp; accounting(logs) out of the box.
With just yaml config, we can secure the web UI.&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;There are hundreds of other features provided by OliveTin like scheduling, file uploads, webhooks, etc.&lt;/p&gt;
&lt;p&gt;If you ever want to provide a simple web UI for scripts with low code or no code, give OliveTin a try!&lt;/p&gt;</description><category>automation</category><category>cross-platform</category><category>devops</category><guid>https://avilpage.com/2026/01/in-praise-of-olivetin.html</guid><pubDate>Fri, 30 Jan 2026 20:13:11 GMT</pubDate></item><item><title>Remote Access to k3d/k3s Kubernetes cluster</title><link>https://avilpage.com/2025/12/remote-access-to-k3d-k3s-cluster.html</link><dc:creator>Anand Reddy Pandikunta</dc:creator><description>&lt;h4&gt;Introduction&lt;/h4&gt;
&lt;p&gt;We learnt how to &lt;a href="https://avilpage.com/2023/03/setup-k8s-anywhere-k3d.html"&gt;deploy kubernetes cluster anywhere with a single k3d command&lt;/a&gt;. 
By default, k3d cluster is accessible only from the host machine.&lt;/p&gt;
&lt;h4&gt;Remote Access&lt;/h4&gt;
&lt;p&gt;&lt;img alt="k3d-remote-access" src="https://avilpage.com/images/k3s-remote-access.png"&gt;&lt;/p&gt;
&lt;p&gt;Create new cluster with&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;k3d&lt;span class="w"&gt; &lt;/span&gt;cluster&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;cloud-k8s&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--api-port&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6443&lt;/span&gt;:6443@loadbalancer&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;--k3s-arg&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--tls-san=&amp;lt;remote-ip&amp;gt;@server:*"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--api-port 6443:6443@loadbalancer&lt;/code&gt; 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.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--k3s-arg "--tls-san=..."&lt;/code&gt;  adds the host's public IP to the certificate, preventing SSL errors later.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ensure remote server firewall allows incoming traffic on the chosen port (e.g., 6443 or 8080). 
To verify, run &lt;code&gt;telnet &amp;lt;remote-ip&amp;gt; 6443&lt;/code&gt; from local machine.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the remote server, get kubeconfig:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;k3d&lt;span class="w"&gt; &lt;/span&gt;kubeconfig&lt;span class="w"&gt; &lt;/span&gt;get&lt;span class="w"&gt; &lt;/span&gt;cloud-k8s
---
apiVersion:&lt;span class="w"&gt; &lt;/span&gt;v1
clusters:
-&lt;span class="w"&gt; &lt;/span&gt;cluster:
&lt;span class="w"&gt;    &lt;/span&gt;server:&lt;span class="w"&gt; &lt;/span&gt;https://0.0.0.0:6443
&lt;span class="w"&gt;  &lt;/span&gt;name:&lt;span class="w"&gt; &lt;/span&gt;k3d-rk
&lt;span class="w"&gt;   &lt;/span&gt;...&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# truncated for brevity&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Copy this kubeconfig, replace &lt;code&gt;0.0.0.0&lt;/code&gt; with the remote server's public IP.&lt;/p&gt;
&lt;p&gt;Open &lt;a href="https://github.com/freelensapp/freelens"&gt;Free Lens&lt;/a&gt;, paste this config and connect to the remote k3d cluster.&lt;/p&gt;
&lt;p&gt;&lt;img alt="k3d-remote-access" src="https://avilpage.com/images/k3s-remote-access-freelens.png"&gt;&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;You can use your favorite Kubernetes tools (kubectl, FreeLens, k9s, etc.) to manage the remote k8s cluster.&lt;/p&gt;</description><category>devops</category><category>kubernetes</category><category>linux</category><guid>https://avilpage.com/2025/12/remote-access-to-k3d-k3s-cluster.html</guid><pubDate>Wed, 17 Dec 2025 03:10:39 GMT</pubDate></item><item><title>Setup Tailscale App Connector in 3 easy steps</title><link>https://avilpage.com/2025/11/tailscale-app-connectors-quick-setup.html</link><dc:creator>Anand Reddy Pandikunta</dc:creator><description>&lt;h4&gt;Problem Statement&lt;/h4&gt;
&lt;p&gt;In the earlier post, we have seen how to &lt;a href="https://avilpage.com/2025/10/tailscale-exit-node-specific-domains.html"&gt;route specific websites to an exit node&lt;/a&gt; using a SOCKS proxy &amp;amp; browser extension(or a PAC file).&lt;/p&gt;
&lt;p&gt;With this approach, when we need to work on multiple computers, we need to setup the SOCKS proxy &amp;amp; browser extension individually.&lt;/p&gt;
&lt;p&gt;Instead we can use Tailscale's App Connectors to route specific websites through selected nodes.&lt;/p&gt;
&lt;p&gt;Tailscale docs are too complicated for this App connectors. Here is a simplified version of the steps.&lt;/p&gt;
&lt;h4&gt;Tailscale - App Connectors&lt;/h4&gt;
&lt;p&gt;Note: There is no need for publicly reachable IP address for the Tailscale node which is used as App Connector.
(Thanks &lt;a href="https://chameth.com"&gt;Chris Smith&lt;/a&gt; for pointing it out. Tailscale docs are misleading in this regard.)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the Tailscale admin console, go to the "Access control" section &amp;amp; add &lt;code&gt;tagOwners&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"tagOwners"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"tag:home-connector"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="s2"&gt;"autogroup:member"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="tailscale app connector acl" src="https://avilpage.com/images/tailscale-app-connector-acl.png"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;tailscale&lt;span class="w"&gt; &lt;/span&gt;up&lt;span class="w"&gt; &lt;/span&gt;--advertise-tags&lt;span class="o"&gt;=&lt;/span&gt;tag:home-connector&lt;span class="w"&gt; &lt;/span&gt;--accept-routes
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Enable IP forwarding on the machine. If your Linux system has a &lt;code&gt;/etc/sysctl.d&lt;/code&gt; directory, run&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'net.ipv4.ip_forward = 1'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;tee&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;/etc/sysctl.d/99-tailscale.conf
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'net.ipv6.conf.all.forwarding = 1'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;tee&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;/etc/sysctl.d/99-tailscale.conf
sudo&lt;span class="w"&gt; &lt;/span&gt;sysctl&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;/etc/sysctl.d/99-tailscale.conf
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Otherwise, run&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;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
&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;From the Tailscale admin console, create a new app connector.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="tailscale app connector" src="https://avilpage.com/images/tailscale-app-connector.png"&gt;&lt;/p&gt;
&lt;p&gt;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 &lt;code&gt;ip.me&lt;/code&gt; domain so that we can verify if the traffic is routed through the connector.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;From the "Machines" page, select the device and approve the requested subnets.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="tailscale app connector subnet" src="https://avilpage.com/images/tailscale-app-connector-subnet.png"&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;img alt="tailscale app connector verify" src="https://avilpage.com/images/tailscale-app-connector-verify.png"&gt;&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;</description><category>networking</category><category>tailscale</category><guid>https://avilpage.com/2025/11/tailscale-app-connectors-quick-setup.html</guid><pubDate>Sat, 22 Nov 2025 12:48:18 GMT</pubDate></item><item><title>TailScale - Use Exit Node for Specific Websites only</title><link>https://avilpage.com/2025/10/tailscale-exit-node-specific-domains.html</link><dc:creator>Anand Reddy Pandikunta</dc:creator><description>&lt;h4&gt;Problem&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://avilpage.com/tags/tailscale.html"&gt;Tailscale&lt;/a&gt;&lt;sup id="fnref:tailscale"&gt;&lt;a class="footnote-ref" href="https://avilpage.com/2025/10/tailscale-exit-node-specific-domains.html#fn:tailscale"&gt;1&lt;/a&gt;&lt;/sup&gt; provides zero-config mesh VPN built on top of Wiregaurd.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Tailscale Exit Node Option" src="https://avilpage.com/images/tailscale-exit-node-option.png"&gt;&lt;/p&gt;
&lt;h4&gt;Solution&lt;/h4&gt;
&lt;p&gt;Setup a SOCKS proxy using &lt;code&gt;ssh&lt;/code&gt; command line tool.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;ssh&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1080&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;-C&lt;span class="w"&gt; &lt;/span&gt;-q&lt;span class="w"&gt; &lt;/span&gt;-N&lt;span class="w"&gt; &lt;/span&gt;user@exit-node-ip
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;-D 1080&lt;/code&gt; : Specifies the local port to listen on for SOCKS connections.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-f&lt;/code&gt; : Requests ssh to go to background just before command execution.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-C&lt;/code&gt; : Enables compression.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-q&lt;/code&gt; : Quiet mode.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-N&lt;/code&gt; : Do not execute remote commands.&lt;/p&gt;
&lt;p&gt;Once it is started, we can use &lt;a href="https://github.com/zero-peak/ZeroOmega"&gt;ZeroOmega&lt;/a&gt;&lt;sup id="fnref:zeroomega"&gt;&lt;a class="footnote-ref" href="https://avilpage.com/2025/10/tailscale-exit-node-specific-domains.html#fn:zeroomega"&gt;2&lt;/a&gt;&lt;/sup&gt; browser extension to route specific domains through the SOCKS proxy.&lt;/p&gt;
&lt;p&gt;&lt;img alt="ZeroOmega Config" src="https://avilpage.com/images/zeroomega-config.png"&gt;&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;auto switch&lt;/code&gt; profile, we can setup specific domains which needs to be directed to the proxy. 
For all other domains, it will use the direct connection.&lt;/p&gt;
&lt;p&gt;This works only for the browser where the extension is installed.&lt;/p&gt;
&lt;p&gt;To apply this at the system level, we can use &lt;code&gt;pac&lt;/code&gt; file and update the system proxy settings to use the &lt;code&gt;pac&lt;/code&gt; file.&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;Tailscale provides app connector feature to route specific apps through the exit node, but it is needs publicly reachable IPs &amp;amp; Linux based OS for now.&lt;/p&gt;
&lt;p&gt;Setting up SOCKS proxy &amp;amp; using a browser extension or PAC file is much easy &amp;amp; straight forward solution to route specific domains through Tailscale exit node.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:tailscale"&gt;
&lt;p&gt;&lt;a href="https://tailscale.com"&gt;https://tailscale.com&lt;/a&gt; &lt;a class="footnote-backref" href="https://avilpage.com/2025/10/tailscale-exit-node-specific-domains.html#fnref:tailscale" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:zeroomega"&gt;
&lt;p&gt;&lt;a href="https://github.com/zero-peak/ZeroOmega"&gt;https://github.com/zero-peak/ZeroOmega&lt;/a&gt; &lt;a class="footnote-backref" href="https://avilpage.com/2025/10/tailscale-exit-node-specific-domains.html#fnref:zeroomega" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><category>how-to</category><category>tailscale</category><guid>https://avilpage.com/2025/10/tailscale-exit-node-specific-domains.html</guid><pubDate>Wed, 22 Oct 2025 22:20:58 GMT</pubDate></item><item><title>MacBook - Natural Scrolling for Mouse</title><link>https://avilpage.com/2025/09/macbook-natural-scrolling-mouse.html</link><dc:creator>Anand Reddy Pandikunta</dc:creator><description>&lt;h4&gt;Problem&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;img alt="macos mouse settings" src="https://avilpage.com/images/macos-mouse-natural-scrolling00.png"&gt;&lt;/p&gt;
&lt;h4&gt;Solution&lt;/h4&gt;
&lt;p&gt;To have natural scrolling for both trackpad and mouse, we can use third-party tools like 
&lt;a href="https://github.com/ther0n/UnnaturalScrollWheels"&gt;UnnaturalScrollWheels&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If we already use &lt;a href="https://karabiner-elements.pqrs.org/"&gt;Karabiner-Elements&lt;/a&gt;, we can use it to set natural scrolling for mouse separately.&lt;/p&gt;
&lt;p&gt;Open Karabiner-Elements and go to the "Devices" tab, select your mouse, and click on "Open mouse settings".&lt;/p&gt;
&lt;p&gt;&lt;img alt="Karabiner-Elements Devices Tab" src="https://avilpage.com/images/macos-mouse-natural-scrolling11.png"&gt;&lt;/p&gt;
&lt;p&gt;In the mouse settings, check the "Flip mouse vertical wheel" option.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Karabiner-Elements Devices Tab" src="https://avilpage.com/images/macos-mouse-natural-scrolling22.png"&gt;&lt;/p&gt;
&lt;p&gt;Now, both trackpad and mouse will have natural scrolling.&lt;/p&gt;</description><category>how-to</category><category>macbook</category><guid>https://avilpage.com/2025/09/macbook-natural-scrolling-mouse.html</guid><pubDate>Tue, 30 Sep 2025 18:20:58 GMT</pubDate></item><item><title>Mutual Funds - Behind the scenes</title><link>https://avilpage.com/2025/08/mutual-funds-behind-the-scenes.html</link><dc:creator>Anand Reddy Pandikunta</dc:creator><description>&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;Structure of a Mutual Fund&lt;/h4&gt;
&lt;p&gt;&lt;img alt="Mutual Fund Structure" src="https://avilpage.com/images/mutual-fund-structure.png"&gt;&lt;/p&gt;
&lt;p&gt;In India, mutual funds have 3-tier structure consisting of the Sponsor, the Trust &amp;amp; the Asset Management Company (AMC). &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The sponsor establishes the mutual fund and is responsible for its operations. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The trust &amp;amp; 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.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AMC is the core entity responsible for the day-to-day management of the mutual fund. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The legal seperation of Trust &amp;amp; AMC ensures that the interests of investors are protected, and the fund's assets are managed independently.&lt;/p&gt;
&lt;p&gt;All AMCs are registered with the Securities and Exchange Board of India (SEBI) and the list is available on the &lt;a href="https://avilpage.com/2025/08/mutual-funds-behind-the-scenes.html"&gt;SEBI website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We can look at SBI MF details from AMFI to understand the structure better.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Mutual Fund Structure" src="https://avilpage.com/images/mutual-fund-structure2.png"&gt;&lt;/p&gt;
&lt;h4&gt;Mutual Fund Transactions&lt;/h4&gt;
&lt;p&gt;&lt;img alt="Mutual Fund Transactions" src="https://avilpage.com/images/mutual-fund-transaction.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RIA&lt;/strong&gt;: 
Investors can use RIA (Registered Investment Advisor) platforms like &lt;a href="https://groww.in/"&gt;Groww&lt;/a&gt;, &lt;a href="https://coin.zerodha.com/"&gt;Zerodha Coin&lt;/a&gt;, to invest in direct mutual funds.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MFD&lt;/strong&gt;
Alternatively, they can also buy regular mutual funds through distributors like NJWealth, PhonePhe etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TEP&lt;/strong&gt;:
To process these transactions, Trading &amp;amp; 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.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RTA&lt;/strong&gt;:
RTA(Registrar and Transfer Agent) plays a crucial role in maintaining investor records, processing transactions, and ensuring compliance with regulatory requirements.&lt;/p&gt;
&lt;p&gt;Investors can also buy mutual funds directly from the fund house's website or through their mobile app.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;This post provided a brief overview of the behind-the-scenes operations of mutual funds in India.&lt;/p&gt;</description><category>finance</category><category>investing</category><guid>https://avilpage.com/2025/08/mutual-funds-behind-the-scenes.html</guid><pubDate>Tue, 19 Aug 2025 02:32:52 GMT</pubDate></item><item><title>Setup Raspberry Pi without Monitor &amp; Keyboard</title><link>https://avilpage.com/2025/07/setup-raspberry-pi-without-monitor-keyboard.html</link><dc:creator>Anand Reddy Pandikunta</dc:creator><description>&lt;h4&gt;Requirements&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Raspberry Pi (any model)&lt;/li&gt;
&lt;li&gt;MicroSD card (8GB or larger)&lt;/li&gt;
&lt;li&gt;Power supply&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Setup&lt;/h4&gt;
&lt;p&gt;Download &amp;amp; install Raspberry Pi Imager from &lt;a href="https://www.raspberrypi.com/software/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="![Raspberry Pi Imager]" src="https://avilpage.com/images/rpi-setup0.png"&gt;&lt;/p&gt;
&lt;p&gt;After installation, connect SD Card to Computer, and start installation process.&lt;/p&gt;
&lt;p&gt;In the config step, setup WiFi credentials and enable ssh server as well.&lt;/p&gt;
&lt;p&gt;&lt;img alt="![Raspberry Pi Imager]" src="https://avilpage.com/images/rpi-setup.png"&gt;&lt;/p&gt;
&lt;p&gt;Once the installation is complete, insert the SD card into the Raspberry Pi and power it on.&lt;/p&gt;
&lt;h4&gt;Find the IP Address&lt;/h4&gt;
&lt;p&gt;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 &lt;code&gt;nmap&lt;/code&gt; or &lt;code&gt;arp&lt;/code&gt;.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;arp&lt;span class="w"&gt; &lt;/span&gt;-an

&lt;span class="c1"&gt;# or using nmap&lt;/span&gt;
nmap&lt;span class="w"&gt; &lt;/span&gt;-sn
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once you have the IP address, you can SSH into the Raspberry Pi.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;ssh&lt;span class="w"&gt; &lt;/span&gt;pi@&amp;lt;IP_ADDRESS&amp;gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;</description><category>headless</category><category>raspberry_pi</category><guid>https://avilpage.com/2025/07/setup-raspberry-pi-without-monitor-keyboard.html</guid><pubDate>Thu, 31 Jul 2025 03:50:56 GMT</pubDate></item><item><title>Raycast replaced 10 macOS apps</title><link>https://avilpage.com/2025/06/raycast-replaced-10-macos-apps.html</link><dc:creator>Anand Reddy Pandikunta</dc:creator><description>&lt;p&gt;Since I started using Raycast, I have replaced many macOS apps with it. 
Here is a list of those apps and their Raycast equivalents.&lt;/p&gt;
&lt;h4&gt;Espanso&lt;/h4&gt;
&lt;p&gt;Instead of using Espanso for text expansion, I now use Raycast's built-in text snippets feature.&lt;/p&gt;
&lt;h4&gt;Hotkey&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;Fly Cut&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;FinderGO&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;Rectangle&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;Textbar&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;Caffenate&lt;/h4&gt;
&lt;p&gt;To prevent my Mac from sleeping, instead of using Caffenate, I now use Raycast's built-in "Caffeinate" command to keep my Mac awake.&lt;/p&gt;
&lt;h4&gt;Calculator&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;Hammer Spoon (partially)&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;Terminal (partially)&lt;/h4&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;With Raycast, I have been able to streamline my workflow by replacing multiple macOS apps with its powerful features.&lt;/p&gt;</description><category>macbook</category><category>productivity</category><guid>https://avilpage.com/2025/06/raycast-replaced-10-macos-apps.html</guid><pubDate>Mon, 30 Jun 2025 15:51:21 GMT</pubDate></item></channel></rss>