funnel
getting started

basic usage

a step-by-step guide to get your first tunnel running.

complete example

this guide walks you through creating your first tunnel, from starting a local service to accessing it from anywhere on the internet.

prerequisites

🌐 local service

a web service running on your machine (we'll use localhost:3000)

🔧 funnel client

the funnel client binary installed on your machine

🐳 docker

docker installed to run the server

configuration (optional)

for convenience, you can set up configuration files to save server endpoints. this allows you to use funnel http 3000 instead of specifying the full server URL each time.

client authentication

for client authentication, currently there is none. what i recommend is throwing a uuid at a subdomain and hoping it sticks like spaghetti on the wall. well yea funnel uses letsencrypt for the domain, so crt.sh indexes it faster than i can say "oops i committed my api keys again".

some buzzkills would call this a "security nightmare". some would say it's like using tissues as a bulletproof vest. but hey, at least it's documented now! that's basically the same as fixing it, right?

well yea it is a little unoptimal

but honestly at this point security is just performance art. we're all just improvising until someone gets pwned.

start a local service

first, you need a local web service to expose. if you don't have one, you can start a simple python web server.

test server

this python server will serve the current directory on port 3000, perfect for testing your tunnel.

# this will serve the current directory on port 3000
python3 -m http.server 3000

you should see output like:

Serving HTTP on 0.0.0.0 port 3000 (http://0.0.0.0:3000/) ...

start the funnel server

next, start the funnel server using docker. this is the remote component that will listen for public traffic.

server component

the server acts as a bridge between public internet traffic and your local client. it runs independently and can serve multiple clients.

# starts the server on the default port 8080
docker run -d --name funnel-server -p 8080:8080 ghcr.io/karol-broda/funnel-server:latest

verify the server is running:

docker logs funnel-server

you should see logs indicating the server is listening on port 8080.

(optional) set up configuration

for convenience, you can create a configuration file to save your server settings. this allows you to use shorter commands in the future.

manual setup required

you must create the configuration file manually. the client will not create a default config automatically.

create a config file at ~/.config/funnel/config.toml with this structure:

[inlets.default]
server = "http://localhost:8080"
domain = "localhost:8080"

you can add more inlets for different environments:

[inlets.default]
server = "http://localhost:8080"
domain = "localhost:8080"

[inlets.production]
server = "https://api.tunneling.dev"
domain = "tunneling.dev"

connect the funnel client

now, connect your local service to the server. this command tells the funnel client to connect to your remote server and forward traffic to your local service on port 3000.

custom subdomain

we're using the custom subdomain demo for this example. you can choose any available subdomain name.

# connect to the server, forwarding to localhost:3000
funnel http 3000 --server http://localhost:8080 --id demo

with configuration

if you set up configuration, you can use the shorter command:

funnel http 3000 --id demo

you should see output similar to:

✓ Connected to server
✓ Tunnel active: http://demo.localhost:8080
✓ Forwarding to localhost:3000

access your service

success!

your local service is now exposed to the world! you can access it from any device with internet connectivity.

test your tunnel:

curl http://demo.localhost:8080

you should see the response from your local python web server. the request flow is:

  1. curlfunnel serverwebsocketfunnel clientlocalhost:3000
  2. localhost:3000funnel clientwebsocketfunnel servercurl

what's next?

congratulations!

you've successfully created your first tunnel! for production use, consider deploying your own server with TLS enabled.

Last updated: August 25, 2025
by karol-broda