Reintroducing Serve and Funnel: even simpler sharing with your tailnet (or the world!)

Sam Linville and Parker Higgins on
Photo of Sam Linville
Photo of Parker Higgins

Tailscale Serve and Funnel aren’t new features, but today, we’re enhancing their user experience based on insights from how users actually interact with them. Not to get too philosophical, but the most useful features are the features you actually use, and we hope that today’s relaunch of Serve and Funnel moves them closer to the top of our users’ toolkits.

Bottom line up front: In Tailscale 1.52 or later, Funnel is now a single command, and in most cases, sharing a local port is as easy as tailscale funnel 3000.

But wait, wait, wait. Let’s back up. What are Tailscale Serve and Funnel, anyways? Read on for more background and info on today’s changes.

Tailscale Funnel lets you expose a local service, file, or directory to the entire internet. You can use it to host a website on a Raspberry Pi, test your local webhook development project, or share the web app you’re developing on your laptop with the world. Learn more about how Funnel works behind the scenes.

Tailscale Serve is a lot like Funnel, but instead of serving content to the entire internet, it’s only accessible to other devices and people in your tailnet. If you want to share a service or a directory or a page with all of your machines and the members of your team, no matter where they are in the world, Serve can help you do so privately and securely. You can use it to set up a reverse proxy for containers and VMs in your homelab, to share an API server you’re developing with a coworker, or to quickly open a directory from your laptop on your phone. And of course, you can regulate access to shared resources within your tailnet using your ACLs. Learn more about Tailscale Serve.

Serve and Funnel are really powerful tools, and you can find even more ways to use them in our docs:

Okay, so what’s changing?

The most common way that you use Serve and Funnel can now be expressed in one short command:

tailscale funnel 3000 // share port 3000 with the internet
tailscale serve 3000 // share port 3000 with your tailnet

These simple commands make http://localhost:3000 available to the internet or your tailnet at your-computer.pango-lin.ts.net over HTTPS. It’s great for sharing your local development server or setting up an easy URL for a service in your homelab.

When you run these commands, they’ll start a foreground session by default, which ends when you press Ctrl+C or quit the terminal session. If you want to persist the configuration even when the terminal session is over, add the --bg flag:

tailscale funnel --bg 3000
tailscale serve --bg 3000

Even though we’ve made the most common use for Serve and Funnel easier, we’ve retained all of the more advanced features that we know are key to so many of your workflows.

# Serve a file, directory, or plain text:

$ tailscale serve /path/to/file.html
$ tailscale funnel /path/to/directory
$ tailscale serve text:"hello from tailscale"

# Start an HTTPS reverse proxy to port 3000

$ tailscale serve 3000
$ tailscale funnel localhost:3000
$ tailscale serve http://localhost:3000
$ tailscale funnel http://127.0.0.1:3000

# The same, but at a path

$ tailscale serve localhost:3000/foo
$ tailscale funnel http://localhost:3000/foo
$ tailscale serve http://127.0.0.1:3000/foo

# The same, but listen on alternate port 8443

$ tailscale serve --https=8443 3000
$ tailscale funnel --https=8443 3000

# Run Funnel or Serve in the background

$ tailscale serve --bg 3000
$ taiscale funnel --bg 3000

# Specify a multiple mount point- all of these can be active at the same time

$ tailscale serve --set-path=/ --bg 3000
$ tailscale funnel --set-path=/foo --bg localhost:5000
$ tailscale serve --set-path=/bar --bg /path/to/file.html

# Ignore an invalid or self-signed certificate

$ tailscale serve https+insecure://localhost:5454
$ tailscale funnel https+insecure://localhost:5454

# Forward incoming TCP connections on port 10000 to a local TCP server on port 22
# (eg.g to run OpenSSH in parallel with Tailscale SSH):

$ tailscale serve --tcp=2222 22
$ tailscale serve --tcp=2222 tcp://localhost:22

What’s behind these changes

The previous method for using Funnel—a two-step command—reflected the underlying infrastructure, but we saw room for improvement. After seeing Serve and Funnel out in the wild, we’ve adjusted the commands to be more aligned with how you use our tools. We hope that the new Serve and Funnel experience will be more intuitive and tailored to your needs.

As we had conversations with the community, used these tools ourselves internally, and studied the most common questions we got about Funnel, we realized a few things.

We put together the new syntax for these tools to make these most common use cases easier to get right quickly. But if you’ve gotten used to the old syntax, we’ve got you covered—enter the old CLI command, and we’ll translate it to the new syntax and print that out for you. We hope this makes the transition seamless.

To see the full command syntax definition, run tailscale funnel --help or tailscale serve --help in the CLI, or visit our CLI documentation.

If you’re already a regular user of Serve and Funnel, or if this post gives you a nudge to check them out for the first time, we would love to hear your feedback—that’s what powered these updates in the first place.

Share via

Subscribe for monthly updates

Product updates, blog posts, company news, and more.

Too much email? RSS Twitter