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

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Run Django behind Apache by loading mod_wsgi, mapping the site URL to your project’s wsgi.py with WSGIScriptAlias, and routing the virtual host to a dedicated daemon process group. Keep static and uploaded media outside Django’s request handler by exposing their directories with Apache Alias rules. Daemon mode is the recommended mode on non-Windows platforms because it separates the application from Apache’s other modules and makes multiple sites easier to isolate.

What the deployment looks like

A production request normally passes through Apache first. Apache serves files that you explicitly map, such as CSS, JavaScript, images, and uploaded media. Requests that do not match those aliases are sent to mod_wsgi, which imports Django through the project’s WSGI entry point and calls the application object defined there.

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

The important pieces have distinct jobs:

  • WSGIScriptAlias maps a URL prefix to the WSGI script, usually <project>/wsgi.py, and binds matching requests to mod_wsgi.
  • WSGIDaemonProcess defines a dedicated group of processes and the Python environment they use.
  • WSGIProcessGroup sends the virtual host’s WSGI requests to that named daemon group.
  • python-home selects the virtual-environment prefix in daemon mode.
  • python-path adds the directory from which your Django project package can be imported.
  • Alias exposes static and media directories directly through Apache rather than through Django.

A minimal daemon-mode virtual host has this shape:

WSGIDaemonProcess example.com python-home=/path/to/venv python-path=/path/to/project
WSGIProcessGroup example.com
WSGIScriptAlias / /path/to/project/mysite/wsgi.py

<Directory /path/to/project/mysite>
    <Files wsgi.py>
        Require all granted
    </Files>
</Directory>

Replace every path and the process-group name with values from your deployment. The name after WSGIProcessGroup must exactly match the name declared in WSGIDaemonProcess.

Prerequisites and layout

Use a compatible Python and mod_wsgi

mod_wsgi is compiled against a specific base Python version. The virtual environment named by python-home must have been created with that same base version. A virtual environment made with a different Python minor version can fail even when its directory and packages look correct.

#1 Best Overall
Sale
Compressed Air Duster,130000RPM Super Power Cordless Air Duster,Rechargeable Brushless Blower,3 Gear Adjustable Blower with LED Light,Dust Remover for Computer/House/Outdoor/Car
  • Powerful Turbo Fan:CAGIWIRU Electric Air Duster have reached speed up to 130000RPM,Can efficient remove dust and debris.With LED light and Three Adjustable Speed to meet with different cleaning tasks.
  • With Attached USB C Fasting Charging cable.Charing 3 hours,Enjoy up to 240 minutes of use on the lowest setting, For third speed can use for 25mins.with four charging options to meet with your needs.
  • Wide Application: attached 5 different nozzles,making it suitable for a variety of scenes, such as car,pet, pc, keyboards, and other electronic devices. It also serves for office and home clean duster.
  • Handy Design & Portable:Cordless air duster electric nozzle is Light weight and small size, design and comfortable to hold and space saving, convenient to carry around. You can put it in your room or inside the car without taking up space.
  • Economical &Reusable: Built durable materials with a long-lasting battery,our CAGIWIRU air duster it's a sustainable alternative to disposable air cans.

Before configuring Apache, establish:

  • The Python version used to build or install mod_wsgi.
  • The base Python version used to create the virtual environment.
  • The absolute path to the virtual-environment prefix, such as /srv/example/venv.
  • The absolute path to the directory containing the Django project package.
  • The absolute path to the WSGI script.
  • The directories that will hold collected static files and uploaded media.

Do not point python-home at the environment’s bin directory. It must point at the virtual-environment prefix itself.

Choose a predictable filesystem layout

An arrangement that keeps code, the environment, and web-served assets separate is easier to secure:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
/srv/example/
├── app/                    # project directory added with python-path
│   ├── manage.py
│   └── mysite/
│       ├── settings.py
│       ├── urls.py
│       └── wsgi.py
├── venv/                   # python-home points here
├── static/                 # output of collectstatic
└── media/                  # uploaded files

The names are illustrative. What matters is that the path in python-path is the directory from which the project package imports successfully, and that the paths used by Apache actually exist.

Install and verify mod_wsgi

Confirm that Apache loads the module

Use your operating system’s package or build process to install mod_wsgi, then verify that Apache reports the module as loaded. Distribution package names and module-enabling commands differ, so follow the package documentation for your platform rather than copying a command intended for another distribution.

Run Apache’s configuration check before every reload:

apachectl configtest

A successful syntax check does not prove that Django can import. It only proves that Apache can parse the configuration. Check the Apache error log after starting or reloading the site; mod_wsgi import and Python-version errors are normally reported there.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
EVEO® Screen Cleaner Spray Kit (Streak-Free) TV Screen Cleaner for Smart TV, Lcd, LEd, Oled | Computer Screen Cleaner Spray and Wipe Microfiber Cloth - TV, Monitor, Laptop, iPad, Car - 6.7oz 1 Pack
  • Screen Cleaner is Your Screen’s New Bestfriend! - EVEO is proud to present a screen cleaner that’s perfectly suited for your TV. Meet your new screen cleaner, computer screen cleaner, laptop cleaner, iPad cleaner, Macbook,tv cleaner or any other electronic device. Our screen cleaner spray and wipe along with the included plush microfiber cloth, easily removes dust, fingerprints & other smudges on the screen’s surface. Clean effectively for a streak-free screen
  • Gentle on your Screens - Our screen cleaner spray and wipes is compatible to be used even for the most sensitive LCD, LED, CRT, and OLED screens in proper use. Be at ease knowing that this product is compatible with all the major brands: LG, SONY, Samsung, Sharp, iPad, iPhone, Android screens, Kindle, PC monitors - we’ve got you covered! Can be used as LCD screen cleaner, tv cleaner, smart tv screen cleaner, and more
  • Premium Super Soft Plush Microfiber Cloth - Included in this efficient screen cleaning kit. This screen cleaner spray and wipe has our signature plush microfiber cloth specially designed to comply with screens and monitors and leave them streak-free. Has been shown to effectively absorbs stubborn stains, zero streaks, and no fiber shedding. Always use this together with our screen cleaner for the best results
  • Easy-to-Use Screen Cleaner Kit + microfiber cleaning cloth - The EVEO Screen Cleaning Kit will easily be your new favorite tool when it comes to taking care of the things you love most, quick and easy solution for a streak-free screen. Simply screw on the sprayer gun on the screen cleaner bottle. Spray the cleaning liquid onto the microfiber cloth, then wipe the screen until desired cleanliness & shine is achieved.
  • Quality Screen Care Kit Worth Purchasing - Enjoy a convenient Screen Cleaner anytime, anywhere you need it. Your satisfaction is our top priority. We stand behind the quality of our products and that’s why, you shouldn’t be worrying at all. We manufacture the Best Screen Cleaner. and can be used for laptop cleaning kit, laptop screen cleaner, tv screen cleaner for smart tv. MacBook screen cleaner, monitor cleaner or screen cleaner spray for electronic devices with microfiber cleaning cloth

Check the Python-version match

If Apache starts but the WSGI application fails to load, first compare the Python version used by mod_wsgi with the version used to create the virtual environment. Rebuilding the virtual environment with the matching base interpreter is usually safer than trying to work around a mismatch in Apache configuration.

Also verify that the module is built for the Python installation you intend to run. Loading a mod_wsgi module compiled for one interpreter while pointing python-home at another is not a supported substitute for rebuilding or installing a compatible module.

Configure a Django site in daemon mode

1. Prepare the project and environment

Install the project’s dependencies into the virtual environment and test the WSGI entry point in a controlled environment before placing Apache in front of it. Ensure that the project directory, the WSGI file, and the settings module are readable by the account under which Apache’s daemon processes run.

Set Django’s production settings separately from Apache configuration. In particular, use production-safe values for debugging, host validation, secret management, and database credentials. Keep secrets in the deployment environment or another protected configuration mechanism rather than in a web-served directory.

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

2. Define the daemon process

Add a WSGIDaemonProcess line inside the appropriate virtual-host configuration:

WSGIDaemonProcess example.com 
    python-home=/srv/example/venv 
    python-path=/srv/example/app

The first token after the directive is the daemon-group name. The python-home value is the virtual-environment prefix. The python-path value must contain the directory from which the Django project package imports; it is not necessarily the directory containing wsgi.py.

Rank #3
Sale
BladeHawks RGB Gaming Mouse Pad Extra Large Extended 31.5x12 Inch-Black | LED mouse pad with 14 lighting modes, covers keyboard & mouse, anti-slip rubber base, waterproof surface, USB powered
  • 【Large size】:Measuring 800 x 300 mm/ 31. 5×12 inches, which is wider and taller than others. Large mouse pad can perfectly fit your keyboard and mouse of any size, and there is also ample space for peripherals such as phones, tablets, etc.
  • 【LED backlight mouse pad】:Blade Hawks RGB mouse pad provides 7 static modes and 7 dynamic modes will give you the options you are looking for. Power-off memory function remembers the last lighting mode you selected. The super glow fiber Chroma will give you a colorful gaming setup that you want.
  • 【Anti-slip rubber base】:Made from Natural rubber, this gaming mousepad will firmly grip your desktop, allowing you to enjoy the ultimate precision in the games you are most passionate about. It also comes with a texture that enhances this ability even further.
  • 【Smooth and waterproof surface】: Micro-textured cloth surface, for extremely precise mouse control and a smooth movement. When liquid splashes on the gaming mouse pad, it forms water droplets and slides down. Will not delay your work or gameplay.
  • 【Plug and play】: This mouse and keyboard pad is powered by USB, plug and play, no driver required. One button control light modes. Press one time to change the lighting mode, press twice to change the brightness, press and hold about 3 seconds turn ON/OFF.

3. Route the virtual host to that group

WSGIProcessGroup example.com

This directive is what associates requests handled by the virtual host with the daemon group. A typo or different capitalization leaves the virtual host pointing at a group that does not exist.

4. Map the URL to wsgi.py

WSGIScriptAlias / /srv/example/app/mysite/wsgi.py

The first argument is the URL base path. Using / sends all requests not claimed by an earlier Apache mapping to Django. If you deploy under a prefix such as /portal/, use that prefix consistently in the alias and in Django’s URL and static-file settings.

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.

5. Grant access only to the WSGI script

<Directory /srv/example/app/mysite>
    <Files wsgi.py>
        Require all granted
    </Files>
</Directory>

The <Directory> path must contain the WSGI file, and the <Files> rule must name it correctly. Restricting the grant to wsgi.py avoids unnecessarily exposing other Python source files in the project directory.

6. Test, reload, and make a request

  1. Run apachectl configtest and correct every syntax error.
  2. Reload Apache using your operating system’s service manager.
  3. Request the site’s health endpoint or home page.
  4. Inspect the Apache and mod_wsgi error logs if the response is not the expected Django page.

Do not troubleshoot application code first. A missing module, wrong path, denied file, or process-group mismatch prevents Django from being called at all.

Understand each directive before changing it

Directive Purpose Frequent mistake
WSGIDaemonProcess Creates a named daemon process group and defines its Python environment and import path. Using a virtual environment made with a different base Python version, or omitting the project directory from python-path.
WSGIProcessGroup Routes the virtual host to the named daemon group. The name does not exactly match the WSGIDaemonProcess name.
WSGIScriptAlias Maps a URL base to the WSGI script and binds matching requests to mod_wsgi. The file path is wrong, the URL prefix is inconsistent, or a later edit breaks the handler binding.
python-home Selects the virtual-environment prefix used by daemon processes. Pointing to venv/bin instead of venv.
python-path Adds the project directory to Python’s module search path. Using the directory containing wsgi.py when the importable project package is one level higher.
<Directory> and <Files> Control Apache’s permission to access the WSGI script and web-served directories. Granting access to the wrong filesystem path or to the entire source tree.

Serve static files and uploaded media with Apache

Django does not serve static assets or uploaded media in a non-development server arrangement. Apache must serve them directly, or a separate web server must do so. Without an explicit mapping, requests for CSS, JavaScript, images, and admin assets commonly reach Django and end in 404 responses.

Collect static assets

Configure Django’s static-file destination for production, then run the project’s collectstatic command so application and admin assets are copied into the directory Apache will expose. The directory used by Alias must be the same directory produced by that command.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Vaydeer Wrist Rest for Keyboard and Mouse, Computer Ergonomic Wrist Support Pad, Soft Memory Foam Arm Cushion for Desk, Palm Hand Office Laptop Typing
  • 【Softer and More Comfortable】Vaydeer wrist rest has unique diamond pattern, which is the combination of softness and aesthetics. The materials of wrist rest are improved into higher quality memory foam and covered with silky smooth lycra. The computer wrist rest makes you as comfortable and cushiony as like rest your wrists on clouds.
  • 【Ergonomic Wrist Saver】The wrist rests for keyboard and mouse comes with a 17.32×3.15×0.83 inch keyboard wrist pad and a 5.94×3.15×0.83 inch mouse wrist support. Based on ergonomic design, the unique concave shape is the perfect fit for your wrist joints. The wrist rest pad fits most computer keyboards and laptops, improve hand and wrist posture, release your wrist and arm stress.
  • 【Non-Slip Rubber Bottom】Featuring an anti-skid silicone base on the bottom, this wrist keyboard support stays firmly in place on your desk, preventing the padding from sliding around, ensuring stable and consistent wrist support during extended computer sessions.
  • 【Better Experience & Pain Relief】Our keyboard arm rest is beneficial to alleviate the soreness caused by direct contact and friction between your arm and a hard desk surface, reducing the risk of wrist fatigue or carpal tunnel. The soft texture of memory foam can evenly distribute the pressure around your wrists and provide good support with just enough give.
  • 【Helpful in Multiple Scenarios】Whether you're working, studying, writing, typing, gaming, this keyboard and mouse rest combo is an essential accessory to add comfort and support to your hands and wrists. It’s also a great gift for men, women, family, friend, coworker, gamer, teacher, etc.

Add Apache aliases

Alias /static/ /srv/example/static/
Alias /media/ /srv/example/media/

<Directory /srv/example/static>
    Require all granted
</Directory>

<Directory /srv/example/media>
    Require all granted
</Directory>

Keep the trailing slash relationship consistent: a URL prefix ending in / should map to a filesystem path representing that directory. Place these aliases so Apache handles the asset requests before the catch-all WSGIScriptAlias / ... mapping.

Protect the source tree

Do not alias the project’s source directory as a public directory. Only the collected static directory and the media directory should be web-served. Uploaded media can contain user-controlled content, so review the file-handling and access policy for your application before making it public.

Diagnose a static-file 404

  • Confirm that collectstatic completed and that the requested file exists under the aliased directory.
  • Check that the URL uses the same prefix as the Alias directive.
  • Check filesystem permissions for the Apache service account.
  • Check that the <Directory> rule uses the real filesystem path and grants access.
  • Check that the alias is not shadowed by another virtual-host or URL mapping.
  • Remember that the Django admin’s CSS and JavaScript are static files too; they need the same Apache handling.

Daemon mode versus embedded mode

mod_wsgi can run Python inside Apache’s own worker processes (embedded mode) or in dedicated daemon processes (daemon mode). Django’s documentation recommends daemon mode on non-Windows platforms.

Concern Embedded mode Daemon mode
Process isolation Python runs in Apache’s process space and shares it with other loaded modules. Python runs in dedicated mod_wsgi daemon processes.
Interaction with Apache modules Application code shares the address space and lifecycle of Apache workers and their modules. The Django process group is separated from Apache’s main worker process space.
Restart and code changes Reload behavior is tied more closely to Apache worker restarts, which can increase restart and memory-management costs for Python applications. The application group can be managed independently from Apache’s front-end workers.
Memory and lifecycle Python memory is part of the Apache worker footprint. Python memory is accounted for in the dedicated daemon processes.
Multiple Django sites Sites share Apache process space, making isolation less explicit. Each site can have its own daemon process group and Python environment.
Recommended use Useful only when you have a specific compatibility or operational reason. The normal choice for production Django deployments on non-Windows systems.

Separate process groups do not replace application-level security, but they reduce accidental coupling between sites and make it clearer which environment owns a failure or restart.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Security hardening

Limit Apache’s filesystem grants

Grant access to the WSGI script and to the two web-served asset roots only. Avoid broad Require all granted rules over the project’s parent directory. A permissive rule can expose settings, source code, environment files, or deployment artifacts.

Prevent accidental source downloads

After every configuration change, verify that WSGIScriptAlias still binds the WSGI handler. If that binding breaks, Apache can fall back to treating a .py file as static content, potentially disclosing source code. A request to the WSGI path should execute the application, not display Python text.

Best Value
Sale
Under Desk Cable Management Tray No Drill, Metal Mesh Cable Management Under Desk with Clamp Mount, 2 Hole Cable Tray with Wire Management and Cord Organizer for Home Office Standing Desk
  • 【No Drill Mounted】Cable management tray can be assembled in as little as 3 minutes or less-simply. Side clips easily clampe the edge of desk, pass through the holes on the sides, and secure excess cables with baskets. Desk cable management supports inward or outward installation to meet your needs in different scenarios, and provides you with great convenience when collecting and organizing wires.
  • 【Rubber Pad Protects Desk】Wire organizer under desk built-in soft rubber pads on the clamp protect your desk from scratches, so you will not damage your furniture or office.
  • 【Sturdy and Beautiful】Cord management under desk is made of high-quality carbon steel and holds about 15 lbs. The wire basket has 2 holes on each side of the tray to enable your cables to pass freely. Cable baskets are suitable for desk thickness use from 0.4" to 2.4".
  • 【Space Saving & Keep Organized】Desk cable management tray holds all your power cords, outlet strips, USB hubs and computer transformers hidden from your feet, and the data cables will not enter the vacuum cleaner to keep your desk clean and tidy. Desk wire organizer is also suitable for use in the kitchen and outdoors.
  • 【Reduce Safety Risks】Cable tray under desk keeps all plugs away from your kids, no more worry about tripping. Using 2 holes wire tray saves extra space, helps you easily cabling and wire protection. The mesh design is not easy to accumulate dust, but avoids safety accidents caused by messy wires.

Use an appropriate service account

Run Apache and its daemon processes under the service account intended for the deployment. That account needs read and execute access to the application and virtual environment, write access only where the application genuinely requires it, and access to the static/media directories according to your upload policy.

Keep secrets out of public paths

Store database credentials, secret keys, and other sensitive values in the deployment environment or protected configuration. Never place them in the static directory, media directory, or any directory exposed with an Apache alias.

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

Isolate sites

Give each Django site its own daemon process-group name, virtual environment, project path, and static/media roots. This prevents a python-path or dependency change for one site from silently affecting another.

Updating code and dependencies safely

  1. Deploy the new code and dependencies into the intended project directory and virtual environment.
  2. Run Django’s deployment checks and the project’s migrations or other release steps using the deployment account.
  3. Run collectstatic when static assets changed, confirming that the output directory is the one Apache aliases.
  4. Run apachectl configtest before touching the running service.
  5. Reload Apache or restart the relevant daemon group according to your process-management procedure.
  6. Request a dynamic page and a known static asset, then inspect the logs for import, permission, or handler errors.

If a release changes the Python base version, rebuild mod_wsgi for that version and recreate the virtual environment rather than reusing the old environment.

Troubleshooting by symptom

Apache fails its configuration test

  • Read the exact file and line number in the error.
  • Check directive spelling, quoting, and closing tags for <Directory> and <Files>.
  • Confirm that the mod_wsgi module is installed and loaded before the virtual-host configuration is parsed.
  • Run the configuration test again after each correction; do not reload a configuration that still fails.

The site returns a server error immediately

  • Inspect Apache and mod_wsgi error logs first.
  • Confirm that WSGIScriptAlias points to an existing file.
  • Confirm that the WSGI script’s parent directory and the <Files wsgi.py> rule match the real path.
  • Check that the daemon group name in WSGIProcessGroup is identical to the one in WSGIDaemonProcess.
  • Check Python-version compatibility and import errors before changing Django code.

Django reports that a project module cannot be imported

  • Set python-path to the directory from which the project package imports, not merely to the directory containing wsgi.py.
  • Verify that the package is readable by the Apache service account.
  • Verify that dependencies were installed in the environment named by python-home, not in a different shell or user environment.
  • Check for a mismatch between the Python used to compile mod_wsgi and the Python used to create the virtual environment.

Static or admin files return 404

  • Run collectstatic and verify the requested file exists in its output directory.
  • Compare the browser URL with the Alias URL prefix character for character.
  • Check the alias order, filesystem path, and <Directory> permission rule.
  • Check read and traverse permissions for every parent directory.

A Python file is displayed instead of executed

Stop serving the site until the handler is corrected. Recheck that mod_wsgi is loaded, that WSGIScriptAlias points to the intended file, and that no later Apache rule overrides the WSGI mapping. Exposing source code can disclose credentials and application logic.

Changes appear to have no effect

  • Confirm that the edited virtual-host file is the one Apache has enabled.
  • Run apachectl configtest, then reload Apache.
  • Confirm that the request is reaching the expected host and daemon process group.
  • Check logs for the timestamp of the new request rather than relying on a cached browser response.

Final deployment checklist

  • mod_wsgi is loaded and compiled for the same base Python version as the virtual environment.
  • python-home points to the virtual-environment prefix, not its bin directory.
  • python-path contains the project directory required for imports.
  • WSGIScriptAlias points to an existing wsgi.py file.
  • WSGIProcessGroup exactly matches the daemon-process name.
  • The WSGI script has a narrowly scoped <Directory>/<Files> access rule.
  • Static and media directories have explicit aliases and matching permission rules.
  • collectstatic has populated the directory used by the static alias, including Django admin assets.
  • Apache passes apachectl configtest before each reload.
  • Logs have been checked after a dynamic request and a static-file request.
  • Secrets and source files are outside public aliases, and the service account has only the access it needs.

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.