Django Apache Setup (mod_wsgi) – Complete Deployment Guide
Last updated 1 month, 2 weeks ago | 131 views 75 5

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 yoursettings.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.