On debian based linux or ubuntu, install the apache server
sudo apt update
sudo apt install apache2
remove the default page using command
a2dissite 000-default
systemctl reload apache2
To configure Django application with apache, you need the mod_wsgi module installed for apache
sudo apt-get install libapache2-mod-wsgi
or
apt install libapache2-mod-wsgi-py3
To enable the module
a2enmod wsgi
You can configure the virtualhost that way you can run multiple sites differentiated by domain name, host and port. You can run multiple websites on same port by configuring apache virtualhosts using ServerName
To get started first create your configuration file at ‘/etc/apache2/sites-available/example.conf’
<VirtualHost *:80>
ServerName www.example.com
ServerAdmin webmaster@example.com
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIDaemonProcess example.com python-home=/path/to/venv python-path=/path/to/mysite.com
WSGIProcessGroup example.com
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
To enable the configured virtualhost or site
a2ensite example
systemctl reload apache2
Note that when you specify the conf/site to the a2ensite you don’t need to include the extension (conf)
After configuration, restart the apache then try to hit the URL (which would be according to ServerName configured) while error log is opend to trouble shoot if any
tail -f /var/log/apache2/error.log
Configure Static Content
Well great, at this point you should see you site working but, you might see site running fuzzy due to missing static files such as CSS and JavaScript.
To collect all static files into single directory djang offers the management command “python manage.py collectstatic” so that you can configure it on web server or serve them from AWS s3. Before using this command you must configure the “STATIC_ROOT” in settings.py
python manage.py collectstatic
After running this command all static files will collected to folder specified in STATIC_ROOT setting
You can update the apache conf to serve these static files on specific path configured using Alias directive
Alias /media/ /path/to/mysite.com/media/
Alias /static/ /path/to/mysite.com/static/
If you are getting “403 Forbidden” tweak the apache configuration to provide the enough permissions. Typicall you will see error like “client denied by server configuration” in apache error logs
Assuming you are using the apache2 version 2.4, you need to configure
<Directory /path/to/site.com/static>
Require all granted
</Directory>
Here is the final configuration that would look like
<VirtualHost *:80>
ServerName example.com
ServerAdmin webmaster@example.com
Alias /static/ /opt/mysite.com/static/
WSGIScriptAlias / /opt/mysite.com/mysite.com/wsgi.py
WSGIDaemonProcess example.com python-home=/opt/empenv python-path=/opt/mysite.com
WSGIProcessGroup example.com
<Directory /opt/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
<Directory /opt/mysite.com/static>
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Configure HTTPS using Let’sEncrypt
To enable the HTTPS for deployed Django application on Apache we need to the private key and SSL certificate. Where SSL certificate is the public key and information about website signed by well known certificate authority. Usually SSL certificate authority or provider like comodo, giticert, Thawte charge to issue the certificate of validity 1 year or 2 years. But, in this tutorial we will use the Let’sEncrypt which certificate authority issues certificates for free but for 3 months only.
certbot is the command line application which assists us to get certficate from Let’sEncrypt authority. Let’s install certbot for apache
sudo apt install certbot python3-certbot-apache
By this point you should have the Django web application configured using VirtualHost over port 80 (HTTP). After certbot is installed run the following command to acquire the SSL certficates and auto configure the apache for HTTPS with redirections
sudo certbot --apache
If multiple websites are configured on Apache, and you wanted to configure certificates for only specified one. Run the certbot with -d option
certbot --apache -d example.com
Start the auto-renewal timer using following command
sudo systemctl enable certbot.timer
Here is the final auto configured, apahce ssl configuration file of website by certbot
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName example.com
ServerAdmin webmaster@example.com
Alias /static/ /opt/mysite.com/static/
WSGIScriptAlias / /opt/mysite.com/mysite/wsgi.py
WSGIDaemonProcess example.com python-home=/opt/empenv python-path=/opt/mysite.com
WSGIProcessGroup example.com
<Directory /opt/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
<Directory /opt/mysite.com/static>
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Troubleshooting
WSGIPythonHome cannot occur within <VirtualHost>
Error: WSGIPythonHome cannot occur within <VirtualHost> section
AH00526: Syntax error on line 9 of /etc/apache2/sites-enabled/example.conf:
WSGIPythonHome cannot occur within <VirtualHost> section
Action 'start' failed.
The Apache error log may have more information.
To resolve this error you must use the WSGIDaemonProcess inside the VirtualHost instead of WSGIPythonHome
Certbot failure due to duplicate WSGI daemon
Error while configuring the SSL using certbot
Error while running apache2ctl configtest.
Action 'configtest' failed.
The Apache error log may have more information.
AH00526: Syntax error on line 11 of /etc/apache2/sites-enabled/mysite.conf:
Name duplicates previous WSGI daemon definition
As a workaround for this issue when using certbot, you can comment the following while using certbot and then uncommend after certficates are deployed.
WSGIScriptAlias
WSGIDaemonProcess
WSGIProcessGroup
This issue is due to the bug of certbot issue 4880 . Once certficates are installed successfully, uncomment the above 3 directives from ssl configuration added by certbot
Leave a Reply