Serve a Python App from a VM: From Local Server to Public Access
In this guide, we’ll deploy a simple Python HTTP server on an AlmaLinux virtual machine and explore how network traffic flows from the VM to the host machine and beyond. By the end, you’ll be able to access your app from your local network and from external devices using a public tunnel.
Let's learn how to:
- Set up a Python HTTP server on a VM
- Access the server from the host machine
- Expose the VM to external devices via Localtunnel
- Understand the traffic flow from client to VM
In this setup, the AlmaLinux VM runs a Python HTTP server, the Fedora host acts as a KVM/QEMU host and NAT gateway, and the smartphone simulates an external client. We’ll show how to make the server accessible locally and over the internet using a tunnel.
1️⃣ Environment Setup
-
AlmaLinux 10 VM (Guest)
- IP:
192.168.122.88 - Runs the Python HTTP server
- IP:
-
Fedora Host
- IP:
192.168.0.136 - Acts as KVM/QEMU host and NAT gateway
- IP:
-
Smartphone / External Device
- Connected via mobile network (e.g., Airtel)
- Accesses the server through a public tunnel
┌─────────────┐
│ Smartphone │
│ (Mobile Data)│
└─────┬───────┘
│
▼
┌─────────────────┐
│ Public Tunnel │
│ (Localtunnel) │
└─────┬───────────┘
│
▼
┌─────────────┐
│ Fedora Host │
│ 192.168.0.136 │
│ KVM/QEMU + NAT│
└─────┬───────┘
│
▼
┌───────────────┐
│ AlmaLinux VM │
│ 192.168.122.88│
│ Python HTTP │
│ Server :8000 │
└───────────────┘
2️⃣ Start the Python HTTP Server on the VM
# Start Python HTTP server on all interfaces, port 8000
python3 -m http.server 8000 --bind 0.0.0.0
Explaination:
- The server serves the current directory as a simple web app.
- You can test locally inside the VM:
curl http://127.0.0.1:8000
Access from the Host Machine
The host machine can reach the VM directly using its private IP. This is useful for testing that the Python HTTP server is running before exposing it externally.
# Test access from Fedora host
curl http://192.168.122.88:8000
✅ Expected output:
- A directory listing of the files served by the Python HTTP server
- Or the contents of an index.html file if present
💡 Tip: If you see a connection refused error, make sure the Python server is running and bound to 0.0.0.0.
Access from External Devices / Smartphone
Smartphones or external devices on a different network cannot reach the VM’s private IP directly. To solve this, we use Localtunnel to create a public HTTPS URL that forwards traffic to the VM.
- Install Node.js and Localtunnel on the VM
# Install Node.js and npm (if not already installed)
sudo dnf install -y nodejs npm
# Install Localtunnel globally
sudo npm install -g localtunnel
- Start the tunnel
# Forward port 8000 to a public URL
lt --port 8000
-Localtunnel will generate a public URL, e.g., https://hot-deer-send.loca.lt
- Open this URL in your smartphone browser → you should see the Python app content.
💡 Tip: Each time you start Localtunnel, the URL changes unless you specify a custom subdomain.
Content Served by Python Server
By default, the Python HTTP server serves the current directory as a simple web app. Example directory structure:
/home/alok/systems-thinking
├── server.py
├── venv/
└── README.md
- Accessing the server URL lists these files automatically in HTML
- You can place an
index.htmlfile to serve a custom homepage
Traffic Flow Diagram
[Smartphone / Mobile Data]
│
▼
[Public Tunnel via Localtunnel]
│
▼
[Fedora Host 192.168.0.136]
(KVM/QEMU + NAT)
│
▼
[AlmaLinux VM 192.168.122.88]
Python HTTP Server :8000
- Smartphone requests → public tunnel → host → VM → Python server → response flows back the same way.
This completes the core tutorial flow: from environment setup → VM server → host access → external access → traffic understanding.
Top comments (0)