Apache serving Django and Angular

Viewed 1559

I have a project with Angular frontend served by a Django Rest API. My project is in the following structure.

example.com
  |- client (holds angular files)
  |- server (holds Django Rest Framework files)

The angular app makes calls to drf through http:

example.com/api/<params>

I'm hosting on a Linode Ubunutu 17.04, using Apache and uWSGI. I can't seem to figure out the best way to serve both Angular and Django at the same time? I can easily host the Django Rest API with the WSGI config, but can't figure out how Apache knows to point to Angular for normal requests.

What's wrong with the below solution or is there a better way?

In /etc/apache2/sites-available/example.com.conf

<VirtualHost *:80>
  ServerName example.com
  ServerAlias www.example.com
  DocumentRoot /var/www/example.com/client/
</VirtualHost>

<VirtualHost *:80>
  ServerName example.com/api
  ServerAlias www.example.com/api
  WSGIScriptAlias / var/www/example.com/index.wsgi
  DocumentRoot /var/www/example.com/server/
</VirtualHost>

Any help would be greatly appreciated!

1 Answers

I don't know if it's the best approach, but it worked for me:

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyRequests Off

    ProxyPass /api/ http://localhost:8000/api/
    ProxyPassReverse /api/ http://localhost:8000/api/

    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
</VirtualHost>

# Server
<VirtualHost *:8000>
    <Directory var/www/example.com/server>
            <Files wsgi.py>
                    Require all granted
            </Files>
    </Directory>

    # mod_wsgi configuration for django app
    # python-home represents a location of venv, in this case same as application path, but it's not neccessarily the same
    # python-path represents a location of application
    WSGIDaemonProcess my_app python-home=var/www/example.com/server python-path=var/www/example.com/server
    WSGIProcessGroup my_app
    WSGIScriptAlias / var/www/example.com/server/wsgi.py
</VirtualHost>

# Client
<VirtualHost *:8080>
    DocumentRoot /var/www/example.com/client
    <Directory /var/www/example.com>
            Require all granted
    </Directory>
</VirtualHost>

Listen to ports 8000 and 8080 by adding this lines in /etc/apache2/ports.conf:

# Internal: server
Listen 8000

# Internal: client
Listen 8080

Explanation: The VirtualHost that listens to port 80 serves as a proxy that redirects the requests further to different ports, based on the URL of the request. If the URL starts with /api/ the request will be redirected to port 8000 (internally) which in turn is handled by another VirtualHost. If the URL doesn't start with /api/, the request will be redirected to port 8080 which represents the client.

In this solution, I'm using mod_wsgi and not uWSGI but the approach will work the same (only the configuration of Server VirtualHost will differ).

Related