Django Apache Setup (mod_wsgi) – Complete Deployment Guide

Last updated 1 month, 2 weeks ago | 131 views 75     5

Tags:- Python Django

Deploying a Django application with Apache and mod_wsgi is a stable, secure, and production-ready method. This guide walks you through setting up Apache to serve your Django project on a Linux-based server (Ubuntu/Debian).


Requirements

Before starting, make sure you have:

  • A Linux server (Ubuntu/Debian preferred)

  • Apache installed

  • Python and Django installed (usually in a virtual environment)

  • Your Django project ready to deploy


Step 1: Install Apache and mod_wsgi

Install Apache and mod_wsgi for Python 3:

sudo apt update
sudo apt install apache2 libapache2-mod-wsgi-py3

mod_wsgi bridges Apache and Python, allowing Apache to serve Python-based applications like Django.


Step 2: Prepare Your Django Project

Let's assume your Django project is located at:

/var/www/myproject/

Structure:

/var/www/myproject/
├── manage.py
├── myproject/
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── myapp/
└── venv/

Activate your virtual environment:

cd /var/www/myproject/
python3 -m venv venv
source venv/bin/activate
pip install django

Also install mod_wsgi if you're using it with a virtual environment:

pip install mod_wsgi

Then run:

mod_wsgi-express module-config

Copy the output lines and save them — you'll need them in your Apache config (it sets Python paths).


Step 3: Collect Static Files

Django doesn’t serve static files in production — you must collect them:

python manage.py collectstatic

Make sure STATIC_ROOT is defined in your settings.py:

STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

Step 4: Configure Apache Virtual Host

Create a configuration file for your site:

sudo nano /etc/apache2/sites-available/myproject.conf

Paste the following:

<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName myproject.com
    ServerAlias www.myproject.com

    DocumentRoot /var/www/myproject

    Alias /static/ /var/www/myproject/static/
    <Directory /var/www/myproject/static>
        Require all granted
    </Directory>

    <Directory /var/www/myproject/myproject>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    WSGIDaemonProcess myproject python-home=/var/www/myproject/venv python-path=/var/www/myproject
    WSGIProcessGroup myproject
    WSGIScriptAlias / /var/www/myproject/myproject/wsgi.py

    ErrorLog ${APACHE_LOG_DIR}/myproject_error.log
    CustomLog ${APACHE_LOG_DIR}/myproject_access.log combined
</VirtualHost>

Replace paths and domain names accordingly.


Step 5: Enable the Site and Restart Apache

sudo a2ensite myproject
sudo systemctl restart apache2

Ensure mod_wsgi is enabled:

sudo a2enmod wsgi

⚙️ Step 6: Update Django Settings for Production

  • Allowed Hosts

ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']
  • Disable Debug

DEBUG = False
  • Secure Settings (Optional)

CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SECURE_BROWSER_XSS_FILTER = True

Step 7: Test Your Deployment

Visit your domain (or IP) in the browser. You should see your Django site running through Apache!

If not:

  • Check error logs:

    sudo tail -f /var/log/apache2/myproject_error.log
    
  • Look for Python tracebacks or permission errors.


Example Directory Structure Recap

/var/www/myproject/
├── manage.py
├── static/
├── venv/
├── myproject/
│   ├── settings.py
│   ├── wsgi.py
│   └── ...
└── myapp/

Tips and Best Practices

Tip Description
Use mod_wsgi-express config Prevents common Python path errors
Use virtualenv Keeps dependencies isolated
Set permissions Apache must be able to read project files
Use collectstatic Django doesn't serve static files in production
Keep secrets out of settings.py Use environment variables or .env files
Use ufw or a firewall Open only needed ports (80/443)
Use HTTPS Set up Let’s Encrypt for free SSL
Use gunicorn or uWSGI + Nginx For more scalable alternatives

Common Pitfalls

Problem Cause Fix
500 Internal Server Error Bad WSGI path or syntax error Check wsgi.py and Apache error logs
Static files not loading Alias /static/ misconfigured or missing collectstatic Check Apache conf and run collectstatic
Site doesn't load Apache not restarted Run sudo systemctl restart apache2
Permission denied Wrong ownership of files Use sudo chown -R www-data:www-data /var/www/myproject
Not serving media files Missing Alias for /media/ Add similar config like static for media

Serving Media Files (Optional)

Add this to your Apache config to serve user-uploaded media files:

Alias /media/ /var/www/myproject/media/
<Directory /var/www/myproject/media>
    Require all granted
</Directory>

Make sure MEDIA_URL and MEDIA_ROOT are set in settings.py.


Conclusion

Deploying Django with Apache and mod_wsgi provides a robust and scalable solution for production environments. While slightly more complex than using a built-in development server, it offers performance and security benefits crucial for real-world applications.