DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
World desk11 min

How to Run Python Apps on a LAMP Server with Ubuntu

Deploy a Python WSGI application on an Ubuntu LAMP server: install Apache and mod_wsgi, create a compatible virtual environment, configure Flask or Django, serve PHP alongside Python, and troubleshoot common failures.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Apache with Ubuntu’s packaged WSGI module, a project-owned virtual environment, and an Apache daemon process group. The supported path is apache2 plus libapache2-mod-wsgi-py3. Apache can then route Python WSGI requests to Flask or Django while continuing to serve PHP, static files, and other sites on the same server. Put the project under a service-readable directory such as /srv/myapp, expose an application callable from a WSGI file, map it with WSGIScriptAlias, test the configuration, and reload Apache.

This design is for WSGI frameworks. FastAPI and Starlette are ASGI frameworks and need an ASGI server behind a proxy instead of being loaded directly by mod_wsgi.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What Apache, Python and LAMP are doing together

Apache is the public HTTP server. It accepts a request, selects a virtual host, and either serves a file directly or passes the request to a handler. PHP requests can continue through the server’s existing PHP setup, while a URL such as /myapp is handed to mod_wsgi. mod_wsgi loads Python into Apache-managed processes and invokes the WSGI callable exposed by your application.

Ubuntu’s server documentation treats Apache as part of a LAMP-style stack that can include Linux, Apache, MySQL and Python. In practice, adding a Python site does not require removing PHP. You can keep a PHP document root such as /var/www/html and give the Python application its own URL prefix or hostname.

#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter | 4Pack Type C Female to A Male Cable Converter for Apple Duo 17 16 15 14 Plus,iWatch Watch 12 11 10,iPad 9 8 Air,Airpods 5 4
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.

Typical request flow

  1. The browser requests https://example.com/myapp/.
  2. Apache selects the matching virtual host.
  3. WSGIScriptAlias maps the URL to a WSGI script.
  4. mod_wsgi starts or reuses the configured daemon process group.
  5. The daemon imports your WSGI module and calls its application object.
  6. The response returns through Apache, which can still serve static assets directly.

Prerequisites and a safe project layout

You need an Ubuntu server with administrative access, a DNS name if the application will be public, and an application that supports WSGI. Install the Python interpreter and virtual-environment support from Ubuntu’s packages, and keep the deployment in a path Apache can traverse.

  • A supported Ubuntu installation with sudo access.
  • Apache 2 installed from Ubuntu packages.
  • Python 3 and the venv module.
  • A WSGI-compatible Flask, Django or similar application.
  • Application dependencies pinned in a requirements file or equivalent package manifest.
  • A project directory outside an inaccessible home directory, for example /srv/myapp.
  • A DNS record and firewall rules appropriate for HTTP and, later, HTTPS.

A layout like this keeps code, the virtual environment and static files easy to address from Apache:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
/srv/myapp/
├── .venv/
├── requirements.txt
├── myapp.wsgi
├── myapp/                 # Flask package, or Django project package
└── static/                # files Apache can serve directly

The Apache service account must be able to read the WSGI file, import the package and traverse every parent directory. Do not make the whole tree writable by the web service; grant write access only to directories that genuinely need it.

Install Apache and Ubuntu’s mod_wsgi package

  1. Update package indexes.
    sudo apt update
  2. Install Apache.
    sudo apt install apache2
  3. Install the distribution WSGI module.
    sudo apt install libapache2-mod-wsgi-py3

    Ubuntu enables this module automatically in the normal package installation. If it was disabled previously, enable it explicitly:

sudo a2enmod wsgi

Restart Apache after changing loaded modules:

sudo systemctl restart apache2

The Ubuntu package is the simplest supported route because it is built for the distribution’s Python integration. A PyPI-built mod_wsgi is another option when you need a different build, but it introduces a critical constraint: the module is compiled against one specific Python installation.

Create the application virtual environment

Create the environment with the same Python installation used to build the mod_wsgi module. A virtual environment isolates packages; it does not change the Python version embedded in mod_wsgi.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter | USB C Dongle with 90W Max Power Delivery, 3×5Gbps USB A Data Ports, for MacBook, Dell, and More (Charger Not Included)
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
sudo mkdir -p /srv/myapp
sudo chown -R $USER:$USER /srv/myapp
cd /srv/myapp
python3 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt

If your project does not yet have a dependency file, install its framework and then record the exact versions in one. For a deployment, install those pinned dependencies into /srv/myapp/.venv, not into the system interpreter. Leave the environment in a location Apache can read; a virtual environment inside a private home directory commonly fails because Apache cannot traverse the home directory even when the files themselves are readable.

Flask package example

Suppose the project contains /srv/myapp/myapp/__init__.py and that module creates a Flask object named app. The virtual environment must contain Flask and every package imported by that module:

cd /srv/myapp
. .venv/bin/activate
python -m pip install Flask
python -m pip freeze > requirements.txt

Use your project’s normal dependency-management process instead of overwriting a carefully maintained lock file with pip freeze.

Django package example

A Django project generated with django-admin normally includes a generated wsgi.py. Install Django and the project’s dependencies into the same environment, then identify the directory containing that file, for example /srv/myapp/project/wsgi.py.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a WSGI entry file

mod_wsgi looks for a module that exposes an object named application. The object is the WSGI callable; a file that merely defines a framework app under another name will not work until it aliases that object.

Flask

Create /srv/myapp/myapp.wsgi:

from myapp import app as application

The import must succeed when run with the project directory on Python’s path. If your Flask object is created by a factory, call that factory in the WSGI file instead:

Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter | 85W Max PD, 2 USB 3.0 & 1 USBC Data Ports, SD/TF Card Reader, for Laptops/Mac and Other Type C Devices (Charger Not Included)
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
from myapp import create_app
application = create_app()

Keep startup work deterministic. Import-time errors, missing environment variables and database connection failures appear as Apache 500 responses, so verify the application can import with the deployment environment before blaming Apache.

Django

Django’s generated WSGI module normally already contains the required callable:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import os
from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
application = get_wsgi_application()

You can point Apache directly at that generated file, or create a small wrapper that imports it. The value of DJANGO_SETTINGS_MODULE must match the project package and the module must be importable from the path supplied to the daemon process.

Configure an Apache virtual host

Create a site file under /etc/apache2/sites-available/, for example /etc/apache2/sites-available/myapp.conf. This example gives the application the /myapp URL prefix and runs it in daemon mode:

<VirtualHost *:80>
    ServerName example.com

    WSGIDaemonProcess myapp 
        python-home=/srv/myapp/.venv 
        python-path=/srv/myapp
    WSGIProcessGroup myapp
    WSGIScriptAlias /myapp /srv/myapp/myapp.wsgi

    <Directory /srv/myapp>
        Require all granted
    </Directory>

    Alias /myapp/static/ /srv/myapp/static/
    <Directory /srv/myapp/static>
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/myapp-error.log
    CustomLog ${APACHE_LOG_DIR}/myapp-access.log combined
</VirtualHost>

Replace example.com with the hostname in your DNS record. If the application should own the whole hostname, map the root URL instead:

WSGIScriptAlias / /srv/myapp/myapp.wsgi

Use a distinct virtual host and hostname when you want PHP and Python sites to have independent routing. A URL-prefix deployment is convenient when an existing PHP site must remain at the root.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray | Data transfer & Fast charging for MacBook, iPhone 17/16/15, iPad, Samsung Galaxy, Apple Watch
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft

What each directive controls

Directive Purpose
WSGIDaemonProcess Creates a named daemon process group and associates it with the virtual environment and project path.
WSGIProcessGroup Selects that daemon group for requests handled by this virtual host.
WSGIScriptAlias Maps a URL path to the WSGI script that exposes application.
Alias Lets Apache serve static files without sending them through Python.
Require all granted Allows Apache to serve the selected directory; limit the directory scope rather than granting access to unrelated paths.

Daemon mode is the usual choice for an ordinary deployment because the application gets its own process group instead of sharing an application process with unrelated Apache modules. The process group still uses the one Python version linked into the loaded mod_wsgi module.

Enable the site, validate it and reload Apache

  1. Enable the virtual host:
sudo a2ensite myapp.conf
  1. Check the complete Apache configuration before reloading:
sudo apachectl configtest

Continue only when the result is Syntax OK. A typo in a virtual-host file can otherwise prevent Apache from reloading.

  1. Reload Apache so existing connections are handled gracefully:
sudo systemctl reload apache2
  1. Request the application URL and inspect the dedicated error log if the browser reports a 500:
sudo tail -f /var/log/apache2/myapp-error.log
sudo tail -f /var/log/apache2/error.log

For a first test, use the exact URL represented by the alias, such as http://example.com/myapp/. A request to the wrong hostname can select a different virtual host and make a correct Python configuration appear broken.

Serve PHP and Python on the same Ubuntu server

Yes. Apache chooses a handler by URL, virtual host and file mapping. Keep PHP at the existing document root and assign Python a separate prefix or host:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Request Typical handler
http://example.com/index.php Existing PHP handler or PHP-FPM configuration
http://example.com/myapp/ mod_wsgi through WSGIScriptAlias
http://example.com/myapp/static/site.css Apache Alias, not Python

Avoid overlapping aliases. If WSGIScriptAlias / is used at the root of a virtual host, that host is dedicated to Python; do not expect PHP files in the same root to be selected automatically. Use separate hostnames or a narrower prefix when both applications need to coexist.

Choose embedded mode, daemon mode or separate instances

Deployment choice When it fits Important boundary
Embedded mod_wsgi Simple internal setups where the application can share Apache worker processes. The application shares process space with other Apache work and modules.
Daemon-mode mod_wsgi Most standalone Flask or Django deployments. Still uses the Python version linked into this Apache’s mod_wsgi module.
Separate mod_wsgi-express instances Applications that genuinely require different linked Python versions. Put a front-end Apache in proxy mode and manage each instance separately.
ASGI server behind Apache FastAPI, Starlette and other ASGI applications. These frameworks do not natively run on a WSGI server.

Daemon mode isolates the application process group, but it is not a Python-version boundary. Treat it as process and package isolation, not as a way to load a second interpreter into the same Apache.

Best Value
Sale
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display | 85W Max PD, 1 Powered USB-C 5Gbps & 2 Powered USB-A 3.0 5Gbps Data Ports, for MacBook Pro, MacBook Air, Dell and More (Black)
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Understand the one-Python-version limit

Apache loads one copy of mod_wsgi, and that module has one Python library bound into it. You can create several virtual environments for separate applications, but those environments must be compatible with that linked Python version. A virtual environment made with Python 3.12 cannot make a mod_wsgi module built for Python 3.10 execute 3.12 code.

When two applications require different Python versions, run separate mod_wsgi-express instances built for the respective interpreters and place a front-end Apache in proxy mode. If you do not need that split, standardize the server on one supported Python build and use per-project virtual environments.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

FastAPI and Starlette require an ASGI design

FastAPI and Starlette are ASGI frameworks. They do not natively run on a WSGI server, so pointing WSGIScriptAlias at an ASGI application is the wrong architecture. Start an ASGI-compatible server for the application and configure Apache as the public-facing reverse proxy. Keep the ASGI process supervised, bind it to a private interface or socket, and let Apache handle the public hostname, TLS and static files.

Flask and Django can be deployed through their WSGI interfaces as described above. Some newer framework features may also have ASGI entry points; choose the interface that matches the server you intend to run rather than forcing an adapter into mod_wsgi.

Static files, uploads and permissions

Static assets should normally be served by Apache with Alias. This avoids spending Python worker time on immutable CSS, JavaScript and image files. Ensure the target directory is readable and every parent directory is traversable by Apache.

Keep user uploads separate from executable source code. If the application needs to write uploads, grant write permission only to that upload directory and do not make the entire project tree writable. A 403 response usually indicates a filesystem traversal or Apache authorization problem; a 404 for a static asset often means the URL prefix and Alias target do not match.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Add HTTPS before public exposure

Do not expose a production login or API over HTTP alone. Ubuntu documents enabling mod_ssl and using a default SSL virtual-host file. Obtain a certificate through a separately verified certificate workflow, configure the certificate and key in the SSL virtual host, and redirect ordinary HTTP traffic to HTTPS after testing.

Keep the same WSGI mapping in the HTTPS virtual host. Verify that cookies, absolute URLs, API callbacks and any proxy headers are correct under the secure scheme. Renew certificates before expiry and test the renewal process rather than waiting for an outage.

Troubleshoot failures in the order they occur

Symptom Likely cause Check or fix
Apache will not reload Syntax error or an invalid directive. Run sudo apachectl configtest; correct the reported file and line before retrying.
404 at the application URL Wrong hostname, URL prefix or WSGI script path. Confirm the selected virtual host, the exact WSGIScriptAlias path and that the file exists.
500 with an import error Dependency missing, wrong python-path or an application startup exception. Read the Apache error log, activate the deployment environment manually and test the same import.
500 mentioning an incompatible Python package The virtual environment was created with a Python version different from mod_wsgi’s linked interpreter. Rebuild the environment with the matching Python installation or use a separate mod_wsgi instance.
403 for the WSGI file or static directory Apache cannot traverse a parent directory or the directory rule does not grant access. Check ownership and execute permissions on each parent, then review the relevant <Directory> block.
Static files return the application’s HTML The Alias is missing, ordered incorrectly or points to the wrong directory. Make the static URL and filesystem target explicit and reload Apache.
PHP works but Python does not The request is landing in a different virtual host or the Python alias overlaps the PHP document root. Test the configured hostname and use a distinct prefix or virtual host for Python.

Read both Apache’s global error log and the application-specific log. A browser’s generic 500 page hides the useful traceback; the server log identifies whether the failure happened while importing Python, loading the WSGI script, checking permissions or executing application code.

Production readiness checklist

  • Apache and libapache2-mod-wsgi-py3 are installed from Ubuntu packages.
  • The WSGI module is enabled, and Apache was restarted after module changes.
  • The virtual environment was created with the Python installation compatible with mod_wsgi.
  • Dependencies are installed and pinned inside that environment.
  • The WSGI file exposes an application callable.
  • The virtual host uses WSGIScriptAlias and a named daemon process group.
  • Static files are mapped with Alias and are not needlessly served through Python.
  • Apache configuration passes apachectl configtest before every reload.
  • Application and Apache logs are monitored for import, permission and runtime errors.
  • PHP and Python routes do not overlap accidentally.
  • Applications needing different linked Python versions use separate mod_wsgi instances.
  • ASGI applications use an ASGI server and proxy architecture instead of mod_wsgi.
  • HTTPS, certificate renewal and secure redirects are configured before public launch.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.