Skip to content

Instantly share code, notes, and snippets.

@leegraham25
Last active April 13, 2025 05:11
Show Gist options
  • Select an option

  • Save leegraham25/5ca7060b333234c9f6ef66f41451a72a to your computer and use it in GitHub Desktop.

Select an option

Save leegraham25/5ca7060b333234c9f6ef66f41451a72a to your computer and use it in GitHub Desktop.
Apache Configuration for React and Django Rest Framework

Setting Up Apache to Run a React Frontend and a Django Rest Framework Backend on a Single Machine

This gist should get React and Django Rest Framework running on debian with apache as the HTTP server.

Step 1 - Install Apache and UFW

First we need to install apache2 and apache2-dev (for compiling mod_wsgi), and set the firewall to allow apache with ufw.

sudo apt upgrade
sudo apt install apache2 apache2-dev ufw
sudo ufw allow 'Apache Full'

Digital Ocean: How To Install the Apache Web Server on Ubuntu 16.04

Step 2 - Compile and enable mod_wsgi

The second step is to compile mod_wsgi to work with your version of Python, then enable it with a2enmod.

wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.5.24.tar.gz
tar xvfz 4.5.24.tar.gz
cd mod_wsgi-4.5.24
./configure
make
sudo make install

Then edit /etc/apache2/apache2.conf to include this line

LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so

mod_wsgi

Step 3 - Create virtual host for Django Rest Framework backend

In this setup DRF will run on a different port to React, in this case DRF is on 8000

sudo mkdir /var/www/backend
cd /etc/apache2/sites-available
# Copy the default apache configuration
sudo cp 000-default.conf backend.conf
sudo nano backend.conf

Edit backend.conf to something like:

Listen 8000
<VirtualHost *:8000>
  ServerName yourServer
  ServerAdmin you@yourDomain
  DocumentRoot /var/www/backend
  
  # Point this to the wsgi.py in the same directory as your settings.py file
  WSGIScriptAlias / /var/www/yourDjangoProject/djangoSettings/wsgi.py
 
  <Directory /var/www/todo/backend>
    <Files wsgi.py>
      Require all granted
      Allow from all
    </Files>
  </Directory>
</VirtualHost>

Add to apache2.conf to use WSGI:

# This is just the root of your virtualenv directory, i.e. two levels above activate
WSGIPythonHome /var/www/backend/virtualenv
WSGIPythonPath /var/www/backend

Allow port 8000 (or your chosen port):

sudo ufw allow 8000

Running different sites on different ports How to use Django with Apache and mod_wsgi

Step 4 - Build React App

Now we need to build the React frontend for production and add a .htaccess file that uses mod_rewrite for client-side routing by React Router:

cd ~/your/react/app/public
nano .htaccess

Set .htaccess to something like

  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]
npm run-script build
sudo cp -r build /var/www/frontend

Deployment Apache Config for React Router

Step 5 - Create virtual host for React frontend

The last config step is to create a virtual host for the React app

sudo mkdir /var/www/frontend
cd /etc/apache2/sites-available
sudo cp 000-default.conf frontend.conf
sudo nano frontend.conf

Edit frontend.conf to something like:

<VirtualHost *:80>
  ServerName yourServer
  ServerAdmin you@yourDomain
  DocumentRoot /var/www/frontend
  
  # Serve static files like the minified javascript from npm run-script build
  Alias /static /var/www/todo/frontend/build/static
  <Directory /var/www/todo/frontend/build/static>
    Require all granted
  </Directory>
</VirtualHost>

Edit apache2.conf to allow htaccess to override the settings in apache2.conf for /var/www/:

<Directory /var/www/>
  Options Indexes FollowSymLinks
  AllowOverride All
  Require all granted
</Directory>

Step 6 - Enable the new sites and restart

Finally we need to disable the default apache config and enable our backend and frontend configs, then restart apache so changes are applied

a2dissite 000-default.conf
a2ensite backend.conf
a2ensite frontend.conf
sudo systemctl restart apache2
@pos-isalem
Copy link

why do I get this error when trying to compile mod_wsgi?

In file included from src/server/mod_wsgi.c:22:0:
src/server/wsgi_python.h:24:10: fatal error: Python.h: No such file or directory
#include <Python.h>
^~~~~~~~~~
compilation terminated.
apxs:Error: Command failed with rc=65536
.
Makefile:31: recipe for target 'src/server/mod_wsgi.la' failed
make: *** [src/server/mod_wsgi.la] Error 1

first, run the below command to get the path of the python
whereis python

then add the below flag when you run ./configure to be:
./configure --with-python=/path-to-python

@vitalfadeev
Copy link

What about next case?

  • domain/
  • domain/api/

where:

  • domain/ - React-based frontend
  • domain/api/ - Django-based backed

How implement it with Apache ?

@hugolvc
Copy link

hugolvc commented Apr 24, 2020

I have the same issue than @pos-isalem. I followed your directions, but now I get this result with ./configure --with-python=/usr/bin/python3.6

linuxmidtc@servermidtc:~/mod_wsgi-4.5.24$ ./configure --with-python=/usr/bin/python3.6m
checking for apxs2... /usr/bin/apxs2
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for prctl... yes
checking Apache version... 2.4.29
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'sysconfig'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'sysconfig'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'sysconfig'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'sysconfig'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'sysconfig'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'distutils.sysconfig'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'sysconfig'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'sysconfig'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'sysconfig'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'sysconfig'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'sysconfig'
configure: creating ./config.status
config.status: creating Makefile

@leegraham25
Copy link
Author

I have the same issue than @pos-isalem. I followed your directions, but now I get this result with ./configure --with-python=/usr/bin/python3.6

Hi, does /usr/bin/python3.6 -c "from distutils import sysconfig" work? There's discussion here that might be helpful. I just tried on debian latest and sudo apt install python3-distutils got ./configure working. After that I ran make and got the fatal error: Python.h: No such file or directory. Running sudo apt install python3-dev fixed it. More info here. I guess these packages are no longer installed by default since I wrote the original instructions. I hope that helps.

@nikithapk
Copy link

I am seeing this error while trying to compile mod_wsgi

src/server/wsgi_interp.c:323:32: error: dereferencing pointer to incomplete type ‘PyInterpreterState’ {aka ‘struct _is’}
323 | tstate = tstate->interp->tstate_head;
| ^~
apxs:Error: Command failed with rc=65536
.
Could anyone help me resolve this issue?
Thanks in advance

@troll-git
Copy link

I am seeing this error while trying to compile mod_wsgi

src/server/wsgi_interp.c:323:32: error: dereferencing pointer to incomplete type ‘PyInterpreterState’ {aka ‘struct _is’}
323 | tstate = tstate->interp->tstate_head;
| ^~
apxs:Error: Command failed with rc=65536
.
Could anyone help me resolve this issue?
Thanks in advance

I think that it is due to missing dependecy. Have you installed apache-dev?

@isyedaliraza
Copy link

For anyone who is facing a problem installing mod_wsgi from the source. If you are using Ubuntu then you can simply use the apt package manager to install mod_wsgi after installing apache2. You can run the following command to install mod_wsgi:
sudo apt install libapache2-mod-wsgi-py3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment