Jeel Shah Jeel Shah - 4 months ago 23
Python Question

How can I fix a 403 forbidden on an apache server using Django?

I get the following error when I try to access my website:

Forbidden. You don't have permission to access / on this server.


My virtual host file looks like the following:

<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined


Alias /static ~/myproject/static

<Directory ~/myproject/static>
Require all granted
</Directory>

<Directory ~/myproject/myprojectapi>
Order allow,deny
Require all granted
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>


And my
apache2.conf
is the default file. I am using
Django 1.9 with Python 2.7 on Ubuntu 14.04


I have literally attempted most, if not all, the solutions found on the site but none of them are working for some reason. I followed this tutorial and gave these permissions:

chmod 664 ~/myproject/db.sqlite3


sudo chown :www-data ~/myproject/db.sqlite3


sudo chown :www-data ~/myproject


I am also operating as the
root
user.

Please let me know if you require any other information; I will be more than happy to provide it. Any help would be greatly appreciated.

Here are the WSGI lines:

WSGIDaemonProcess goggest python-path=~/myproject:/usr/lib/python2.7/dist-packages
WSGIProcessGroup goggest
WSGIScriptAlias / ~/myproject/myprojectapi/wsgi.py

Answer

Below is how I fixed (with a lot of help) the problem. This answer assumes you have the following project structure:

~/myproject
    - myproject
      - ...
      - settings.py
      - wsgi.py
    - myapp
      - ...
      - static
        - myapp
          - ...

Digression

I was facing the problem where I got an error in my apahce error.log which said it could not find settings. This issue is most likely caused by an error in your python-path. This portion assumes that you are using the daemon method (recommended by docs).

  1. Check your wsgi.py file and make sure it says myproject.settings instead of settings in os.environ.setdefault(" ... ", " ... ")
  2. Check and double check your python-path which should be something like WSGIDaemonProcess [any-name] python-path=/home/[username]/myproject:/usr/lib/python2.7/site-packages

This should fix the problem (at least it did for me).

Fixing 403 Forbidden (or at least, circumventing it)

The following is the conf that did the job for me. It is not apache2.conf and there is nothing new in my apache2.conf, it remains the default one. The following is in apache2/sites-available/000-default.conf.

<VirtualHost *:80>
        ServerAdmin webmaster@localhost

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        DocumentRoot /home/[username]/myproject # (1)

        Alias /static path/to/your/static_root    # (2)

        <Directory path/to/your/static_root>
                Require all granted
        </Directory>

        <Directory /home/[username]/myproject/myproject>
            Options Indexes FollowSymLinks Includes ExecCGI
            AllowOverride All
            Order allow,deny
            Allow from all
            Require all granted
        </Directory>

        <Directory /home/[username]/myproject/myproject>
                <Files wsgi.py>
                        Require all granted
                </Files>
        </Directory>

        WSGIDaemonProcess [any-name] python-path=/home/[username]/myproject:/usr/lib/python2.7/site-packages
        WSGIProcessGroup [any-name]
        WSGIScriptAlias / /home/[username]/[myproject]/[myproject]/wsgi.py

        WSGIApplicationGroup %{GLOBAL}

</VirtualHost>

RE: Points (1), (2)

(1). Change the document root to the head of the directory which contains your django project files. In this case, I changed it to /home/[username]/myproject. Do not use ~/ for reference. I tried that and it didn't seem to pan out.

(2). If you are serving your static files from the same server then make sure you have set a STATIC_ROOT and STATIC_URL in your settings.py file. In my case, I set STATIC_URL to /static/ and STATIC_ROOT to /var/www/[any-name]/static/. When you decide to deploy, you will have to run sudo python manage.py collectstatic.

Also note that it should be Alias /static not Alias /static/ (note the trailing slash). The docs show /static/ but that is incorrect and will not work when you try and serve static files (apache does not complete the path).

That's it. All of these steps got my server up and running. If you have any questions, feel free to comment and I will try to help out. Good luck!