Python HTTP Server Howsnip

How to Set Up a Python HTTP Server on Ubuntu

Running a simple HTTP server with Python is one of the fastest ways to share files, test web content, build mock APIs, or perform local development on Ubuntu. Python includes a built-in HTTP server module that requires no additional software, making it ideal for beginners and developers alike.

In this tutorial, you’ll learn how to set up a Python HTTP server on Ubuntu, configure firewall access, create a custom server, run it in the background, add HTTPS support with Nginx, and troubleshoot common issues.

Prerequisites

Before you begin, ensure you have:

  • An Ubuntu system
  • Python 3 installed
  • Access to the terminal
  • Administrative privileges (required for firewall and service configuration)

Step 1: Verify Python Installation

Most modern Ubuntu releases include Python 3 by default. Start by checking the installed version.

python3 --version

Python HTTP Server

This command displays the currently installed Python version.

Install or Update Python

If Python is not installed, update package information and install Python 3:

sudo apt update
sudo apt install python3

The first command refreshes Ubuntu’s package lists, while the second installs Python 3.

Install Optional Development Tools

For testing, package management, and virtual environments, install the following tools:

sudo apt install python3-pip

Python HTTP Server

pip allows you to install additional Python packages.

sudo apt install python3-venv

The venv package enables isolated Python environments for development projects.

Step 2: Create a Simple Python HTTP Server

Python includes the built-in http.server module, which can instantly serve files from a directory.

Navigate to Your Working Directory

Move to the folder you want to share:

cd /path/to/your/folder

Replace the path with the actual directory you want the server to serve.

Start the Server

Run:

python3 -m http.server

Python HTTP Server

This starts an HTTP server on the default port 8000.

Access the Server

Open a web browser and visit:

http://localhost:8000

Python HTTP Server

If the directory does not contain an index.html file, the browser displays a list of available files and folders.

Use a Different Port

To run the server on another port, such as 8080:

python3 -m http.server 8080

This launches the server on port 8080 instead of the default port 8000.

Allow Access from Other Devices

To make the server accessible from other devices on the network:

python3 -m http.server 8000 --bind 0.0.0.0

Python HTTP Server

The –bind 0.0.0.0 option tells the server to listen on all available network interfaces.

Important: Anyone who can reach your system’s IP address and port may be able to view the served files.

Step 3: Configure Firewall Rules with UFW

Ubuntu commonly uses UFW (Uncomplicated Firewall) for firewall management.

Enable UFW

If UFW is not already enabled, run:

sudo ufw enable

This activates the firewall.

Allow Access to Port 8000

If your Python server is running on port 8000, allow incoming connections on that port:

sudo ufw allow 8000

This opens port 8000 for external access.

Reload Firewall Rules

After making changes, reload UFW:

sudo ufw reload

This applies updated firewall rules without disabling the firewall.

Verify Firewall Status

Check active firewall rules:

sudo ufw status

Python HTTP Server

The output shows whether port 8000 is allowed.

Restrict Access to the Local Machine Only

If you only want local access, bind the server to the loopback address:

python3 -m http.server 8000 --bind 127.0.0.1

This prevents external devices from reaching the server.

Step 4: Create a Custom Python HTTP Server

While the built-in server is useful for file sharing, custom servers provide greater flexibility. You can create custom responses, add API endpoints, handle requests, and return data in different formats.

Example: Simple API Endpoint

Create a file named server.py and add the following code:

Python HTTP Server

from http.server import BaseHTTPRequestHandler, HTTPServer
import json

class SimpleAPI(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == "/status":
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()

response = {
"server": "running",
"path": self.path
}

self.wfile.write(json.dumps(response).encode())
else:
self.send_response(404)
self.end_headers()

def run_server():
server = HTTPServer(("localhost", 8000), SimpleAPI)
print("Server running at http://localhost:8000/")
server.serve_forever()

if __name__ == "__main__":
run_server()

How the Code Works

  • BaseHTTPRequestHandler processes incoming HTTP requests.
  • The do_GET() method handles GET requests.
  • Requests to /status return a JSON response.
  • Any other path returns a 404 error.
  • serve_forever() keeps the server running continuously.

Run the Custom Server

python3 server.py

Test the Endpoint

Open:

http://localhost:8000/status

Python HTTP Server

The server returns a JSON response indicating that it is running. This approach is useful for creating simple mock APIs and testing HTTP behavior without installing a full web framework.

Step 5: Run the Server in the Background

For long-running services, running the server directly in a terminal window may not be practical.

Common options include:

  • systemd
  • tmux
  • screen
  • nohup

Option 1: Use nohup

A quick way to run the server in the background:

nohup python3 -m http.server 8000 --bind 0.0.0.0 > server.log 2>&1 &

Python HTTP Server

The nohup utility keeps the process running even after you close the terminal session.

Option 2: Create a systemd Service

Create a new service file:

sudo nano /etc/systemd/system/python-http.service

Python HTTP Server

Add the following configuration:

[Unit]
Description=Python HTTP Server
After=network.target

[Service]
ExecStart=/usr/bin/python3 -m http.server 8000 --directory /var/www
WorkingDirectory=/var/www
Restart=always

[Install]
WantedBy=multi-user.target

Enable the Service

sudo systemctl enable python-http

Python HTTP Server

This configures the service to start automatically during system boot.

Start the Service

sudo systemctl start python-http

Verify Service Status

sudo systemctl status python-http

Python HTTP Server

After configuration, the HTTP server will start automatically whenever the system boots.

Step 6: Add HTTPS Using Nginx as a Reverse Proxy

Python’s built-in HTTP server does not provide HTTPS support. A common solution is to place Nginx in front of the Python server.

Install Nginx

sudo apt install nginx

Python HTTP Server

Nginx will handle incoming web traffic and forward requests to the Python server.

Basic Reverse Proxy Configuration

Example Nginx configuration:

Edit the following file /etc/nginx/sites-available/python-proxy

server {
listen 80;

location / {
proxy_pass http://127.0.0.1:8000;
}
}

Python HTTP Server

This configuration forwards requests received on port 80 to the Python server running on port 8000.

Reload Nginx

sudo systemctl reload nginx

Python HTTP Server

This applies the new configuration without restarting the service.

Step 7: Enable HTTPS with Let’s Encrypt

To secure traffic with SSL/TLS certificates, install Certbot.

Install Certbot

sudo apt install certbot python3-certbot-nginx

Python HTTP Server

These packages integrate Let’s Encrypt certificates with Nginx.

Request and Configure Certificates

sudo certbot --nginx

Certbot automatically obtains and configures SSL certificates for your Nginx server. After completion, users can securely access the site over HTTPS.

Troubleshooting Common Issues

a) Error: Address Already in Use

This error usually occurs when another process is already using port 8000.

Identify the Process

sudo lsof -i :8000

Python HTTP Server

The command displays the process ID (PID) currently using the port.

Stop the Process

sudo kill <pid>

Replace <pid> with the actual process ID returned by the previous command.

b) Error: Permission Denied

If you receive permission-related errors:

  • Use directories that your user account can access.
  • Check folder ownership and permissions.
  • Avoid serving files from restricted system locations unless necessary.
  • Cannot Access the Server from Another Device

If external devices cannot connect:

  • Verify that the server is bound to 0.0.0.0.
  • Confirm that UFW allows the required port.
  • Check network restrictions or router isolation settings.
  • Ensure the correct IP address is being used.

Conclusion

Python’s built-in HTTP server provides a fast and convenient way to serve files and test web applications on Ubuntu.

You can start with a basic server using http.server, expose it to other devices through firewall configuration, build custom API endpoints, run the service automatically with systemd, and secure traffic using Nginx and Let’s Encrypt.