Deploy to Apache

Hello,

I need a solid, up-to-date guide to help me deploy my Django site to Ubuntu 20.04 with Apache and mod_wsgi.

This one is not working. It leads to “index of” page, not my homepage.

Thank you.

My initial guess is that you’ve got something that doesn’t match up quite right.

Please post your httpd.conf file for your application, along with your root urls.py file and any settings you may have that would be affected by this, along with the url that you are trying to use that gives your the “index of” page.

Hello,

I have followed more than 10 tutorials, each one with a totally different approach, and every time I had to start fresh. What I have now is a fresh DigitalOcean droplet, Ubuntu 20.04, Apache and mod_wsgi installed.

Here’s my configuration:

<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName mydomain.com
ServerAlias www.mydomain.com
DocumentRoot /var/www/mydomain.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

RewriteEngine on
RewriteCond %{SERVER_NAME} =mydomain.com [OR]
RewriteCond %{SERVER_NAME} =www.mydomain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

My Django project is here: https://github.com/OmidShojaee/omidshojaee.com

Nothing fancy. Just a simple homepage.

Please you tell me what should I put in my config file to make it work in Daemon mode.

Thank you very much.

Unfortunately, deployment is not a “cookbook” style issue. There are far too many variables including things like virtual environments and file systems and permissions and app locations, etc, etc, to provide a one-size fits all answer to your question.

That’s why we ask for you to post the complete configuration file components relative to your situation. It is possible to perhaps identify specific issues that way.

Hello,

I have provided the Apache config file and my code is available on Github. Please let me know what else is required.

You haven’t supplied any of the WSGI-specific configuration parameters that link mod_wsgi to your application.

That’s what I’m looking for.

Follow the tutorial that you linked to at the top - making all the appropriate settings for your environment. We don’t know your environment. We don’t know your directory structure, or any of a host of other bits of information that may be important.

You mentioned at start that you were getting the index page. The index page by itself is not an indication of something being wrong or not done correctly. It could be something as simple as a path or URL mis-specified.

But that needs to be our starting point here. We can’t start from scratch.

I followed this tutorial and this is what I get when browsing omidshojaee.com:

Screenshot 2020-11-16 104243

Here’s my configuration showing the directory structure as well:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName omidshojaee.com
    ServerAlias www.omidshojaee.com
    DocumentRoot /var/www/omidshojaee.com
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =omidshojaee.com [OR]
    RewriteCond %{SERVER_NAME} =www.omidshojaee.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

    Alias /static /var/www/omidshojaee.com/static
    <Directory /var/www/omidshojaee.com/static>
        Require all granted
    </Directory>

    <Directory /var/www/omidshojaee.com/website>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    WSGIDaemonProcess website python-home=/var/www/omidshojaee.com/venv python-path=/var/www/omidshojaee.com
    WSGIProcessGroup website
    WSGIScriptAlias / /var/www/omidshojaee.com/website/wsgi.py
</VirtualHost>

The big difference between what you have configured here and what their tutorial presents is that you have placed your code within your document root. They show the code residing outside that root to prevent people from browsing to see your source code.

I’m guessing that because you have done it this way, it’s able to “match” the url to your file system before finding the match for the wsgi module.

As a general rule, you don’t want your code within your document root. (Static files, sure, but not your code.)

Ok I’ll redo everything according to the tutorial. Let’s see how it works.

This is my new config. Everything is moved to my home directory.

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName omidshojaee.com
    ServerAlias www.omidshojaee.com
    DocumentRoot /var/www/omidshojaee.com
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =omidshojaee.com [OR]
    RewriteCond %{SERVER_NAME} =www.omidshojaee.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

    Alias /static /home/omid/websites/omidshojaee.com/static
    <Directory /home/omid/websites/omidshojaee.com/static>
        Require all granted
    </Directory>

    <Directory /home/omid/websites/omidshojaee.com/website>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    WSGIDaemonProcess omidshojaee python-home=/home/omid/websites/omidshojaee.com/venv python-path=/home/omid/websites/omidshojaee.com
    WSGIProcessGroup omidshojaee
    WSGIScriptAlias / /home/omid/websites/omidshojaee.com/website/wsgi.py
</VirtualHost>

But I see the exact ‘index of’ page again (the image I attached to my post above).

I’ll assume that you did restart apache after making these changes, and that you have all the appropriate permissions set on your home directories - have you checked the apache logs (probably /var/logs/httpd/) to see if there were any relevant messages there? Can you, while logged on to that server, run manage.py? (That’s just to check/verify that all the packages are installed correctly.)

(I will admit, I’m having a hard time seeing how your RewriteRule is going to work - I don’t believe it’s a valid rule - but then I haven’t worked with Apache RewriteRules in more than 5 years - probably closer to 10 - and so I don’t really remember all the various options and how they interrelate.)

Yes Apache (and the VM itself) is restarted several times. And with manage.py runserver, I get the default Django page which means everything looks fine.

But when I checked the error log of Apache I found this:

Exception ignored in: <function Local.__del__ at 0x7fe81019c4c0>
Traceback (most recent call last):
  File "/home/omid/websites/omidshojaee.com/venv/lib/python3.8/site-packages/asgiref/local.py", line 96, in __del__
NameError: name 'TypeError' is not defined
Exception ignored in: <function Local.__del__ at 0x7fe81019c4c0>
Traceback (most recent call last):
  File "/home/omid/websites/omidshojaee.com/venv/lib/python3.8/site-packages/asgiref/local.py", line 96, in __del__
NameError: name 'TypeError' is not defined
Exception ignored in: <function Local.__del__ at 0x7fe81019c4c0>
Traceback (most recent call last):
  File "/home/omid/websites/omidshojaee.com/venv/lib/python3.8/site-packages/asgiref/local.py", line 96, in __del__
NameError: name 'TypeError' is not defined

I have no idea what that means

Unfortunately, I don’t have any specific answers for you on this, just some thoughts and ideas that might apply.

I have typically seen this when something isn’t right in the venv. It could be a permissions issue. You’ll want to ensure that everything within your venv is readable (and executable where appropriate) by the id running apache - usually www-data in Ubuntu.
If you’re using symbolic links in your venv to refer to libraries elsewhere in your system, www-data needs access to those libraries as well.

For diagnosing this, I might change LogLevel to Info in apache to see if more detailed information is provided.

Are you using the system-standard installation of Python, or have you loaded a different version? I know I’ve run across situations where a version mis-match between a wsgi server and the version of Python being used by Django has caused problems. (Ancient history, but potentially still valid)

If you have root access to that system, or at least sudo to where you could run something as a different user, you could try running manage.py as www-data to see if it is a permissions issue or if you can get more details from the command line.

This is interesting — https://github.com/GrahamDumpleton/mod_wsgi/issues/568

This implies to me that that error may not be an issue needing to be addressed and might not be at all relevant to your app not working.

Thanks.

DigitalOcean has launched a PaaS and I’m going to try it.

Let’s see what happens.

It turns out DigitalOcean’s App Platform is a terrible PaaS.

And now I understand what is the problem: it’s https not wsgi.

I have SSL installed and Apache is configured to redirect http to https.

And in settings.py I have the following lines:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

But it doesn’t work.

If I remove the below lines from Apache config file (to redirect http to https):

RewriteEngine on
RewriteCond %{SERVER_NAME} =www.omidshojaee.com [OR]
RewriteCond %{SERVER_NAME} =omidshojaee.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

and browse with http, I see my Django site.

So clearly my Django settings are not working with https redirect.

I have already checked the documentation and not found the answer.

I’d verify that what you’re redirecting to is what you’re expecting it to be. I’d want to know exactly what is being generated by this rule.

I have already checked the log and didn’t find anything.

Apache is doing what it is supposed to do: redirect http to https. It is Django refusing to work properly.