# Keep It Local

> Source: <https://www.olafalders.com/2026/06/30/keep-it-local/>
> Published: 2026-06-30 00:00:00+00:00

Who wants to talk about networking today? I know I do. Two
addresses do most of the heavy lifting here: `127.0.0.1`

(aka *localhost* or the
*loopback* address — only your own machine can reach it) and `0.0.0.0`

(bind to
this and you’re reachable on *every* network interface). See
[Localhost](https://en.wikipedia.org/wiki/Localhost) and
[0.0.0.0](https://en.wikipedia.org/wiki/0.0.0.0#Binding) for a refresher.

## clodhopper[#](#clodhopper)

Yesterday I talked about [clodhopper](/2026/06/29/on-hopping-claudes/), my
personal Claude Code dashboard. It collects data from your running agents and
spins up a read-only app to show their status. By default, it
binds to localhost (`127.0.0.1`

), which means I don’t accidentally broadcast my
workflows to the world. I also run it on my Tailscale network, which means I can view it on my
own private network, but the world can’t. I was doing this by interpolating the
Tailscale IP in the startup command: `clodhopper serve --host "$(tailscale ip -4)"`

. Today I added a `--tailscale`

arg, to make this a touch easier.

```
# Default: loopback only — only this machine can reach it
clodhopper serve

# Don't do this on an untrusted network — binds every interface
CLODHOPPER_HOST=0.0.0.0 clodhopper serve

# Tailnet only — reachable from your tailnet (subject to ACLs), not the LAN
clodhopper serve --tailscale
```

So, that’s all fine, but we are now living in a world where anyone can spin up a custom app on their machine and accidentally broadcast it to the world. Is this bad? Not always, but consider the following:

- your app keeps secrets in
`.env`

- your app spins up a web server
`.env`

somehow ends up in the path that your app is serving- random bot sniffs out your app and fetches
`.env`

- now you need to rotate your secrets and you may not even be aware that your secrets are in the hands of a bad actor

"[Localhost](https://www.flickr.com/photos/10768314@N00/4823138926)" by [Wesley Nitsckie](https://www.flickr.com/photos/nitsckie/) is licensed under [CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/).

Ideally you’d restrict access to your resources to only the audiences which
require them. So, defaulting to `localhost`

and then expanding your reach from
there is a good way to go. In my case I’ve been enjoying using a
[Tailscale](https://tailscale.com/) tailnet. Only my own authenticated devices
can connect. Internet creeping will have to take place elsewhere, because my
apps are now for my eyes only.

Moving beyond `clodhopper`

, here are ways to apply the same principle to some open source apps.

## air[#](#air)

[air](https://github.com/air-verse/air)runs`full_bin`

through a shell, so you can interpolate`tailscale ip -4`

straight into your app’s host flag in`.air.toml`

— no hardcoded address:

```
[build]
# Loopback only
full_bin = "./tmp/main -port 5003 -host 127.0.0.1"

# Tailnet only — resolved at startup, no hardcoded address
full_bin = "./tmp/main -port 5003 -host $(tailscale ip -4)"
```

## Python’s built-in file server[#](#pythons-built-in-file-server)

`http.server`

binds`0.0.0.0`

by default — pass an explicit`--bind`

.

```
# Default binds 0.0.0.0 (all interfaces)
python3 -m http.server 5000

# Loopback only
python3 -m http.server 5000 --bind 127.0.0.1

# Tailnet only
python3 -m http.server 5000 --bind "$(tailscale ip -4)"
```

## App::HTTPThis[#](#apphttpthis)

[App::HTTPThis](https://metacpan.org/dist/App-HTTPThis/view/bin/http_this)serves the current directory over HTTP.- Use
`--host`

to control the bind address.

```
# Loopback only
http_this --host 127.0.0.1

# Tailnet only
http_this --host "$(tailscale ip -4)"
```

*nota bene*: the current version of `http_this`

binds to *every* interface
but emits a message that implies that it is binding *only* to `127.0.0.1`

.

``` bash
$ http_this .
Exporting '.', available at:
   http://127.0.0.1:7007/
```

😬 Today I opened [#13](https://github.com/davorg-cpan/app-httpthis/pull/13) to
clarify the behaviour, but maybe take this as a reminder that it’s good to be
explicit about the things that really matter, rather than relying on the
defaults.
