Set Up a Django Server with Apache Virtual Host and Python Virtual Environment
It took me some time to get everything working together, so I’d like to document the steps to save you time in the future.
Firstly, assume that you already have your CentOS/Ubuntu instance running and Python installed. Create a folder for your project and set the appropriate permissions:
sudo mkdir /opt/yourpath/projects
sudo chown $USER /opt/yourpath/projects
If you haven’t already initialized your project, you can do so with:
python -m pip install Django
django-admin startproject APPNAME /opt/yourpath/projects/APPNAME
By default, the server runs on port 8000:
python manage.py runserver
To prepare your Django server for production, edit the settings.py file with the following settings:
DEBUG = False
ALLOWED_HOSTS = ['*']
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Then, you can build the static files using:
python manage.py collectstatic --noinput
Next, serve your web application via the Apache web server. Assuming you installed Apache2 through yum or apt-get, enable virtual hosts for your project and create the following file:
touch /opt/yourpath/apache2/conf/vhosts/project-vhost.conf
With the content below:
<IfDefine !IS_APPNAME_LOADED>
Define IS_APPNAME_LOADED
WSGIDaemonProcess APPNAME python-home=/opt/yourpath/python python-path=/opt/yourpath/projects/APPNAME
</IfDefine>
<VirtualHost 127.0.0.1:80 _default_:80>
...
Remember to replace all instances of APPNAME with your Django project name. Then, create another file for HTTPS:
touch /opt/yourpath/apache2/conf/vhosts/project-https-vhost.conf
And populate it with similar content, replacing APPNAME as appropriate.
After updating the configurations, restart the Apache server. Your Django site should now be operational.
Lastly, isolate Python dependencies within a virtual environment to avoid dependency issues and version conflicts. Inside your project directory, run:
pip install virtualenv
virtualenv venv
source venv/bin/activate
This creates a folder containing all your Python executables. Subsequent pip install
commands will affect only this folder. Now, go back and edit project-vhost.conf and project-https-vhost.conf, changing the python-home
path to point to the venv
folder:
From:
WSGIDaemonProcess APPNAME python-home=/opt/yourpath/python python-path=/opt/yourpath/projects/APPNAME
To:
WSGIDaemonProcess APPNAME python-home=/opt/yourpath/projects/APPNAME/venv python-path=/opt/yourpath/projects/APPNAME
Be sure to point the Python home path to the venv
folder, not to the /bin
executable or the Python location, to avoid a 500 error. If you encounter issues, check the Apache server error log:
tail /opt/yourpath/apache2/logs/error_log
That’s it! Navigate to your public IP address, and you should see your Django page.
P.S. If you encounter a timeout error at the WSGI level:
Timeout when reading response headers from daemon process
Edit project-vhost.conf and project-https-vhost.conf to add the following line below WSGIDaemonProcess
:
WSGIApplicationGroup %{GLOBAL}
This addition can resolve timeouts caused by Python C extension modules, such as NumPy.