Start with the public service in a few commands, or bring inlet to your own server and manage it yourself.
Scroll for more sections →
01
Use inlet
Install the client, create a token, and give your local app a public URL. The public demo supports GitHub login and open signup.
Install the client
On macOS or Linux, install with Homebrew or curl. Choose a method:
brew install ynui/tap/inlet
Manual download & Windows: Standalone binaries for Windows (amd64), macOS (amd64/arm64), and Linux (amd64/arm64). Extract the archive and place inlet on your PATH.
Start your app first. Replace 3000 with the port your app listens on.
inlet login
inlet http 3000
Use inlet login to link device tokens to GitHub. It opens a browser for approval, then returns to the terminal and saves an inlet token and server URL locally. Use inlet signup for an open token under the server’s per-IP limit. The client prints the public link; share it to let someone reach your app. Press Ctrl-C to stop the tunnel. Inlet does not save your GitHub access token.
Using a private inlet server? Ask its operator for an invite, then run inlet signup --server https://inlet.example.com --invite <invite-code>. The URL is saved with your token; https:// is converted to the secure WebSocket connection automatically.
Client commands
Setup and checks
inlet config showShow the saved server, token status, and inspector port (from ~/.config/inlet/config.json).
inlet config set-server https://inlet.example.comSwitch servers. Use https:// for a TLS site or http://localhost:8080 for local development.
inlet versionShow the installed client version.
inlet doctor [--port 3000]Check the configured inlet server and, optionally, your local app.
Sign in and tokens
inlet login [--server URL] [--label NAME] [--no-browser]Sign in with GitHub and create an account-linked token for this client.
inlet signup [--server URL] [--invite CODE]Create an open-signup token or claim a one-time invite code.
inlet auth <token>Save an existing client token supplied by the server operator.
inlet token listSee and manage tokens for your GitHub account (or signup IP).
inlet token label <prefix> "work laptop"Name a token so it is easier to recognize in the list. Clear with "".
inlet token revoke <prefix>Revoke a token. It cannot open new connections after revocation.
Run a tunnel
inlet http 3000Start a tunnel to a local port. Flags may appear before or after the port.
inlet http 3000 --new-urlRotate the 12-character tunnel ID and get a new public link.
inlet http 3000 --inspect 4041Choose another local inspector port. The default is 4040.
The inspector at http://127.0.0.1:4040 keeps the last 200 requests and is only available locally on loopback. Public URLs route to https://<domain>/<tunnel-id>/.... Inlet forwards HTTP only; WebSocket upgrades from your public app URL are not supported.
Troubleshooting
Start with inlet doctor --port 3000. It checks the configured server and your local app.
The public link does not load. Confirm your app is running on the port you passed to inlet http, and that the tunnel is still running. Ctrl-C stops it.
Connection or token errors. Run inlet config show to check the saved server and token status. A revoked token cannot open new connections; run inlet login again, or inlet auth <token> with a token from the operator.
The browser does not open during login. Run inlet login --no-browser and finish approval in any browser.
See what your app received. Open the inspector at http://127.0.0.1:4040. If that port is taken, choose another with --inspect.
WebSocket features fail through the public URL. Inlet forwards HTTP only; WebSocket upgrades from the public app URL are not supported.
Run one server behind your domain and TLS proxy. Clients and public requests share one inlet port.
1. Prepare the server
Point a DNS name such as inlet.example.com at your server. Install Docker with the Compose plugin, then clone inlet and set the public URL in its environment file.
git clone https://github.com/ynui/inlet.git
cd inlet
cp .env.example .env
Set INLET_PUBLIC_BASE to the HTTPS address users will open. To offer GitHub login, create a GitHub OAuth App, enable Device Flow, and set both GitHub credentials.
Set INLET_OPEN_SIGNUP=true to let anyone create an account. When it is false, only invited users can sign up; existing users can still add tokens. Otherwise, keep signup invite-only. Create a strong admin secret with openssl rand -hex 32 and put its output in INLET_ADMIN_TOKEN.
Keep the database. Compose stores it in ./data/inlet.db by default; set INLET_DB to a Postgres or MySQL URL to use an external database instead. Back up wherever the data lives — it contains token and invite records. Keep .env private and out of Git.
Prefer not to use Docker? Download the inletd archive from Releases, or build from source: install Go 1.23+, clone the repository, run make build, then start ./inletd. Put server settings in .env or export the matching INLET_* variables before starting it.
Server environment variables
Configuration precedence: startup defaults → ~/.config/inlet/server.json → CLI flags → environment variables. Remote setting changes made with inlet admin persist in the database and take precedence thereafter.
INLET_PUBLIC_BASEPublic base URL advertised to clients (e.g. https://inlet.example.com).
INLET_OPEN_SIGNUPAllow token creation without an invite (true or false, default false).
INLET_ADMIN_TOKENSecret to bootstrap remote operator administration; stored hashed in the database.
INLET_CONTROL_ADDROptional separate listener for control and signup (default: shares INLET_BIND).
INLET_GITHUB_CLIENT_IDGitHub OAuth App client ID with Device Flow enabled.
INLET_GITHUB_CLIENT_SECRETGitHub OAuth App client secret for token verification.
INLET_ACCESS_LOGLog request method, tunnel ID, status, and duration (default false).
INLET_DBDatabase DSN/path (default ./data/inlet.db). SQLite path, or sqlite://, postgres:///postgresql://, or mysql:// URL.
INLET_STALE_AFTERDelete inactive invite/admin tokens after this period (default 720h / 30d).
INLET_OPEN_STALE_AFTERDelete inactive open-signup tokens after this period (default 168h / 7d).
INLET_REVOKED_RETENTIONKeep revoked tokens before purging (default 168h / 7d).
INLET_INVITE_TTLDefault lifetime for new invites (default 24h).
2. Put HTTPS in front
Terminate TLS at Nginx and forward every path to inlet's listener. Add the map once inside Nginx's http block; put the server block in your site config. Replace the hostname, certificate paths, and upstream for your deployment.
If Nginx is on the host, set its upstream to the published inlet port and restrict direct access to that port with your firewall. If Nginx shares inlet's Compose network, use proxy_pass http://inletd:8080; and remove the host ports mapping. Inlet needs WebSocket upgrade headers for its client control connection.
3. Invite clients and administer the server
With INLET_ADMIN_TOKEN set and the server running, connect from your workstation with inlet admin.
Send the one-time invite code to the client. They claim it with inlet signup --server https://inlet.example.com --invite <invite-code>; the client saves the token and server URL.
Remote administration uses HTTPS and a separate admin token. The bootstrap token appears as admin-token in token lists. Never share it with regular clients.
Admin command reference
Run from your workstation with inlet admin. Credentials are saved separately in ~/.config/inlet/admin.json and never touch client configs. Remote commands require HTTPS (or loopback in development).
Authentication and configuration
inlet admin auth --server https://inlet.example.com <admin-token>Save an operator admin token and target server URL.
inlet admin config showShow the configured server, admin token status, and remote open-signup status.
inlet admin config set-server https://inlet.example.comChange the remote server used by the admin CLI.
inlet admin config set open-signup <true|false>Enable or disable open signup remotely. Setting is persisted in the database.
inlet admin versionShow the installed admin CLI version.
Invites
inlet admin invite create [--ttl 24h] [--label NAME]Create a single-use invite code. The code is shown once.
Tokens
inlet admin token list [--limit 50] [--offset 0]View token metadata in pages. Maximum page size is 200.
inlet admin token create [--label NAME]Create a regular client token directly. Its secret is shown only once.
inlet admin token label <prefix> "NAME"Rename a token shown by token list. Clear with "".
inlet admin token revoke <prefix> [<prefix> ...]Revoke one or more token prefixes in a single transaction (up to 100).
Local server commands
Run these inside the server container or from the working directory containing its database (default ./data/inlet.db). With Docker Compose, prefix each command with docker compose exec inletd.
inletd doctorCheck the running server health endpoint (/_inlet/healthz).
inletd invite [create] [--ttl 24h] [--label NAME]Create a one-time invite code for a client.
inletd token create [--label NAME]Issue an active client token straight to the database; printed once.
inletd token listList token prefixes, labels, tunnel IDs, last used time, and state.
inletd token revoke <prefix>Revoke a token directly in the server database.
To update, pull the latest source and run docker compose up -d --build. For configuration options and the full proxy example, see the deployment guide on GitHub.