Set Up a Local Password‑Protected HTTP File Server on Android with Termux and Python

17 min read Learn step‑by‑step how to turn your Android phone into a local, password‑protected HTTP file server using Termux and Python—no root required. October 13, 2026 04:00 How to Set Up a Local Password‑Protected HTTP File Server on Android Using Termux and Python (No Root)

Why you might need a local HTTP file server on Android

Sometimes you want to share a handful of documents, photos, or backup files with a laptop or another phone on the same Wi‑Fi network, but you don't want to rely on cloud services. A lightweight HTTP server running directly on your Android device gives you:

  • Instant, LAN‑only access—no internet required.
  • Full control over who can connect—you can protect the server with a password.
  • Zero‑root solution—Termux provides a Linux‑like environment without touching the system partition.

This tutorial shows you how to set up exactly that, using the free python3 module that ships with Termux. By the end you will be able to point any browser on the same network to http://your‑phone‑ip:8000 and be prompted for a username and password.

Before you start

Make sure your Android device is charged above 50 % and connected to a stable Wi‑Fi network. The server will only be reachable from devices on the same subnet.

  • Android version 6.0 (Marshmallow) or newer. Termux runs on most devices, but very old ROMs may lack the required libc support.
  • At least 200 MB of free storage for Termux packages and your files.
  • A USB‑C or micro‑USB cable if you plan to copy large files from a PC via adb push (optional).

Step 1 – Install Termux and grant permissions

  1. Open the Google Play Store (or F-Droid for the open‑source build) and search for Termux. Install the app.
  2. Launch Termux. The first run will download the basic package set; this may take a minute depending on your connection.
  3. When the welcome screen appears, grant storage access by typing:
    termux-setup-storage
    This creates a ~/storage shortcut that maps to your shared internal storage (e.g., /sdcard).
  4. Confirm the permission dialog that Android shows. Without this step the HTTP server cannot serve files outside Termux's private directory.

Why this matters: Termux runs in its own sandbox. The termux-setup-storage command links that sandbox to the public storage area, allowing the server to read the files you want to share.

Step 2 – Update package lists and install Python

  1. Update the package repository to avoid version conflicts:
    pkg update && pkg upgrade -y
  2. Install Python 3 and the pip package manager:
    pkg install python -y
  3. Verify the installation:
    python3 --version
    You should see something like Python 3.11.x.

Note: The python package in Termux includes the http.server module we will use later, so no extra dependencies are required.

Step 3 – Choose a folder to serve

You can serve any directory that Termux can read. For simplicity we will use a folder inside the shared storage called SharedServer:

  1. Create the folder from the Android UI (e.g., using the Files app) or via Termux:
    mkdir -p ~/storage/shared/SharedServer
  2. Copy the files you want to share into that folder. You can drag‑and‑drop from a PC using adb push:
    adb push MyDocument.pdf /sdcard/SharedServer/
  3. Confirm the files are visible from Termux:
    ls ~/storage/shared/SharedServer

If you prefer to keep the files private, you can serve a directory inside Termux's home (e.g., ~/my_private_share). Just remember that the HTTP server can only read what the Termux user can access.

Step 4 – Create a simple password‑protected HTTP server script

Python’s built‑in http.server module does not provide authentication out of the box. We will wrap it with a tiny request handler that checks a hard‑coded username and password. This keeps the tutorial self‑contained and avoids installing extra packages.

  1. Open a text editor inside Termux. The simplest is nano (already bundled):
    nano ~/serve_protected.py
  2. Paste the following Python code (replace admin and Secret123 with your own credentials):
    #!/usr/bin/env python3
    import base64
    from http.server import SimpleHTTPRequestHandler, HTTPServer
    
    USERNAME = 'admin'
    PASSWORD = 'Secret123'
    
    class AuthHandler(SimpleHTTPRequestHandler):
        def do_AUTHHEAD(self):
            self.send_response(401)
            self.send_header('WWW-Authenticate', 'Basic realm="Secure Area"')
            self.send_header('Content-type', 'text/html')
            self.end_headers()
    
        def parse_auth_header(self):
            auth_header = self.headers.get('Authorization')
            if auth_header is None:
                return False
            auth_type, encoded = auth_header.split(' ', 1)
            if auth_type != 'Basic':
                return False
            decoded = base64.b64decode(encoded.strip()).decode('utf-8')
            user, pwd = decoded.split(':', 1)
            return user == USERNAME and pwd == PASSWORD
    
        def do_GET(self):
            if not self.parse_auth_header():
                self.do_AUTHHEAD()
                self.wfile.write(b'Authentication required.')
            else:
                super().do_GET()
    
    if __name__ == '__main__':
        import os, sys
        # Change directory to the folder we want to serve
        os.chdir(os.path.expanduser('~/storage/shared/SharedServer'))
        port = int(sys.argv[1]) if len(sys.argv) > 1 else 8000
        server_address = ('', port)
        httpd = HTTPServer(server_address, AuthHandler)
        print(f'Serving on http://0.0.0.0:{port} (press Ctrl+C to stop)')
        httpd.serve_forever()
    
  3. Save the file (Ctrl+O, Enter) and exit nano (Ctrl+X).
  4. Make the script executable:
    chmod +x ~/serve_protected.py

Explanation: The script changes the working directory to ~/storage/shared/SharedServer, starts a basic HTTP server on port 8000 (or a custom port you pass as an argument), and intercepts each GET request. If the Authorization header is missing or incorrect, the server returns a 401 Unauthorized response prompting the browser for credentials.

Step 5 – Launch the server

  1. Start the server in the foreground so you can see log output:
    ./serve_protected.py 8000
  2. Termux will display a line similar to:
    Serving on http://0.0.0.0:8000 (press Ctrl+C to stop)
  3. Leave this terminal open. If you prefer the server to keep running after you close the session, you can use nohup or tmux, but that is beyond the scope of this tutorial.

Now the server is listening on all network interfaces of the phone. The next step is to find the phone’s IP address on the Wi‑Fi network.

Step 6 – Find your phone’s LAN IP address

  1. In the same Termux session, run:
    ip addr show wlan0
  2. Look for a line that starts with inet . The number before the slash is your IP, e.g., 192.168.1.42/24. The part before the slash (192.168.1.42) is what you will use in the browser.

If your device uses a different interface name (some manufacturers label Wi‑Fi as wlp2s0), replace wlan0 accordingly.

Step 7 – Access the server from another device

On a laptop, tablet, or another phone connected to the same Wi‑Fi network, open a web browser and type:

http://192.168.1.42:8000

The browser will pop up a native authentication dialog. Enter the username and password you defined in the script (default admin / Secret123). After successful authentication you should see a directory listing of the SharedServer folder, and you can click any file to download it.

Step 8 – Optional: Use a custom port or bind to a specific interface

Some networks block port 8000, or you might want to avoid conflicts with other services. You can start the script with a different port number:

./serve_protected.py 8080

If you only want the server reachable from the Wi‑Fi interface (and not from USB tethering, for example), modify the server_address line in the script to bind to the specific IP:

server_address = ('192.168.1.42', port)

Remember to update the URL you type in the client browser accordingly.

Troubleshooting

1. “Permission denied” when accessing files

If the server returns a 403 error, the most common cause is that Termux does not have permission to read the target directory. Re‑run termux-setup-storage and ensure the folder lives under /sdcard/SharedServer (or the ~/storage/shared symlink). Also double‑check the file permissions with ls -l – they should be at least readable by the owner.

2. No response from the server on the client side

  • Verify the phone’s IP address again; DHCP can change it after a router reboot.
  • Make sure the Wi‑Fi network does not isolate clients (some guest networks block inter‑device traffic).
  • Temporarily disable Android’s “Battery optimization” for Termux (Settings → Apps → Termux → Battery → Optimize battery usage → Don’t optimize). Otherwise Android may pause the process after a few minutes of inactivity.

3. The authentication dialog never appears

This usually means the client browser cached a previous 401 response without credentials. Clear the browser cache or open a private/incognito window and try again.

4. Server stops after you close the Termux window

Termux processes are tied to the session. To keep the server alive you can:

  1. Install tmux (pkg install tmux) and start the script inside a tmux session.
  2. Use nohup:
    nohup ./serve_protected.py 8000 &
    The output will be redirected to nohup.out.
  3. Enable Termux’s “Background execution” setting (Settings → Termux → Background execution) if your device’s manufacturer allows it.

Security considerations

  • LAN‑only exposure: The server is reachable only from devices on the same Wi‑Fi subnet. Do not forward port 8000 through your router unless you understand the risks.
  • Password storage: The credentials are stored in plain text inside the script. For higher security, you can read them from an environment variable or a separate config file with restrictive permissions (chmod 600).
  • HTTPS: The built‑in server uses plain HTTP. If you need encryption, consider using openssl to create a self‑signed certificate and run python3 -m http.server with the --bind and --directory options, but that adds complexity beyond the scope of this guide.

Advanced tweaks (optional)

Serving a specific file type only

Modify the do_GET method to filter extensions. Example:

if not self.path.endswith('.pdf'):
    self.send_error(403, "Only PDF files are allowed")
    return

Logging requests to a file

Add a simple logger inside the handler:

import datetime

def log_request(self, code='-'):
    now = datetime.datetime.now().isoformat()
    with open('/sdcard/SharedServer/access.log', 'a') as f:
        f.write(f"{now} - {self.client_address[0]} - {self.command} {self.path} - {code}\n")

# Call log_request at the end of do_GET after super().do_GET()

Running on a USB‑tethered network

If you connect your phone to a laptop via USB and enable USB tethering, the interface is usually rndis0. Replace wlan0 with rndis0 in the ip addr command to obtain the correct IP.

Cleaning up

When you no longer need the server:

  1. Stop the Python process with Ctrl+C in the Termux window.
  2. If you used nohup or tmux, locate the process ID with ps aux | grep serve_protected.py and kill it with kill.
  3. Optionally delete the script and shared folder:
    rm ~/serve_protected.py
    rm -r ~/storage/shared/SharedServer

Remember that any files you placed in SharedServer remain on your device unless you delete them manually.

Recap of the workflow

  • Install Termux and enable storage access.
  • Install Python via pkg install python.
  • Create a directory with the files you want to share.
  • Write a short Python script that adds Basic Auth to the built‑in HTTP server.
  • Start the script, note the phone’s LAN IP, and connect from another device using a browser.
  • Apply optional tweaks for ports, logging, or persistent background execution.

With these steps you have a lightweight, password‑protected file server that works on any Android phone without root. It’s perfect for quick ad‑hoc transfers, classroom demos, or sharing large media files without uploading them to the cloud.

User Comments (0)

Add Comment
We'll never share your email with anyone else.