How to Set Up Django with PostgreSQL, Nginx, and Gunicorn on Ubuntu VPS Server
Welcome! Today, we will discuss how you can host your website on any VPS server. First of all, before thinking about hosting your website, it's important to know that the website we are hosting today is built using Django. We have already developed our Django website, and we are going to be hosting it on a VPS server. We will set it up to work with the PostgreSQL Database, Nginx server, and Gunicorn on Ubuntu 24.04 (LTS).
What you need before hosting your website
- You need a Django website ready to be shipped to production.
- Buy a VPS server
- Buy your domain name
Accessing Our Server With an SSH Client
Now, we need to get an SSH client. Some options include PuTTY, or you can even use your command line or PowerShell. There's also a powerful SSH client called MobaXterm. For this tutorial, we will be using MobaXterm. If you don't have MobileXterm installed on your system, head to their website, download it and install it. Use this link Okay, so once you are done with the installation of MobaXterm. Open your MobaXterm application. sudo apt update
Then let's type in the following command:
sudo apt install python3-dev python3.12-venv libpq-dev postgresql postgresql-contrib nginx curl
Let's wait for a moment while all our software is installed.
It's time to create our database, let's run the code below:
sudo -u postgres psql
Now we will be inside the PostgreSQL database. It's time to create our database.
CREATE DATABASE mydb;
Don't forget to end all the SQL statements with a semicolon, please.
We are supposed to create a database user to connect with Django.
But in the new Django and PostgreSQL setup, there's a permission error that can restrict you when trying to make migrations from your Django app to the database if you are using a newly created user. So, we are going to skip creating a new user. Instead, we will use the existing "postgres" user, which is the main user of the database. This error doesn't affect the PostgreSQL user but can impact new users created for a database.
What we will do is create a password for our PostgreSQL user and use that user as our database user for the Django app.
Okay, let's type "\password" and it will prompt us to add a password for the PostgreSQL user.
We enter our desired password, confirm it by entering it again, and then hit Enter. Now, our PostgreSQL user has a password.
Now our database user is "postgres" and our password is the new password we created.
Okay, so now it's time to create our Django project. We already have our Django project locally. In MobaXterm, you can't directly upload a folder.
So, let's start the Django project again here.
We need to move to the root directory of our Ubuntu server. Then, create a home folder if it doesn't already exist.
cd /..
Will move use to the root directory.
mkdir home
to create our home folder.
Note: the command cd (change directory) is used to navigate the command line interface. If you want to move one-inch backward use "cd ..", to move frontward use cd then the name of the available folder Ex: "cd home" or "cd home/mywebsite", but make sure the folder(s) exist there before trying to move to it. You can check the available folders with "ls" command. You can also move to the root directory one touch using the "cd /.." command.
Now we have created our home and project folder, let's create our virtual environment.
python3 -m venv myvitname
Let's wait for a moment. Once the virtual environment is created, we need to activate it.
source myvitname/bin/activate
Once we've activated our virtual environment, it's time to install some packages. We need Django, Gunicorn, Psycopg, pillow, etc.
pip install django gunicorn psycopg[binary] pillow
Now is the time to create our Django project.
django-admin startproject mynewproject
Once you have created your Django project, move straight to the settings.py and open it.
MobaXterm has a file editor, you can use that to edit your files or right-click on the file and select "open with" It will show you multiple options, and you can select VS code.
Now, remember your domain name and your IP address. In the settings.py file, you'll find the "ALLOWED_HOSTS" section. You may have omitted this in your local development environment, but now it's time to fill that in for your Django project.
In the "ALLOWED_HOSTS," add the domain name you bought from Dynadot or Namecheap. Include both the www version and the non-www version. Our domain will not work yet, but let's have them there, for now, only the IP address will work at this point.
Then, copy the IP address from your server and add it to the list. If you fail to add all of them to the list Django will not allow them to serve your website. So we also need to add localhost to our list since our PostgreSQL database is available on our local server.
This is how our ALLOWED_HOST will look like:
ALLOWED_HOSTS = ['18.28.00.15', 'withubb.com', 'www.withubb.com', 'localhost']
Let's move down to the place where we have the database settings, it has sqlite3 database by default change it to our PostgreSQL database.
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "mydatabase",
"USER": "mydatabaseuser",
"PASSWORD": "mypassword",
"HOST": "localhost",
"PORT": "",
}
}
Scroll down to where we have the media and static root and add the configuration below so Django can serve your static and media root.
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'mediafiles/'
Run the following commands to create the initial migrations and apply them to your PostgreSQL database:
python manage.py makemigrations
python manage.py migrate
To create an admin user, run:
python manage.py createsuperuser
You will be prompted to enter a username, email, and password.
Gather all static content by running:
python manage.py collectstatic
Confirm the operation when prompted, and the static files will be placed in the `static` directory.
Enable your fire wall and allow traffic on port 8000 to test the development server:
sudo ufw allow 8000
sudo ufw enable
Test your project by starting the development server:
python manage.py runserver 0.0.0.0:8000
Visit your server's IP or domain followed by `:8000. For the admin interface, append `/admin` to the URL and log in using your admin credentials.
Test Gunicorn's ability to serve your project, move to the project and run:
gunicorn --bind 0.0.0.0:8000 mywebsite.wsgi
The admin interface will not have styling at this point, as Gunicorn doesn't serve static files. Press `CTRL+C` to stop the server.
Exit your virtual environment by typing:
deactivate
To automate Gunicorn startup, create a systemd socket and service:
Create the socket file:
sudo nano /etc/systemd/system/gunicorn.socket
Add the following:
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
Next, create the service file:
sudo nano /etc/systemd/system/gunicorn.service
Add this content:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/home/mywebsite/
ExecStart=/home/mywebsite/myvitname/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
mywebsite.wsgi:application
[Install]
WantedBy=multi-user.target
Enable and start the Gunicorn socket:
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
Verify the gunicorn socket is active:
sudo systemctl status gunicorn.socket
To use Nginx as a reverse proxy, create a server block:
sudo nano /etc/nginx/sites-available/mywebsite
Add the following:
server {
server_name mywebsite.com, www.mywebsite.com, my_server_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/mywebsite/mywebsite ;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
Enable the configuration:
sudo ln -s /etc/nginx/sites-available/mywebsite /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
ufw is our firewall, you need to check the status first:
sudo ufw status
If inactive, you need to enable it and add rules so you don't lock yourself out.
sudo ufw enable
It will prompt you if you want to override existing rules, input Y, and enter.
Open port 80 for Nginx and remove the development server rule:
sudo ufw delete allow 8000
sudo ufw allow openSSH
sudo ufw allow 'Nginx Full'
At this stage, your application should be live and accessible via your server's domain or IP address. You've done an amazing job following along! In the next chapter, we'll cover advanced Nginx configurations, securing your website with Certbot's free SSL certificate, and setting up DNS records for your domain name.
More Articles
Top 10 Coding Projects to Elevate Your Portfolio
2 days, 20 hours ago · 8 min read7 best programming Languages to Learn in 2024
5 days, 15 hours ago · 6 min read5 essential tools for building a responsive business website
5 days, 15 hours ago · 5 min readTop 10 website development trends 2024
2 weeks, 2 days ago · 10 min readHow to Design a Website for a Small Business on a Budget
2 weeks, 2 days ago · 7 min readRemote vs. Non-Remote Jobs: Which is Best for You?
3 weeks, 1 day ago · 9 min readTypes of websites with examples
4 weeks, 2 days ago · 10 min readTop 5 best cheapest and fastest VPS hosting providers
1 month ago · 7 min readBest E-commerce platforms for business websites in 2024
1 month ago · 14 min readWeb Design Tools for Professionals in 2024
1 month ago · 6 min readx