Running a web server on a phone sounds like a novelty, but it becomes a practical tool for developers, testers, or anyone who wants to share files securely on a local network. This tutorial shows you how to create a fully functional HTTPS server on Android using the free Termux terminal emulator and the lightweight Nginx web server—without rooting the device.
If you have never used Termux before, think of it as a Linux shell that runs inside Android. All commands below are typed inside the Termux console.
pkg update && pkg upgrade -y
This ensures you have the latest security patches.termux-setup-storage
You will be prompted to allow "Files and media" access – tap Allow. This creates a ~/storage directory linked to the device's internal storage.Why this matters: Without storage permission, Nginx cannot read the HTML files you want to serve, and you would be forced to keep everything inside Termux’s private directory, which is inconvenient for larger sites.
curl for testing:
pkg install nginx openssl-tool curl -y
The -y flag auto‑confirms installation.nginx -v
You should see something like nginx version: nginx/1.24.0.Note: Nginx in Termux runs as the current user, not as root, so it can only bind to ports >= 1024. We will use port 8443 for HTTPS to avoid the privileged‑port restriction.
A real HTTPS server needs a certificate. For a local server a self‑signed certificate is sufficient. Browsers will warn you, but you can add an exception.
mkdir -p ~/nginx/sslopenssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out ~/nginx/ssl/server.keyopenssl req -new -key ~/nginx/ssl/server.key -subj "/C=US/ST=State/L=City/O=MyAndroidServer/CN=AndroidLocal" -out ~/nginx/ssl/server.csr
openssl x509 -req -days 365 -in ~/nginx/ssl/server.csr -signkey ~/nginx/ssl/server.key -out ~/nginx/ssl/server.crt
The -subj string avoids interactive prompts. Adjust the fields if you like.ls -l ~/nginx/sslWhy a self‑signed cert? It encrypts traffic, preventing anyone on the same Wi‑Fi from sniffing the content. The trade‑off is the browser warning, which is acceptable for a private LAN.
We'll serve a tiny HTML page that displays the device's IP address, proving the server works.
mkdir -p ~/nginx/htmlindex.html file:
cat > ~/nginx/html/index.html <<'EOF'
Android Local HTTPS Server
Hello from Android!
This page is served over HTTPS by Nginx running inside Termux.
Your device IP: $(ip -4 addr show wlan0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
EOF
The embedded shell command will be evaluated by the browser only if you enable server‑side processing, which Nginx does not do by default. It is kept as a placeholder to illustrate where dynamic content could go.cat ~/nginx/html/index.htmlWe will replace the default configuration with a minimal one that listens on port 8443 and serves the ~/nginx/html directory.
cp $PREFIX/etc/nginx/nginx.conf $PREFIX/etc/nginx/nginx.conf.backupnano (install with pkg install nano if missing):
nano $PREFIX/etc/nginx/nginx.conf
Replace its contents with the following (copy‑paste the block):
worker_processes 1;
error_log /data/data/com.termux/files/usr/var/log/nginx/error.log warn;
pid /data/data/com.termux/files/usr/var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8443 ssl;
server_name localhost;
ssl_certificate /data/data/com.termux/files/home/nginx/ssl/server.crt;
ssl_certificate_key /data/data/com.termux/files/home/nginx/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
root /data/data/com.termux/files/home/nginx/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
}
Save with Ctrl+O, then exit with Ctrl+X.nginx -t
You should see syntax is ok and test is successful.The paths use Termux’s internal storage layout (/data/data/com.termux/files/home) which is where the ~ shortcut points.
nginx
The command returns to the prompt; the server runs in the background.ip -4 addr show wlan0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
Note the IP, e.g., 192.168.1.42.curl (ignore certificate warnings):
curl -k https://127.0.0.1:8443
You should see the HTML of index.html.https://192.168.1.42:8443
The browser will display a security warning because the certificate is self‑signed. Proceed by adding an exception (usually "Advanced > Proceed to site"). You should now see the "Hello from Android!" page.If the page loads, your HTTPS server is up and running.
Termux terminates background processes when the app is swiped away. Two common approaches prevent that:
termux-api and termux-boot packages, then create a script ~/.termux/boot/nginx-start.sh containing nginx. The server will start automatically after a reboot.tmux or screen session, launch Nginx inside it, and detach. Example:
pkg install tmux
tmux new -s nginx
nginx
# Press Ctrl+b then d to detach
The process stays alive even if you close the Termux UI, as long as the app isn’t force‑stopped.Choose the method that fits your workflow. For occasional testing, a simple tmux session is quick and reversible.
If you have a static site (HTML, CSS, JS) stored in the Android "Downloads" folder, you can point Nginx to it without copying files into Termux.
/storage/emulated/0. For example, a site in Downloads/site would be at /storage/emulated/0/Download/site.root directive to point there:
root /storage/emulated/0/Download/site;
Save and reload Nginx:
nginx -s reloadRemember that any device on the LAN can request those files, so keep sensitive data out of the shared folder.
ss -ltnp | grep 8443 inside Termux to see the culprit.iptables package in Termux and run iptables -L to see if a DROP rule exists. If so, you can temporarily allow traffic:
iptables -I INPUT -p tcp --dport 8443 -j ACCEPT-k flag (as shown) to ignore verification, or add the generated certificate to your local trust store if you need strict verification.ssl directory and its files are readable by the Termux user. The default permissions are fine, but if you moved the files elsewhere, run:
chmod 600 ~/nginx/ssl/*
chmod 755 ~/nginx/ssltmux or termux-boot (as described in Step 7) mitigates this. Additionally, enable "Battery optimization" → "Don’t optimize" for Termux in Settings.listen 8443 ssl http2; in the server block. This improves performance for modern browsers.http block, enable gzip:
gzip on;
gzip_types text/plain text/css application/json application/javascript;certbot on a PC, then copy the files to the phone. Automating the copy with rsync over SSH is possible.By following these steps you now have a lightweight, fully functional HTTPS web server running entirely on your Android device, without needing root access. The server can host static sites, share documentation, or act as a quick test endpoint for mobile‑first development. Because the entire stack lives inside Termux, you can easily uninstall it later without leaving traces on the system.
Feel free to experiment—add PHP via php-fpm, serve API mock responses, or integrate the server into automated UI tests that require a local endpoint. Just remember the security warnings and keep the service confined to trusted networks.









