How to Host a Web Server on Android and Make It Public (Complete 2026 Guide)
Your Android phone can run a fully functional public web server. No static IP, no router configuration, no root access, and no PC required. This guide covers every method: a no-code GUI app, Termux with Node.js and Express, Termux with Python and Flask, running servers in the background with tmux, security best practices, and custom domain setup. Unlike ngrok, Localtonet has a native Android app and a Termux package, making it a tunneling service with first-class Android support.
Why Run a Web Server on Android?
Modern Android devices have more CPU power and RAM than the servers that ran the early web. Combined with Localtonet, your phone becomes a real server with a public HTTPS URL accessible from anywhere in the world. No cloud subscription needed.
ngrok, Cloudflare Tunnel, and most other tunneling tools have no official Android app or Termux package.
Localtonet has both: a dedicated Android app on Google Play and a native Termux .deb package.
This makes Localtonet a strong option for running tunnels directly from Android.
How Localtonet Tunneling Works on Android
Your web server runs locally on your Android device on a port like 8080 or 3000.
Localtonet creates an encrypted tunnel from that local port to a public HTTPS URL.
Anyone who visits that URL reaches your phone's server directly. No port forwarding, no static IP, and no router configuration needed.
There are two ways to use Localtonet on Android:
Option A: Localtonet Android App (Recommended)
The official Localtonet app lets you create and manage tunnels from a graphical interface. It also supports VPN tunnels, which are not available in Termux.
Install the app
Download from Google Play. Free to install.
Copy your AuthToken
Log in to localtonet.com, go to My Tokens, and copy your AuthToken. The token is unique per device. You can create multiple tokens for different devices.
Paste AuthToken in the app
Open the app and paste your token. Your Android device is now linked to your Localtonet account.
Create a tunnel from the dashboard
Go to the HTTP Tunnel Page in your browser.
Select your Process Type (Random Subdomain, Custom Subdomain, or Custom Domain), select your AuthToken, choose a server,
enter IP 127.0.0.1 and the port your server runs on, then click Create.
Press Start from the tunnel list to activate it.
Option B: Localtonet Inside Termux (.deb Package)
If you work entirely in Termux, install Localtonet as a native package. You authenticate with your token and manage tunnels from the Localtonet web dashboard.
Termux is not systemd-based, so service mode commands (--install-service, --start-service) are not supported.
VPN tunnels are also unavailable in Termux. Use the Android app for VPN.
Download the Termux package
wget https://localtonet.com/download/localtonet-termux.zip
Extract
unzip localtonet-termux.zip
Install with pkg
pkg install ./localtonet.deb
Authenticate with your token
localtonet --authtoken YOUR_TOKEN_HERE
After authenticating, manage and start your tunnels from the Localtonet web dashboard.
4 Methods to Run a Web Server on Android
Method 1: GUI Web Server App (No Terminal)
Web Server App + Localtonet
The fastest path to a public Android web server with zero terminal commands. Perfect for serving static HTML files or a simple website.
Install a Web Server App
Install kWS - Android Web Server or Simple HTTP Server from Google Play. Both are free, support static file serving, and require no root access.
Configure Port and Root Directory
Set the port to 8080. Port 80 requires root on non-rooted devices. Always use a port above 1024. Set the root directory to the folder containing your site files.
Start the Server
Tap Start. Verify it works by opening http://127.0.0.1:8080 in Chrome on the same phone.
Create an HTTP Tunnel from the Dashboard
Go to the HTTP Tunnel Page. Select your process type, select your AuthToken, choose a server, enter IP 127.0.0.1 and port 8080. Click Create, then press Start in the list. Localtonet gives you a public HTTPS URL.
On non-rooted Android, apps cannot bind to port 80. Always use port 8080 or any port above 1024.
Best For
- Serving static HTML/CSS/JS sites
- Non-developers who need a quick public URL
- Quick file sharing via browser
Not Ideal For
- Dynamic server-side logic
- REST APIs or database-connected apps
- Automated or scripted workflows
Method 2: Termux + Node.js + Express REST API
Termux + Node.js + Express
The Google Play version of Termux is outdated and no longer maintained. pkg install commands frequently fail. Always install from F-Droid.
Step 1: Set Up Termux
Update packages and grant storage access
pkg update && pkg upgrade -y
termux-setup-storage
Tap Allow when prompted. This gives Termux access to your phone's storage.
Install Node.js
pkg install nodejs-lts
Verify: node -v && npm -v
Step 2: Create an Express API
Create a project folder and install Express
mkdir ~/myserver && cd ~/myserver
npm init -y
npm install express
Create the server file
nano server.js
Paste this Express app:
const express = require('express');
const app = express();
app.use(express.json());
app.get('/', (req, res) => {
res.json({ message: 'Android server is running!', time: new Date() });
});
app.get('/api/status', (req, res) => {
res.json({ status: 'ok', platform: 'android' });
});
app.post('/api/data', (req, res) => {
console.log('Received:', req.body);
res.json({ received: true, data: req.body });
});
app.listen(3000, () => {
console.log('Server running at http://localhost:3000');
});
Save: Ctrl+X โ Y โ Enter
Start the server
node server.js
Test locally: open http://127.0.0.1:3000 in Chrome on your phone.
Step 3: Create the Tunnel from Dashboard
Go to the HTTP Tunnel Page
Open localtonet.com/tunnel/http in your browser.
Configure and create
Select your process type (Random Subdomain for quick testing), select your AuthToken, choose a server, enter IP 127.0.0.1 and port 3000. Click Create.
Start the tunnel
Press Start from the tunnel list. Localtonet will display your public HTTPS URL. Your Express API is now live on the internet.
To serve a folder of static files instead of building a custom server, install the http-server package globally: npm install -g http-server. Navigate to your folder and run http-server -p 8080. Use port 8080 when creating your tunnel in the dashboard.
Method 3: Termux + Python + Flask Web App
Termux + Python + Flask
Quick File Server (One Command)
Install Python and navigate to your folder
pkg install python
cd ~/storage/downloads
Start the built-in HTTP server
python -m http.server 8080
Everything in that folder is now served at http://127.0.0.1:8080. Create a tunnel for port 8080 in the dashboard to make it public.
Full Flask Web App
Install Flask
pkg install python
pip install flask
Create your Flask app
mkdir ~/flaskapp && cd ~/flaskapp
nano app.py
Paste this starter app:
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route('/')
def home():
return '<h1>Hello from Android!</h1>'
@app.route('/api/status')
def status():
return jsonify({'status': 'running', 'platform': 'android'})
@app.route('/api/data', methods=['POST'])
def receive_data():
data = request.get_json()
print('Received:', data)
return jsonify({'received': True, 'data': data})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False)
Save: Ctrl+X โ Y โ Enter
Run the app
python app.py
Flask starts on port 5000. Test locally at http://127.0.0.1:5000.
Create tunnel for port 5000 in the dashboard
Go to localtonet.com/tunnel/http โ enter IP 127.0.0.1, port 5000 โ Create โ Start.
To access files in /sdcard, run termux-setup-storage once and grant the permission. Without this, Termux can only access its own internal directory.
Method 4: Keep Your Server Running in the Background (tmux)
Background Server with tmux + WakeLock
By default, Android may kill your Termux processes when the screen turns off or when you switch apps. Two tools solve this: tmux keeps your server session alive independently of the terminal window, and termux-wake-lock prevents the CPU from sleeping.
Android 12 and 13 introduced a background process limiter that can terminate Termux processes even with tmux and WakeLock active. Fix it via ADB: adb shell "device_config put activity_manager max_phantom_processes 2147483647". Also go to Settings โ Apps โ Termux โ Battery โ Unrestricted.
Install tmux
pkg install tmux
Start a named tmux session
tmux new -s myserver
A green status bar appears at the bottom. You're now inside a persistent session.
Start your server inside the session
# Node.js:
node ~/myserver/server.js
# Flask:
python ~/flaskapp/app.py
# Python file server:
python -m http.server 8080
Detach (server keeps running)
Ctrl+B, then D
You're back at the Termux prompt. Your server is still running. You can close Termux now.
Enable WakeLock to prevent CPU sleep
termux-wake-lock
Or pull down the notification shade and tap Acquire WakeLock in the Termux notification.
Reattach to your session anytime
tmux ls
tmux attach -t myserver
Ctrl+B, D - Detach |
Ctrl+B, C - New window |
Ctrl+B, N - Next window |
tmux ls - List sessions |
tmux kill-session -t myserver - Stop session
Bonus: Zero-Install SSH Tunnel
Zero-Install SSH Tunnel
Localtonet lets you create a public tunnel using the SSH client already built into Windows 10+, macOS, and Linux. No Localtonet binary is needed on the machine creating the tunnel. Your web server runs on Android. You activate the tunnel with one SSH command from any other device.
Create a tunnel in the dashboard
Go to Tunnels โ New Tunnel. Select TCP or HTTP. Click Create.
Get your SSH command
Open the tunnel card โ Settings โ SSH Command. You'll see a pre-built one-liner:
ssh -p 223 YourTunnelToken@example.localto.net -R3327:127.0.0.1:8080
Paste into any terminal and press Enter
Traffic is forwarded immediately: example.localto.net:3327 โ 127.0.0.1:8080
Using a Custom Domain with Your Android Server
By default Localtonet assigns you a public URL like abc123.localto.net.
If you want your Android server accessible at your own domain (for example api.yourdomain.com), Localtonet handles this through its built-in DNS Manager.
Add your domain to the Localtonet DNS Manager
Log in to your dashboard and go to the DNS Manager. Add your domain address there.
Update your domain's nameservers
Go to the admin panel of your domain registrar (Namecheap, GoDaddy, etc.) and update your domain's nameservers to:
ns1.localtonet.com
ns2.localtonet.com
Wait for DNS propagation. This typically takes a few minutes to a few hours.
Select your custom domain when creating a tunnel
Go to the HTTP Tunnel Page. In the Process Type field, select Custom Domain. You can now choose your own domain and customize its subdomains for the tunnel.
Create and start the tunnel
Complete the tunnel creation with your custom domain selected. Your Android server is now accessible at your own domain with automatic HTTPS. No SSL certificate setup needed.
After setup you can view, add, and update all your DNS records directly from the Localtonet DNS Manager. Custom domains work with all Localtonet tunnel types: HTTP, TCP, UDP, File Server, and more.
Security Best Practices
๐ Always use authentication on public tunnels
Enable Localtonet's built-in SSO or Username/Password authentication on tunnels that serve sensitive content. Go to your tunnel settings and add an authentication method. Never expose an unprotected server to the public internet, even temporarily.
๐ซ Never expose sensitive directories
When using python -m http.server or http-server, serve from a dedicated folder only. Never serve from ~ (home) or the /sdcard root. An exposed home directory could reveal SSH keys, auth tokens, or config files.
๐ Set debug=False in Flask
Flask debug mode exposes an interactive debugger that can execute arbitrary Python code. Always use debug=False when your server is reachable from the internet.
๐ Close tunnels when not in use
Press Stop on any tunnel in the Localtonet dashboard when you no longer need the public URL. Leaving tunnels open unnecessarily increases your attack surface.
๐ฆ Keep packages updated
Run pkg update && pkg upgrade in Termux regularly. Also keep your app dependencies updated: npm update or pip install --upgrade flask.
Troubleshooting Common Issues
| Problem | Cause | Fix |
|---|---|---|
pkg install fails with errors |
Outdated Play Store Termux | Uninstall and reinstall Termux from F-Droid |
| Cannot bind to port 80 | Ports below 1024 require root | Use port 8080 or higher |
| Server stops when screen turns off | Android kills background processes | Use tmux + WakeLock + set Termux battery to Unrestricted |
Cannot access /sdcard files |
Storage permission not granted | Run termux-setup-storage and allow |
| Process killed on Android 12/13 | Phantom Process Killer | adb shell "device_config put activity_manager max_phantom_processes 2147483647" |
| Tunnel URL not working | Server not running or wrong port | Test http://127.0.0.1:PORT in Chrome first, then create tunnel with the same port |
Flask: Address already in use |
Old process still running on that port | Run pkill -f "python app.py" or use a different port |
| Custom domain not working | Nameservers not updated yet | Confirm ns1/ns2.localtonet.com are set at your registrar and wait for DNS propagation |
pkg install fails
Cannot bind port 80
Server stops on screen off
Custom domain not working
Frequently Asked Questions
Can I host a web server on Android without root?
Yes. All methods in this guide work on non-rooted Android devices. The only limitation is that ports below 1024 (including port 80) require root. Use port 8080, 3000, or 5000 instead. Localtonet will still give you a public HTTPS URL regardless of which local port you use.
Does ngrok work on Android?
ngrok has no official Android app or Termux package. You cannot run ngrok natively on Android. Localtonet is an alternative: it has a dedicated Android app on Google Play and a native Termux .deb package.
Should I install Termux from Google Play or F-Droid?
Always install Termux from F-Droid. The Google Play version is outdated and no longer maintained. pkg install commands frequently fail. The F-Droid version receives regular updates and works correctly with package installations.
How do I keep a web server running when my phone screen is off?
Use tmux to keep your server session alive independently of the terminal, and run termux-wake-lock to prevent the CPU from sleeping. Also go to Settings โ Apps โ Termux โ Battery and set it to Unrestricted. On Android 12+, disable the Phantom Process Killer via ADB.
How do I use a custom domain with Localtonet on Android?
First add your domain in the Localtonet DNS Manager. Then update your domain's nameservers to ns1.localtonet.com and ns2.localtonet.com at your registrar. Once DNS propagates, select Custom Domain as the Process Type when creating any tunnel and choose your domain. Automatic HTTPS is included.
Can I run Node.js on Android?
Yes. Install Termux from F-Droid, then run pkg install nodejs-lts. This gives you a Node.js and npm environment on your Android device. You can install npm packages, run Express servers, and use Node frameworks. Create an HTTP tunnel in the Localtonet dashboard to make your server publicly accessible.
How do I make my Android server accessible from the internet?
Start your web server on any local port (for example 3000 or 8080). Install the Localtonet app or authenticate via the Termux package. Then go to localtonet.com/tunnel/http, create an HTTP tunnel with IP 127.0.0.1 and your port, and press Start. Localtonet gives you a public HTTPS URL. No static IP, port forwarding, or router config needed.
Your Android Phone Is Already a Server. Make It Public.
The only tunneling service with a native Android app and Termux support. Get a public HTTPS URL in under 2 minutes. Free to start.
Get Started Free โ