Preparing your device correctly saves you from dead‑ends later. Follow these checks before installing anything.
If you plan to expose the server beyond your local network, read the Security warning at the end of the guide.
termux-setup-storage. This command creates a ~/storage shortcut and asks for the standard Android storage permission. Grant it.After granting permission you’ll see three symbolic links: shared, downloads, and external. You can store your web projects under ~/storage/shared/termux-web if you want them visible to other apps.
pkg update && pkg upgrade -y
Keeping packages up‑to‑date prevents compilation errors later on.
Termux’s pkg command pulls pre‑compiled binaries, which makes installation fast. Choose the stack that matches the language you plan to use.
pkg install -y git curl wget
pkg install -y nodejs
pkg install -y python
pkg install -y php
pkg install -y nginx
pkg install -y openssl-tool
All of these packages install into Termux’s private filesystem (/data/data/com.termux/files/usr) and do not interfere with the system.
For clarity, create a dedicated folder for your web work.
cd ~/storage/shared
termux-web and move into it:
mkdir termux-web && cd termux-web
node-demo:
mkdir node-demo && cd node-demo
Using the shared storage makes it easy to edit files later with a GUI editor like QuickEdit or VS Code Remote on a PC.
Node.js is popular for quick prototypes. The same workflow applies to Python or PHP – we’ll add those later.
npm init -y
npm install express
server.js:
cat > server.js <<'EOF'
const express = require('express');
const app = express();
const PORT = 8080;
app.get('/', (req, res) => {
res.send('Hello from Termux!');
});
app.listen(PORT, () => console.log(`Server listening on http://0.0.0.0:${PORT}`));
EOF
node server.js
You should see the message Server listening on http://0.0.0.0:8080. The 0.0.0.0 bind tells the server to listen on all network interfaces, which is required for other devices to reach it.
Open the Android browser (Chrome, Edge, etc.) and navigate to http://127.0.0.1:8080 or http://localhost:8080. You should see the text “Hello from Termux!”. If the page does not load:
node server.js in the terminal).sudo – Termux does not have sudo, and the command would have failed.This step proves that the phone is acting as a true network host.
ip addr show wlan0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
http://<PHONE_IP>:8080. Replace <PHONE_IP> with the number you just retrieved.If the request times out, try these checks:
192.168.1.x or 10.0.0.x. Both devices must share the prefix.INTERNET permission automatically, but some custom ROMs require manual approval in Settings → Apps → Termux → Permissions.Flask is a micro‑framework that runs with a single command. It’s useful for quick APIs.
cd ~/storage/shared/termux-web && mkdir flask-demo && cd flask-demo
pip install flask
app.py:
cat > app.py <<'EOF'
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello from Flask on Termux!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
EOF
python app.py
Open http://127.0.0.1:5000 on the phone or http://<PHONE_IP>:5000 from another device. The response should be “Hello from Flask on Termux!”.
NGINX can serve static files and proxy to PHP‑FPM. In Termux, we’ll use the built‑in PHP built‑in server for simplicity, but we’ll also show how to start NGINX.
mkdir -p ~/storage/shared/termux-web/php-demo && cd $_
index.php:
cat > index.php <<'EOF'
EOF
php -S 0.0.0.0:8081
http://<PHONE_IP>:8081 from another device. You should see the PHP output.nano $PREFIX/etc/nginx/nginx.conf
Replace the server block with:
server {
listen 8082;
server_name _;
root /data/data/com.termux/files/home/storage/shared/termux-web/php-demo;
index index.php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
php-fpm binary):
php-fpm
nginx
http://<PHONE_IP>:8082 to see the same message.NGINX is optional for simple demos, but it mirrors a production setup where static assets are served directly and dynamic requests are handed to PHP‑FPM.
Termux sessions end when you swipe the app away or when Android reclaims resources. Two tools help you run services in the background.
termux-wake-lockpkg install -y termux-api
termux-wake-lock
termux-wake-unlock.tmux or screenBoth provide detachable terminal sessions.
pkg install -y tmux
web:
tmux new -s web
node server.js).Ctrl+b then d.tmux attach -t web to view logs or stop the server.Using tmux is especially handy when you want to run multiple services simultaneously (e.g., Node API on 8080 and Flask on 5000).
Termux includes vim and nano, but many developers prefer a graphical editor.
pkg install -y vim. Learn basic commands (:wq, /search) for quick edits.termux-open command to launch a file in a third‑party app, e.g., termux-open server.js.openssh (pkg install -y openssh) and enable the SSH daemon:
sshd
Then connect from a PC using ssh u0_aXXX@<PHONE_IP>. This gives you full VS Code Remote or Sublime Text editing capabilities.Even a development server can be abused if left open on a public Wi‑Fi. Here are low‑effort hardening steps.
127.0.0.1 in your code.openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem -subj "/CN=android-local"
Then start Node with node server.js --tls-key key.pem --tls-cert cert.pem (or configure Flask/NGINX accordingly).Authorization header.iptables (pkg install -y iptables) and block inbound traffic except from your own IP range.These measures are optional for pure local development, but they illustrate good security hygiene.
If you see EADDRINUSE (Node) or “Address already in use” (Python), another process is listening on the same port.
netstat -tuln | grep LISTEN
kill -9 <PID>
Some Android builds restrict apps from listening on non‑loopback interfaces unless the app has the INTERNET permission, which Termux already declares. If binding fails, try:
getenforce. If it returns Enforcing, you may need to switch to Permissive via setenforce 0, but this requires root. In a no‑root scenario, the workaround is to bind to 127.0.0.1 and use adb reverse tcp:8080 tcp:8080 to forward the port to a PC.ping <PHONE_IP> from the other device to verify basic connectivity.Android may kill background processes to reclaim RAM.
termux-wake-lock method described earlier.Now that the basics work, here are a few practical scenarios where a local Android server shines.
_site folder to ~/storage/shared/termux-web/site, and serve it with NGINX for on‑the‑go demos.npm install -g node-red) to connect Bluetooth sensors to your phone and expose data over HTTP.Because everything runs in user space, you can experiment without risking the system partition.
Termux does not provide a firewall UI, and the binaries run with the same privileges as your user account. If you forward ports through your router (port‑forwarding) or use a reverse‑proxy service, anyone on the internet could reach your phone. Always:
With the steps above you now have a fully functional, portable web development environment on your Android device. Whether you’re debugging a React Native backend, prototyping a Python API, or simply need a quick static file server, Termux gives you the flexibility of a Linux workstation in the palm of your hand.









