bash lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 22.04.3 LTS
Release: 22.04
Codename: jammy
sudo apt update
sudo apt install python3.10
sudo apt install python3-pip
sudo apt install python3-virtualenv
python3 -m venv <name of virtual environment>
sudo apt install apache2
sudo apt install libapache2-mod-wsgi-py3
- This is only necessary if you want to clone your project from GitHub
sudo apt install git
sudo apt update
sudo apt upgrade
git clone <project url>
source <name of virtual environment>/bin/activate
pip install -r requirements.txt
python manage.py collectstatic
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
- This is only necessary if you want to access the project from the server's
IP address
- Open the project's
settings.py
filenano <path to project>/settings.py
- Add the server's
IP address
to theALLOWED_HOSTS
listALLOWED_HOSTS = [ 'localhost', '<server IP address>', ]
- Save the file and exit
- We will later need to add the domain name to the
ALLOWED_HOSTS
list if we want to access the project from the domain name
-
First, lets check that apache2 is running properly
sudo systemctl status apache2
-
If apache2 is running properly, we should see something like this:
● apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2021-11-02 16:00:00 UTC; 1h 30min ago Docs: https://httpd.apache.org/docs/2.4/ Main PID: 1234 (apache2) Tasks: 55 (limit: 2299) Memory: 6.1M CGroup: /system.slice/apache2.service ├─1234 /usr/sbin/apache2 -k start ├─1235 /usr/sbin/apache2 -k start └─1236 /usr/sbin/apache2 -k start
-
And also be able to see the default apache2 page at the server's
IP address
-
With all that out of the way, we can start setting up the config file
-
We can start the config file by copying the default config file
sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/<name of config file>.conf
-
Open the config file
sudo nano /etc/apache2/sites-available/<name of config file>.conf
-
Currently, the config file should look like this (with the exception of the comments):
<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
-
We need to add the following lines to the config file:
Alias /static /path/to/static/files
-
The
Alias
line tells apache2 where to find the static files for the project -
Next, we need to add the following lines to the config file:
<Directory /path/to/static/files> Require all granted </Directory>
-
The
Directory
line tells apache2 to allow access to the static files -
Next, we need to add the following lines to the config file:
<Directory /path/to/project> <Files wsgi.py> Require all granted </Files> </Directory>
-
The
Directory
line tells apache2 to allow access to the project files -
The
Files
line tells apache2 to allow access to thewsgi.py
file -
Next, we need to add the following lines to the config file:
WSGIDaemonProcess <name of project> python-path=/path/to/project python-home=/path/to/virtual/environment WSGIProcessGroup <name of project> WSGIScriptAlias / /path/to/project/wsgi.py
-
The
WSGIDaemonProcess
line tells apache2 to create a daemon process for the project -
The
WSGIProcessGroup
line tells apache2 to use the daemon process for the project -
The
WSGIScriptAlias
line tells apache2 where to find thewsgi.py
file -
This is recommended by the official Django documentation here
-
Optionally
, if serving media files, we need to add the following lines to the config file:Alias /media /path/to/media/files <Directory /path/to/media/files> Require all granted </Directory>
-
Same as the
Alias
andDirectory
lines for the static files
- We need to set the permissions for the project so that apache2 can access the project files
- First, we need to add the apache2 user to the group that owns the project files
sudo usermod -a -G <group that owns the project files> www-data
- Next, we need to change the permissions of the project files
sudo chown -R <user that owns the project files>:<group that owns the project files> /path/to/project
- Next, we need to change the permissions of the virtual environment
sudo chown -R <user that owns the project files>:<group that owns the project files> /path/to/virtual/environment
- Next, we need to change the permissions of the static files
sudo chown -R <user that owns the project files>:<group that owns the project files> /path/to/static/files
Optionally
, if serving media files, we need to change the permissions of the media filessudo chown -R <user that owns the project files>:<group that owns the project files> /path/to/media/files
- The user or group should at least have read permissions for the project files and virtual environment
- The user or group should at least have read and execute permissions for the static files
Optionally
, if serving media files, the user or group should at least have read and execute permissions for the media files- To check the permissions of the project files and virtual environment, run the following command:
ls -l /path/to/project ls -l /path/to/virtual/environment
- Apache2 should now be able to access the project files (apache2 runs as the
www-data
user) - Use the command below to change the permissions of the project files and virtual environment if apache2 is still unable to access the project files
sudo chmod -R <permissions> /path/to/project sudo chmod -R <permissions> /path/to/virtual/environment
- If you are using the local sqlite3 database, you need to change the permissions of the database file
sudo chmod -R <permissions> /path/to/database/file/sqlite3.db
- We need to enable the config file so that apache2 can use it
- First, we need to disable the default config file
sudo a2dissite 000-default.conf
- Next, we need to enable the config file
sudo a2ensite <name of config file>.conf
- Next, we need to restart apache2
sudo systemctl restart apache2
- Apache2 should now be able to serve the project on the server's
IP address
http://<IP address>
- If apache2 is unable to serve the project, check the apache2 error log
sudo tail -f /var/log/apache2/error.log
- We need to set up the domain name so that we can access the project from the domain name
- First, we need to accuire a domain name. This can be done from a domain name registrar like Namecheap, GoDaddy, or Google Domains (there are many more)
- Next, we need to point the domain name to the server's
IP address
-
- If the server is on the same network, we can point the domain using CNAMES
- IMPORTANT CNAMES are aliases for domain names, which means that our network has to be able to resolve the domain name to the server's
IP address
or else it will NOT work - First, we need to create a CNAME record for the domain name
- Next, we need to point the CNAME record to the servers
internal domain name (hostname)
- Next allow the external domain name to access the project
- Open the project's
settings.py
filenano <path to project>/settings.py
- Add the domain name to the
ALLOWED_HOSTS
listALLOWED_HOSTS = [ 'localhost', '<server IP address>', '<domain name>', ]
- Save the file and exit
- We should now be able to access the project from the domain name
http://<domain name>
- If you are unable to access the project from the domain name, check the apache2 error log
- If you dont have a way to resolve the internal domain name, you can add it to your machines
hosts
file forlinux and mac
sudo nano /etc/hosts
- For
windows
, you can add it to thehosts
file located atC:\Windows\System32\drivers\etc\hosts
- I had this issue when I was setting up the project where apache2 would just constantly load the page. And after first load it would not even load on second refresh
- I found out that the wsgi application group was not setting up properly
- I fixed this by adding/changing the
WSGIProcessGroup
line in the config file to:WSGIApplicationGroup %{GLOBAL}