25 min read

Self-Host Streamlit with Remote Access via Localtonet

Install and verify a Streamlit dashboard locally, then make it remotely accessible through a Localtonet HTTP tunnel.

A locally hosted Streamlit dashboard reaching a remote phone through an HTTP tunnel.
Localtonet routes remote browser requests to the Streamlit app running on the host computer.
Tutorials · Streamlit · Localtonet · 2026

Build a Python data app locally, verify it, and provide controlled remote access

Streamlit turns Python scripts into interactive web applications without requiring a separate frontend. In this guide, we install Streamlit, validate the installation with its included example, create a small dashboard, and confirm that the application works locally. We then connect the verified local service to a Localtonet HTTP tunnel so authorized users can reach it remotely without inbound router port forwarding, firewall changes, VPN setup, or a public IP address. The workflow deliberately uses the hostname and port reported by Streamlit at runtime instead of assuming network defaults.

🔒 Verify locally before creating public access 🌐 Publish the app through an HTTP tunnel ⚡ Keep development and remote access as separate steps

How Streamlit self-hosting and remote access fit together

Remote browser traffic traveling through a Localtonet HTTP tunnel to Streamlit on localhost.
The public endpoint forwards HTTP traffic through the tunnel to Streamlit on the private host.

Streamlit is an open-source Python framework for creating interactive data applications. A Streamlit project remains a Python script, but Streamlit renders the script as a browser-based interface. Its components can display text, dataframes, charts, media, forms, and interactive widgets. The framework is especially useful when the people building a dashboard are more comfortable with Python than with a separate frontend stack.

Self-hosting begins with a local process. When you run a Streamlit script, that process starts a web service and prints runtime information in the terminal. A browser on the same computer can open the displayed local address and interact with the app. The Streamlit process must remain running for that page to remain available.

Remote access is a separate networking concern. A dashboard can work perfectly on its host while remaining unreachable from another network. Direct internet exposure commonly requires an inbound router rule, a suitable firewall rule, and a publicly reachable IP address. Those requirements can be unavailable or undesirable on development workstations, home networks, temporary lab machines, and networks behind carrier-grade NAT.

With Localtonet, the client application on the machine that can reach Streamlit establishes an outbound connection to one of our relay servers. An HTTP tunnel then connects a public HTTPS address to the local Streamlit address and port. This avoids opening an inbound router port. The tunnel is available only while the selected Localtonet client is connected, the tunnel is running, and the Streamlit process remains available.

🐍 Python-first application Streamlit lets you define the interface and application behavior in Python, making it suitable for dashboards, reports, prototypes, and interactive data tools.
✅ Local verification first Testing the application directly on its host separates Streamlit installation or code errors from tunnel configuration problems.
🌐 HTTP remote access A Localtonet HTTP tunnel points to the local IP address and port reported by the running Streamlit service.
🔌 Outbound tunnel connection Our client establishes the outbound connection, so the workflow does not require inbound router port forwarding or a public IP address.

Why installation and tunneling should remain separate

Treating installation, application startup, and remote access as distinct stages makes the system easier to understand and troubleshoot. Streamlit is responsible for running the Python application. Localtonet is responsible for carrying remote HTTP traffic to that already running service. A tunnel does not install Streamlit, start the dashboard, repair Python dependencies, or make a failed local application healthy.

The most reliable order is therefore: install Streamlit, launch a known example, create the intended application, verify it locally, note the actual runtime address, and only then configure the HTTP tunnel. If remote access later fails, this order gives you a known-good local baseline.

Use Streamlit's runtime output as the source of truth

Streamlit prints browser-accessible connection information when it starts. This guide does not hardcode a hostname, listening interface, or port because those details can depend on configuration and environment. Copy the local address and port from the terminal session that is running your app.

Prerequisites and deployment decisions

Complete the following preparation before installing the application or opening remote access:

  • A computer on which you are permitted to install and run Python packages.
  • A working Python environment with the pip package installer available.
  • A terminal or command prompt.
  • Permission to create files in a project directory.
  • A browser for local and remote verification.
  • A Localtonet account and a supported Localtonet client installed on the device that will run the tunnel.
  • Permission to expose the intended dashboard and its data to approved remote users.

The supplied Streamlit installation instructions use pip install streamlit. Streamlit's installation documentation should be consulted if your Python environment requires a platform-specific installation path. This guide does not prescribe a Python version because the supplied evidence does not establish a version range, and compatibility requirements can change between releases.

Choose the correct Localtonet client device

Install and run our client on the Streamlit host or another device that can reach the Streamlit service over the local network. If the client and Streamlit run on the same computer, the local target can use the address reported by Streamlit for that host. If they run on different computers, the target must be an address that is reachable from the Localtonet client device.

Do not assume that a loopback or host-local address will work from a different machine. An address that means “this computer” always refers to the computer making the connection. When our client runs elsewhere, verify the Streamlit service from that client device before building the tunnel.

Decide what the remote audience should see

Review the application before exposure. A development dashboard may reveal data samples, filenames, exception details, model outputs, internal metrics, upload controls, or actions that were harmless while access was limited to the local computer. Once the app has a public address, anyone who obtains that address may be able to send requests unless an appropriate access-control layer protects it.

Remote connectivity and application authorization are different controls. The tunnel transports requests to Streamlit. It does not automatically redesign the application, classify its data, or determine which Streamlit actions a visitor should be allowed to use. Plan authentication and authorization according to the app's contents and your organization's policies.

Component Responsibility What to verify
Python environment Runs Streamlit and the dashboard code Python and pip operate in the intended environment
Streamlit process Serves the interactive web application The runtime output appears and the app opens locally
Dashboard script Defines widgets, calculations, data access, and displayed results The script runs without import or execution errors
Localtonet client Establishes the outbound connection to our relay The intended device is connected using its own token
HTTP tunnel Maps a public HTTPS address to the local Streamlit target The configured local IP address and port match the running app
Application access controls Restrict who can use sensitive functions or view protected data Remote users receive only the access they are authorized to have

Install and validate Streamlit

Start with Streamlit's documented installation sequence. Run the commands in the Python environment intended for the dashboard. If your operating system has multiple Python installations or environments, confirm that pip refers to the environment from which you will later launch Streamlit.

1

Install the Streamlit package

Open a terminal in your intended Python environment and install Streamlit with its documented pip command.

pip install streamlit
2

Launch the included Hello application

Run Streamlit's bundled example to validate the package installation independently of your own application code.

streamlit hello
3

Confirm the example opens

Streamlit should open its Hello application in a browser. If the browser does not open automatically, read the terminal output and manually open the local URL it provides. Interact with the examples to confirm that the application is responsive.

Successful completion of the Hello test establishes that Streamlit can start in the current environment and serve a browser interface. It does not yet verify your project's imports, files, datasets, or application logic. Those are tested in the next stage.

If the Streamlit command is unavailable

A successful package installation followed by a “command not found” or equivalent message often indicates that the installation and execution commands are using different Python environments, or that the environment's executable directory is not available to the shell. Reopen or reactivate the intended environment, confirm that installation completed without errors, and retry from that same environment.

Avoid repeatedly installing into unrelated Python environments. First identify which environment is active and which pip command performed the installation. The exact environment-management commands vary by operating system and tool, so they are not guessed here.

Create and run a small Streamlit dashboard

A Streamlit file, running terminal, and locally rendered dashboard shown together.
The source file, running process, and browser result confirm that the Streamlit app works locally.

After the bundled example works, create a project directory and add a file named streamlit_app.py. This filename follows the official quickstart example, but the important operational requirement is that the filename supplied to the run command matches the file you created.

Add the following minimal application:

import streamlit as st

x = st.slider("Select a value")
st.write(x, "squared is", x * x)

This application demonstrates the central Streamlit programming model. The call to st.slider renders an interactive control and returns its current value to Python. The call to st.write displays the selected value and its square. It requires no manually defined HTTP routes, separate JavaScript bundle, or HTML template.

Save the file, open a terminal in the directory containing it, and run:

streamlit run streamlit_app.py

Keep this terminal open. It hosts the running Streamlit process and displays information that is important for both local verification and the Localtonet configuration. If the command reports that the file cannot be found, inspect the current directory and filename rather than changing the tunnel configuration.

Extend the application only after the baseline works

The small slider app is intentionally simple. Once it runs correctly, you can add the imports, datasets, charts, model calls, upload controls, and other components needed by the real dashboard. Make one coherent change at a time and reload the app after each change. This narrows the cause when a dependency, data source, or code path fails.

Streamlit supports use cases such as dashboards, reports, chat applications, data visualization, science tools, finance applications, and machine learning interfaces. The remote-access architecture remains the same: the final script must run as a reachable local HTTP service before the tunnel can forward traffic to it.

Do not put credentials directly in the example script

A dashboard may need database passwords, service credentials, API keys, or private model endpoints. Do not hardcode those values in source code that may be shared, committed to a repository, displayed in an error, or exposed through application behavior. Use a secret-management approach appropriate for your environment, and never place a Localtonet device token in the Streamlit script.

Verify the complete application locally

Local verification is a required checkpoint, not an optional convenience. If the app does not work through the local URL, adding a public tunnel cannot make it healthy. Complete the following checks while the Streamlit process is running.

  1. Read the terminal output produced by streamlit run streamlit_app.py.
  2. Identify the local browser address shown by Streamlit.
  3. Open that exact address in a browser on the Streamlit host.
  4. Move the slider and confirm that the displayed square changes.
  5. Reload the page and confirm that the app renders again.
  6. Watch the terminal for Python exceptions or request-time errors.

Record the hostname or IP address and the port from the working local URL. These values become the local target for the Localtonet HTTP tunnel. Do not substitute a commonly used port or an address copied from another installation.

Test from the Localtonet client device when it is separate

If our client will run on a different device, perform an additional local-network test from that device. Open the Streamlit address that is intended for the tunnel target and confirm that the dashboard loads. If it cannot be reached from the client device, solve that local reachability issue before creating the tunnel.

A working browser test on the Streamlit host proves only that the host can reach its own service. It does not prove that another device can reach a host-local listening address. The correct listening interface and local network configuration depend on your Streamlit and operating-system setup. Because the supplied Streamlit evidence does not establish an interface configuration command, this guide does not invent one.

Save the exact target, not just the public-facing idea

The tunnel needs a concrete local IP address and port. “The Streamlit dashboard” is not enough information. Use the values confirmed by a successful local connection from the device that will run our client.

Enable remote access with a Localtonet HTTP tunnel

Connected Localtonet console forwarding an HTTP tunnel to Streamlit on port 8501.
A connected HTTP tunnel maps the public URL to the local Streamlit port.

Once the intended Streamlit dashboard is running and locally verified, create an HTTP tunnel in Localtonet. An HTTP tunnel is appropriate because Streamlit presents a browser-based web application. Standard HTTP tunneling is not a VPN. If your goal is a private mesh network or LAN bridging, that is a separate VPN Manager use case.

Our client makes an outbound connection to the selected relay server. You therefore do not need to configure inbound router port forwarding, obtain a public IP address, or set up a VPN merely to expose this application. The public endpoint remains dependent on the Streamlit process, the Localtonet client connection, and the tunnel's running state.

1

Install and run the Localtonet client

Install our client for the operating system on the device that can reach Streamlit. Use the current installation workflow for that platform rather than copying an unverified command. Keep the client running for as long as remote access is required.

2

Authenticate or select the intended device

Use the device-specific Localtonet authentication token associated with the client that will run the tunnel. Treat the token as a secret. Do not paste it into the Streamlit application, publish it in a repository, include it in a screenshot, or share it with remote visitors.

3

Select an available relay server

Choose a currently available server or region from the Localtonet dashboard. Available server codes and regions can change and may vary, so obtain the value from the current product interface rather than using a hardcoded value from an old tutorial.

4

Create an HTTP tunnel to the verified target

Create the HTTP tunnel and enter the local IP address and port taken from the successful Streamlit verification. If Streamlit and our client are on different devices, use the address that was proven reachable from the client device.

5

Start the tunnel

Creating a tunnel does not mean it is running. Use the Start button and confirm that the selected client remains connected. The dashboard will provide the public address assigned to the HTTP tunnel.

6

Test the public address

Open the assigned public HTTPS address in a browser, preferably from a separate network or device. Confirm that the dashboard loads, the slider responds, and the Streamlit terminal does not report an application error. Stop or delete the tunnel when it is no longer needed.

HTTP and File Server tunnels can use a generated subdomain, a selected subdomain where supported, or a custom domain. All of those process types serve content through a public HTTPS address. If you need a custom domain, check the current Localtonet documentation for its DNS requirements before changing records. This guide does not provide guessed DNS values.

For the current product interface and HTTP workflow, use the Localtonet HTTP tunnel documentation alongside the verified local target from this guide.

Validate the tunnel as an end user would

A useful remote test should do more than confirm that the first page appears. Interact with the same widgets and workflows that users will need. If the production dashboard loads data, accepts uploads, invokes a model, or writes changes, test those paths with non-sensitive test data and the permissions intended for the remote audience.

Also test from outside the host's local network. Otherwise, a browser may be reaching a local address or cached page rather than exercising the public path. Keep the Streamlit terminal visible during testing so that you can correlate browser behavior with application errors.

Observed result Likely area Next check
Local URL does not open Streamlit process or Python application Read the Streamlit terminal output and correct the local failure first
Local access works, but the tunnel cannot connect Local target or client reachability Verify the exact IP address and port from the Localtonet client device
Tunnel exists, but the public address is unavailable Tunnel lifecycle or client state Confirm that the tunnel was started and the selected client is connected
Page opens, but an app action fails Application code, data source, or dependency Inspect the Streamlit terminal and reproduce the same action locally
Access stops after a terminal closes Streamlit process lifecycle Restart the app and use an appropriate supervised process strategy for long-running use

Plan safe access before sharing the URL

A public URL changes the risk profile of an application. Even if the link is shared with only a small group, it should not be treated as a substitute for authentication. URLs can appear in browser history, logs, chat messages, screenshots, analytics, and copied documents.

Apply least privilege to the application and its environment. The operating-system account that runs Streamlit should have access only to files, databases, and services required by the dashboard. If the app only reads a dataset, avoid granting write access. If users can upload files or trigger operations, validate inputs and constrain what those operations can affect.

🔐 Protect sensitive functions Use an authentication and authorization design appropriate for the application instead of relying on possession of the public URL.
🗝️ Keep secrets outside source code Do not place database credentials, API keys, Localtonet tokens, or private endpoints in scripts, screenshots, or repositories.
📁 Limit host permissions Run the dashboard with only the filesystem and network permissions required for its intended work.
⏹️ Stop unused exposure Stop or delete the Localtonet tunnel when remote access is no longer required.
Review development behavior before internet exposure

Development applications can reveal exception details or internal information that was never intended for remote users. Test failure paths as well as successful paths, remove unnecessary diagnostics from the user interface, and avoid exposing confidential datasets during initial tunnel validation.

The device token also deserves careful handling. It identifies the client device that runs the tunnel and must not be guessed, embedded in public configuration examples, or sent to users who only need the dashboard URL. If a token may have been exposed, follow the current Localtonet account workflow to replace or revoke it rather than continuing to use it.

Operate and update the self-hosted dashboard

A working test session is not automatically a durable deployment. For continued availability, three components must remain healthy: the Streamlit process, the Localtonet client, and the HTTP tunnel. Restarting the computer, closing the terminal, stopping the client, or stopping the tunnel can interrupt remote access.

Starting the service

Start the Streamlit app from the directory containing its script:

streamlit run streamlit_app.py

Confirm the runtime output, test the local URL, and then verify that our client is connected and the tunnel is running. This short local-first check prevents unnecessary tunnel debugging after a code or dependency change.

Stopping remote access

Stop the HTTP tunnel when the dashboard should no longer be public. You can later start it again if the local target and selected client are still valid. Delete the tunnel if the configuration is no longer needed. Remember that stopping Streamlit also makes the public endpoint unusable, but it does not by itself remove the tunnel configuration from the dashboard.

Updating application code

Make updates in a controlled sequence:

  1. Preserve a known working version of the script and dependency information.
  2. Make the intended code or data change.
  3. Run and test it locally.
  4. Exercise important interactive paths.
  5. Confirm that the local address and port still match the tunnel target.
  6. Test the public address only after local validation passes.

Streamlit supports live editing behavior during development, but a long-running deployment still needs a process-management approach suitable for its operating system. The supplied evidence does not establish one universal service manager, startup path, container configuration, or background command, so this guide does not invent one. Choose a supervised process method that can restart the application and preserve logs according to your host's operational standards.

Monitor the right boundaries

When users report an outage, test each boundary independently. First confirm that the Streamlit process exists. Next test its local URL. Then check whether the Localtonet client is connected. After that, confirm the tunnel is running and test the public address. This sequence identifies the failed layer instead of treating the entire system as one opaque service.

Troubleshoot installation, startup, and remote access

Five checkpoints for diagnosing Streamlit installation, local startup, tunnel status, and remote access.
Testing each layer in order isolates whether a failure is local, tunnel-related, or remote.

The package installation fails

Read the complete pip error rather than only its final line. Confirm that Python and pip are available in the intended environment and that the account has permission to install packages there. Network restrictions, package-index access, platform prerequisites, and Python compatibility can also affect installation. Because those details vary by system, follow the specific diagnostic emitted by pip and the current Streamlit installation guidance instead of applying unrelated commands.

streamlit hello does not open a browser

A browser not opening automatically does not necessarily mean that the Streamlit process failed. Inspect the terminal. If Streamlit reports a local URL and continues running, manually enter that URL in a browser on the same host. If the process exits or displays an exception, resolve that error before moving on.

The app file cannot be found

The command streamlit run streamlit_app.py expects a file with that name in the current directory. Confirm the filename, including its extension, and open the terminal in the project directory. Also check whether an editor silently added another extension to the filename.

The sample works, but the real app fails

This result shows that the base Streamlit installation can run, while something specific to the project is failing. Look for missing Python packages, unavailable files, incorrect relative paths, failed data connections, or exceptions in application code. Reproduce the failing user action locally while watching the terminal.

The app works on its host but not from the client device

This is a local reachability problem. The address used on the Streamlit host may refer only to that host or may not be reachable from another device. Verify the address shown at runtime and the Streamlit listening configuration. Also review local network policy and host firewall rules. Do not create broad firewall exceptions without understanding their effect.

The public endpoint does not work

Confirm all of the following:

  • The Streamlit process is still running.
  • The app still works through its local URL.
  • The Localtonet client is running and connected.
  • The selected device token belongs to the client that can reach Streamlit.
  • The tunnel's local IP address and port match the current Streamlit runtime output.
  • The tunnel was started after it was created.
  • You are testing the public URL assigned to that tunnel.

If the Streamlit process selected a different runtime port after a restart, update the tunnel's target to the new verified value or adjust the application using documented Streamlit configuration appropriate for your environment. This guide does not guess configuration flags that were not established by the supplied evidence.

The page loads, but interaction fails

Test the same action through the local URL. If it fails locally too, investigate the Streamlit application and its dependencies. If it works locally but fails only remotely, confirm that the public request is reaching the intended running process and review any errors printed in the Streamlit terminal. Keep the test minimal and avoid using sensitive data while diagnosing the issue.

The tunnel disconnects unexpectedly

A Localtonet tunnel is available only while the selected client is connected and the tunnel is running. Check whether the client device slept, restarted, lost network connectivity, or stopped the client application. Also verify that the correct tunnel remains in the running state.

Frequently asked questions

What command installs Streamlit?

The documented installation command is pip install streamlit. Run it in the Python environment from which you intend to launch the dashboard. Validate the installation with streamlit hello.

How do I run my own Streamlit application?

Save the application as streamlit_app.py, open a terminal in that file's directory, and run streamlit run streamlit_app.py. If you use another filename, supply that filename instead.

Which port should I enter in the Localtonet tunnel?

Use the port shown by the running Streamlit process and confirmed by a successful local browser test. Do not assume a port from another tutorial because runtime configuration can differ.

Does Localtonet start or host the Streamlit process?

No. Streamlit runs on your selected machine. Our client connects the public HTTP tunnel to that local service. The Streamlit process must remain running and reachable from the client device.

Do I need router port forwarding or a public IP address?

No. The Localtonet client establishes an outbound connection to our relay, so this workflow does not require inbound router port forwarding or a public IP address.

Is an HTTP tunnel the same as a VPN?

No. An HTTP tunnel publishes a specific local web service. Localtonet VPN Manager is the separate feature for private mesh networking and LAN bridging.

Can the Localtonet client run on a different device from Streamlit?

Yes, provided that the client device can reach the Streamlit IP address and port. Test that local-network connection from the client device before configuring the tunnel.

Does creating a tunnel start it automatically?

No. Creating the configuration does not mean the tunnel is running. Use the Start button, and keep the selected client connected. You can later stop or delete the tunnel.

Does the public URL automatically protect a private dashboard?

No. A public URL provides connectivity, not an application-specific authorization design. Protect sensitive data and functions with suitable authentication, authorization, least-privilege permissions, and safe secret handling.

Connect your verified Streamlit app with Localtonet

Install Streamlit, confirm the dashboard through its runtime URL, and then use that exact local IP address and port to create an HTTP tunnel. Keep the application, our client, and the tunnel running only for as long as remote access is required.

Get Started Free →

Localtonet is a secure multi-protocol tunneling and proxy platform designed to expose localhost, devices, private services, and AI agents to the public internet supporting HTTP/HTTPS tunnels, TCP/UDP forwarding, mobile proxy infrastructure, file server publishing, latency-optimized game connectivity, and developer-ready AI agent endpoint exposure from a single unified control plane.

support