How to Connect Django to PostgreSQL on a VPS in 2026

If you’re deploying your Django application on a VPS, connecting it to PostgreSQL is one of the most important steps you shouldn’t skip. While SQLite is great for development, PostgreSQL is built to deliver better performance, security, and reliability in production.

Don’t worry if you’ve never configured PostgreSQL with Django before. I’ll walk you through every step in a simple and practical way, so you can follow along without getting confused or wondering what to do next.

We’ll begin by preparing your VPS, install and configure PostgreSQL, create a dedicated database and user, update your Django settings, run migrations, and finally verify that everything is working correctly. By the end, your Django application will be ready to use PostgreSQL with confidence in a production environment.


What You’ll Need Before You Start

Before making any changes, it’s worth checking that your server and project are ready. Having everything prepared beforehand will make the setup process much smoother and help you avoid common configuration errors later.

Here’s what you’ll need:

  • A Linux VPS (Ubuntu 22.04 or Ubuntu 24.04 LTS is recommended)
  • Root or a user account with sudo privileges
  • An existing Django project already running on the VPS
  • Python 3 and pip installed
  • SSH access to your VPS
  • PostgreSQL installed (or permission to install it)
  • A stable internet connection for downloading required packages
  • Basic familiarity with the Linux terminal

Quick Pre-Setup Checklist

Before moving on, confirm the following:

  • You can successfully connect to your VPS using SSH.
  • Your Django project files are already available on the server.
  • Python and pip are installed and working correctly.
  • You have permission to install software and edit configuration files.
  • Your virtual environment (if you’re using one) is activated before installing Python packages.

Taking a couple of minutes to verify these prerequisites can save a lot of troubleshooting later in the setup process.


Why Use PostgreSQL with Django on a VPS?

Before you start the setup, it’s important to understand why PostgreSQL is the preferred database for production Django applications. While Django uses SQLite by default for development, PostgreSQL is a better choice when deploying your project on a VPS.

SQLite stores data in a single file, making it simple for local development. However, as your application grows and starts handling multiple users, larger datasets, and frequent database operations, its limitations become noticeable.

PostgreSQL is built for production environments. It delivers better performance under heavy traffic, supports multiple simultaneous connections, ensures reliable data integrity with ACID-compliant transactions, and offers advanced security features like user roles, authentication, and granular permissions. It also scales easily as your application grows and integrates seamlessly with Django’s ORM, making migrations and database management much easier.

Some of the key benefits of using PostgreSQL with Django include:

  • Better performance for production workloads
  • Efficient handling of multiple concurrent users
  • Reliable data integrity and transaction support
  • Advanced security and access control
  • Easy backup and recovery options
  • Excellent scalability as your application grows
  • Native support for Django’s ORM and migrations

In short, SQLite is ideal for development, while PostgreSQL is the recommended database for deploying Django applications on a VPS. It provides the performance, security, and reliability needed to run real world web applications with confidence.

Now that you know why PostgreSQL is the better choice, let’s start by connecting to your VPS and preparing it for the installation.


Step 1: Connect to Your VPS Using SSH

Before you can install PostgreSQL or modify your Django project, you’ll first need to access your VPS through SSH (Secure Shell). SSH creates an encrypted connection between your computer and the server, allowing you to run commands, edit files, and manage your application remotely.

If you’ve already been deploying your Django project on the VPS, you’ve likely used SSH before. If not, don’t worry, the process only takes a minute.

Open Your Terminal

Use the appropriate terminal application for your operating system:

  • Windows: PowerShell, Windows Terminal, or Command Prompt (OpenSSH installed by default on recent Windows versions)
  • macOS: Terminal
  • Linux: Any terminal emulator

Once your terminal is open, you’re ready to connect.

Connect to Your VPS

Run the following command:

ssh username@your_server_ip

Replace:

  • username with your VPS username (for example, root or ubuntu)
  • your_server_ip with your server’s public IP address

Example:

ssh root@203.0.113.10

Or, if you’re using a non-root account:

ssh ubuntu@203.0.113.10

The first time you connect, SSH may display a message asking whether you trust the server’s fingerprint.

Example:

Are you sure you want to continue connecting (yes/no)?

Type:

yes

Then press Enter.

Next, enter your server password or allow SSH to authenticate using your private key if you’ve configured key based login.

Tip: SSH key authentication is generally more secure than password based login and is recommended for production servers.

Verify That You’re Connected

After a successful login, your terminal prompt will change to something similar to:

root@vps:~#
or
ubuntu@server:~$

You can quickly verify that you’re connected to the correct machine by running:

hostname

To check your current logged in user:\

whoami

You can also confirm your Linux distribution and version:

cat /etc/os-release

Typical output on Ubuntu might look like:

PRETTY_NAME="Ubuntu 24.04 LTS"

This helps ensure you’re following commands appropriate for your operating system.

Update Your Package List

Before installing any new software, it’s a good practice to refresh your package index so your server knows about the latest available packages.

On Ubuntu or Debian, run:

sudo apt update

If package updates are available, you can install them with:

sudo apt upgrade

Keeping your server updated helps improve security, stability, and compatibility with newer software versions.

Note: While a full system upgrade isn’t always required before installing PostgreSQL, regularly updating your VPS is considered a best practice for production environments.

Navigate to Your Django Project

If your Django project is already deployed on the VPS, move into its directory before making any changes.

For example:

cd /var/www/myproject
or
cd ~/myproject

Replace the path with the actual location of your Django project.

If you’re using a Python virtual environment, activate it now:

source venv/bin/activate

Once activated, your terminal prompt typically changes to something like:

(venv) ubuntu@server:~/myproject$

Activating the virtual environment ensures that any Python packages you install, such as the PostgreSQL driver, are added only to your project and won’t interfere with other Python applications on the server.

Quick Check Before Moving On

Before proceeding to the PostgreSQL installation, make sure:

  • You’re successfully connected to the VPS via SSH.
  • You’re logged in with a user that has sudo privileges (or as root).
  • Your package list has been updated.
  • You’ve navigated to your Django project directory.
  • Your Python virtual environment is activated, if you’re using one.

With your server ready, the next step is to install PostgreSQL, enable its service, and verify that it’s running correctly on your VPS.


Step 2: Install PostgreSQL (Skip If It’s Already Installed)

Now that you’re connected to your VPS, the next step is to install PostgreSQL. If you’ve already installed PostgreSQL on your server, you can quickly verify that it’s running correctly and move on to the next section.

For a new VPS, however, you’ll need to install the PostgreSQL server package before Django can connect to it.

The commands below are written for Ubuntu 22.04 LTS and Ubuntu 24.04 LTS, which are the most commonly used Linux distributions for Django deployments.

Check Whether PostgreSQL Is Already Installed

Before installing anything, it’s a good idea to see if PostgreSQL is already available on your server.

Run:

psql --version

If PostgreSQL is installed, you’ll see output similar to:

psql (PostgreSQL) 16.3

The version number may differ depending on your server.

If you receive an error such as:

psql: command not found

then PostgreSQL isn’t installed yet, and you can continue with the installation.

Update the Package Repository

Refresh your package list before installing new software:

sudo apt update

This ensures your VPS downloads the latest available PostgreSQL package from the Ubuntu repositories.

Install PostgreSQL

Install both the PostgreSQL server and its additional utilities by running:

sudo apt install postgresql postgresql-contrib -y

Here’s what gets installed:

  • postgresql – The PostgreSQL database server.
  • postgresql-contrib – Additional extensions and utilities that are commonly used with PostgreSQL.

Depending on your VPS and internet speed, the installation usually takes a minute or two.

Verify the Installation

Once the installation finishes, check the PostgreSQL version again:

psql --version

Example output:

psql (PostgreSQL) 16.3

This confirms that PostgreSQL has been installed successfully.

Check the PostgreSQL Service Status

PostgreSQL runs as a background service. Before connecting Django to it, make sure the service is active.

Run:

sudo systemctl status postgresql

A healthy service typically displays something similar to:

Active: active (running)

If you see this status, PostgreSQL is running correctly.

To exit the status screen, press:

q

Start PostgreSQL If It Isn’t Running

If the service isn’t active, start it manually:

sudo systemctl start postgresql

Then verify its status again:

sudo systemctl status postgresql

Enable PostgreSQL to Start Automatically

To make sure PostgreSQL starts automatically whenever your VPS reboots, enable the service:

sudo systemctl enable postgresql

You should see a confirmation message indicating that the service has been enabled.

This is an important step because your Django application won’t be able to connect to the database if PostgreSQL isn’t running after a server restart.

Confirm PostgreSQL Is Accepting Connections

One of the easiest ways to verify the server is ready is to switch to the default PostgreSQL administrator account.

Run:

sudo -i -u postgres

Your prompt will change to something similar to:

postgres@your-server:~$

Now open the PostgreSQL interactive shell:

psql

If everything is working correctly, you’ll see a prompt like:

postgres=#

This means the PostgreSQL server is running and accepting local connections.

To leave the PostgreSQL shell, type:

\q

Then return to your normal user account:

exit

Verify That PostgreSQL Is Listening

For an extra confirmation, you can check whether PostgreSQL is listening on its default port (5432).

Run:

sudo ss -tulpn | grep 5432

You should see output indicating that PostgreSQL is listening on port 5432.

For a typical Django deployment where both Django and PostgreSQL are running on the same VPS, the database listens on the local interface, which is the recommended and most secure configuration.

Common Installation Issues

If PostgreSQL doesn’t install or start correctly, here are a few things to check:

  • Ensure your VPS has a stable internet connection.
  • Confirm that your package repositories are up to date by running sudo apt update.
  • Make sure you have sudo or root privileges.
  • If another installation process is using the package manager, wait for it to finish before trying again.
  • Restart the PostgreSQL service if it fails to start on the first attempt:
sudo systemctl restart postgresql

Step 3: Create a PostgreSQL Database and User

With PostgreSQL installed and running, the next step is to create a dedicated database and a separate database user for your Django application.

Although PostgreSQL includes a default postgres superuser, you should avoid using it directly in your Django project. The postgres account has unrestricted administrative privileges, which makes it unsuitable for everyday application access.

A better approach is to create:

  • A dedicated database for your Django project
  • A dedicated database user
  • A strong password
  • Appropriate permissions for that user

This follows the principle of least privilege, improving both security and maintainability.

Switch to the PostgreSQL Administrator

First, log in as the PostgreSQL system user:

sudo -i -u postgres

Your terminal prompt should change to something similar to:

postgres@your-server:~$

Now open the PostgreSQL interactive shell:

psql

If successful, you’ll see:

postgres=#

You’re now ready to create your database.

Create a New Database

Create a database that will store all of your Django application’s data.

Replace myprojectdb with your preferred database name.

CREATE DATABASE myprojectdb;

If everything works correctly, PostgreSQL returns:

CREATE DATABASE

Choose a database name that’s easy to recognize, especially if your VPS hosts multiple applications.

Examples:

  • blogdb
  • ecommerce_db
  • inventory_db
  • schoolportal_db

Using descriptive names makes server management much easier later.

Create a Dedicated Database User

Next, create a new PostgreSQL user that Django will use when connecting to the database.

Example:

CREATE USER django_user WITH PASSWORD 'YourStrongPasswordHere';

Example output:

CREATE ROLE

Replace:

  • django_user with your preferred username
  • YourStrongPasswordHere with a long, unique password

A strong password should:

  • Be at least 16 characters long
  • Include uppercase letters
  • Include lowercase letters
  • Include numbers
  • Include special characters
  • Avoid dictionary words

Example:

T7@kL92!Pg#xQ8vR

Never use simple passwords like:

  • password123
  • admin
  • django
  • postgres

Weak passwords make your database much easier to compromise.

Grant Database Privileges

Now allow your new user to access the database.

Run:

GRANT ALL PRIVILEGES ON DATABASE myprojectdb TO django_user;

Output:

GRANT

This allows your Django application to connect to and work with the database.

On newer PostgreSQL versions, it’s also a good idea to grant permissions on the default public schema. This helps avoid permission-related errors when Django creates tables during migrations.

First, connect to your new database:

\c myprojectdb

Then run:

GRANT ALL ON SCHEMA public TO django_user;

Example output:

GRANT

This gives your application the necessary rights to create and manage database objects within the schema.

Verify the Database Was Created

You can list all databases by running:

\l

You should see something similar to:

myprojectdb
postgres
template0
template1

This confirms your new database exists.

Verify the User Was Created

To list PostgreSQL users (roles), run:

\du

Example output:

Role name      | Attributes
---------------+--------------------
postgres       | Superuser
django_user    |

This confirms that your application user has been created successfully.

Test the New User Login

Before configuring Django, it’s a good idea to verify that the new credentials actually work.

Exit the PostgreSQL shell:

\q

Return to your normal shell if needed:

exit

Now try connecting with the new user:

psql -U django_user -d myprojectdb -h localhost

PostgreSQL will prompt you for the password.

If the login succeeds, you’ll enter the PostgreSQL shell:

myprojectdb=>

This confirms:

  • The database exists
  • The username is correct
  • The password works
  • PostgreSQL accepts connections using the new account

Exit the shell when you’re done:

\q

Keep Your Credentials Safe

You’ll need the following information in the next step when configuring Django:

SettingExample
Database Namemyprojectdb
Database Userdjango_user
Database PasswordYourStrongPasswordHere
Hostlocalhost
Port5432

Rather than hardcoding these values into your Django project, you’ll learn later how to store them securely using environment variables.

Common Mistakes to Avoid

When creating a PostgreSQL database for Django, these are some of the most common issues developers run into:

  • Using the postgres superuser for the application instead of creating a dedicated user.
  • Choosing a weak or easily guessable password.
  • Forgetting to grant database privileges to the new user.
  • Misspelling the database name or username.
  • Skipping the connection test before configuring Django.
  • Not granting schema permissions on newer PostgreSQL versions, which can cause migration errors.

Taking a few extra minutes to verify each step now can save a lot of troubleshooting later.


Step 4: Install the PostgreSQL Driver for Django

At this point, your PostgreSQL database is ready. However, Django still doesn’t know how to communicate with it.

To bridge the gap between your Django application and the PostgreSQL server, you’ll need to install a PostgreSQL database driver for Python. This driver allows Django’s ORM (Object-Relational Mapper) to send queries, retrieve data, and perform database operations without requiring you to write raw SQL for everyday tasks.

Without this driver, Django won’t be able to establish a connection to your PostgreSQL database, even if your database settings are configured correctly.

Activate Your Python Virtual Environment

If your Django project uses a virtual environment, which is the recommended approach, activate it before installing any Python packages.

Navigate to your project directory if you aren’t already there:

cd /path/to/your/django-project

Now activate your virtual environment:

source venv/bin/activate

Depending on your project, the virtual environment folder may have a different name, such as:

  • venv
  • env
  • .venv

After activation, your terminal prompt should look similar to:

(venv) ubuntu@server:~/myproject$

If you’re not using a virtual environment, you can still continue, but using one is strongly recommended because it keeps your project’s dependencies isolated from the rest of the system.

Before installing new packages, it’s a good idea to update pip to the latest version.

Run:

python -m pip install --upgrade pip

Or, if your server uses Python 3 explicitly:

python3 -m pip install --upgrade pip

Keeping pip updated helps avoid installation issues with newer Python packages.

Install the PostgreSQL Driver

For most Django projects, install the PostgreSQL driver using:

pip install psycopg[binary]

This installs the modern psycopg (version 3) driver along with its binary dependencies, making installation easier on most Linux servers.

If you’re working with an older Django project that specifically depends on psycopg2, you can install:

pip install psycopg2-binary

Which one should you choose?

  • psycopg (v3) is the latest PostgreSQL adapter and is recommended for new Django projects.
  • psycopg2-binary is still widely used and remains compatible with many existing Django applications. If your project or deployment documentation already specifies psycopg2, it’s perfectly fine to continue using it.

Verify the Installation

Once the installation finishes, check that the package was installed successfully.

For the modern driver:

pip show psycopg

Example output:

Name: psycopg
Version: 3.x.x

Or, if you installed psycopg2-binary:

pip show psycopg2-binary

You can also list installed packages:

pip list

Look for either:

  • psycopg
  • psycopg2-binary

If it’s listed, the installation was successful.

Test That Python Can Import the Driver

A quick import test helps confirm that Python can access the installed package.

For psycopg (v3):

python -c "import psycopg; print('PostgreSQL driver installed successfully')"

Expected output:

PostgreSQL driver installed successfully

If you’re using psycopg2:

python -c "import psycopg2; print('PostgreSQL driver installed successfully')"

Receiving the success message means the driver is installed correctly and ready for Django to use.

Add the Driver to Your Requirements File

If your project uses a requirements.txt file, don’t forget to update it so anyone deploying the project later installs the same dependencies.

Run:

pip freeze > requirements.txt

Or, if you prefer to append only the new package manually, add the appropriate line:

For psycopg:

psycopg[binary]

Or for psycopg2:

psycopg2-binary

Keeping your dependencies documented makes deployments more consistent across development, staging, and production environments.

Common Installation Issues

If the driver doesn’t install successfully, here are a few things to check:

  • Ensure your virtual environment is activated before running pip install.
  • Confirm you’re using the same Python interpreter that runs your Django project.
  • Update pip if you encounter package resolution errors.
  • Make sure your VPS has an active internet connection.
  • If you accidentally installed the package globally instead of inside your virtual environment, activate the virtual environment and install it again.

Most installation issues are caused by using the wrong Python environment rather than problems with PostgreSQL itself.


Step 5: Update Django Database Settings

Now comes the most important part of the setup, configuring Django to use your PostgreSQL database instead of the default SQLite database.

When you create a new Django project, the settings.py file is configured to use SQLite automatically. That’s great for local development, but for a production VPS, you’ll want Django to connect to the PostgreSQL database you created earlier.

In this step, you’ll replace the default database configuration with your PostgreSQL credentials and verify that everything is configured correctly.

Locate the settings.py File

Every Django project contains a settings.py file where the project’s configuration is stored.

A typical project structure looks like this:

myproject/
├── manage.py
├── requirements.txt
├── venv/
└── myproject/
   ├── __init__.py
   ├── settings.py
   ├── urls.py
   ├── asgi.py
   └── wsgi.py

Navigate to your project directory:

cd /path/to/your/project

Then open the settings.py file using your preferred text editor.

For example, with Nano:

nano myproject/settings.py

Or with Vim:

vim myproject/settings.py

Replace myproject with your actual Django project folder name.

Find the Default SQLite Configuration

Inside settings.py, you’ll find a section similar to this:

DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.sqlite3',
       'NAME': BASE_DIR / 'db.sqlite3',
   }
}
This tells Django to use SQLite.

Since you’re moving to PostgreSQL, this configuration needs to be replaced.

Configure PostgreSQL

Replace the SQLite configuration with the following:

DATABASES = {
   "default": {
       "ENGINE": "django.db.backends.postgresql",
       "NAME": "myprojectdb",
       "USER": "django_user",
       "PASSWORD": "YourStrongPasswordHere",
       "HOST": "localhost",
       "PORT": "5432",
   }
}

Replace the placeholder values with your own:

SettingDescription
NAMEYour PostgreSQL database name
USERPostgreSQL username created earlier
PASSWORDPassword for that PostgreSQL user
HOSTUsually localhost when PostgreSQL runs on the same VPS
PORTPostgreSQL’s default port (5432)

If your Django application and PostgreSQL server are running on the same VPS, keeping the host as localhost is the most common and secure configuration.

Understand What Each Setting Does

Before saving the file, it’s useful to understand what each option means.

ENGINE

This tells Django which database backend to use.

For PostgreSQL:

"ENGINE": "django.db.backends.postgresql"

If this value is incorrect, Django won’t know how to communicate with PostgreSQL.

NAME

This is the database that Django will use.

Example:

"NAME": "myprojectdb"

It must match the database you created in PostgreSQL.

USER

The username Django uses when connecting to PostgreSQL.

Example:

"USER": "django_user"

This should be the dedicated application user, not the postgres superuser.

PASSWORD

This is the password associated with your PostgreSQL user.

Example:

"PASSWORD": "YourStrongPasswordHere"

The password must exactly match the one you assigned when creating the PostgreSQL user.

HOST

The database server location.

If PostgreSQL runs on the same VPS:

"HOST": "localhost"

If the database is hosted on another server, replace localhost with that server’s IP address or hostname.

PORT

PostgreSQL listens on port:

"PORT": "5432"

Only change this if you’ve configured PostgreSQL to use a different port.

Save Your Changes

After updating the configuration:

  • Save the file.
  • Exit your text editor.

For Nano:

  • Press Ctrl + O to save.
  • Press Enter to confirm.
  • Press Ctrl + X to exit.

Double Check Your Credentials

Before moving on, verify that:

  • The database name is correct.
  • The username is correct.
  • The password matches exactly.
  • The host is correct.
  • The port is 5432 unless you’ve changed it intentionally.

Even a small typo in one of these values can prevent Django from connecting to PostgreSQL.

Avoid Hardcoding Credentials in Production

The configuration shown above is useful for understanding how Django connects to PostgreSQL, but hardcoding usernames and passwords directly in settings.py isn’t recommended for production environments.

If your project is stored in a Git repository or shared with other developers, sensitive credentials could accidentally be exposed.

A more secure approach is to load these values from environment variables or a .env file. This keeps secrets separate from your source code and makes deployments easier across different environments.

We’ll cover this in the next step.

Common Configuration Mistakes

If Django fails to connect after updating settings.py, check for these common issues:

  • The database name doesn’t exist.
  • The PostgreSQL username is incorrect.
  • The password contains a typo.
  • The database user doesn’t have permission to access the database.
  • The PostgreSQL service isn’t running.
  • The PostgreSQL driver (psycopg or psycopg2) wasn’t installed in your active virtual environment.
  • You’re editing the wrong settings.py file in a multi project setup.

Taking a moment to review these settings carefully can save a lot of debugging time.


Step 6: Store Database Credentials Securely

Your Django project is now configured to connect to PostgreSQL. However, before moving any further, there’s one important improvement you should make.

In the previous step, you added the database name, username, and password directly inside settings.py. While this works, it’s not recommended for production environments.

Imagine uploading your project to GitHub or sharing it with another developer. If your database credentials are hardcoded into the project, anyone with access to the code could see them. This creates an unnecessary security risk.

A much safer approach is to store sensitive information in environment variables or a .env file. Your application reads these values at runtime, keeping passwords and other secrets separate from your source code.

Why Use Environment Variables?

Using environment variables provides several advantages:

  • Keeps database passwords out of your source code.
  • Makes it safer to use version control systems like Git.
  • Allows different settings for development, staging, and production.
  • Makes server migrations easier because only the environment variables need to change.
  • Follows Django’s recommended security practices for production deployments.

In short, your code remains the same across environments, while only the configuration changes.

Install python-decouple

One of the simplest ways to manage environment variables in Django is by using the python-decouple package.

If it isn’t already installed, activate your virtual environment and run:

pip install python-decouple

Once the installation is complete, verify it:

pip show python-decouple

You should see information about the installed package.

Create a .env File

Inside your Django project directory (where manage.py is located), create a file named:

.env

Open the file and add your database credentials.

Example:

DB_NAME=myprojectdb
DB_USER=django_user
DB_PASSWORD=YourStrongPasswordHere
DB_HOST=localhost
DB_PORT=5432

Replace these example values with your own PostgreSQL database information.

Important: Do not wrap the values in quotes unless they’re actually part of the value.

Update settings.py

Next, open your settings.py file and import the config function.

Near the top of the file, add:

from decouple import config

Now replace your hardcoded database configuration with this:

DATABASES = {
   "default": {
       "ENGINE": "django.db.backends.postgresql"
       "NAME": config("DB_NAME"),
       "USER": config("DB_USER"),
       "PASSWORD": config("DB_PASSWORD"),
       "HOST": config("DB_HOST", default="localhost"),
       "PORT": config("DB_PORT", default="5432"),
   }
}

Now Django loads the database credentials from the .env file instead of storing them directly in the project.

This makes your configuration cleaner, safer, and much easier to manage.

Protect the .env File

Your .env file contains sensitive information and should never be committed to a Git repository.

If your project uses Git, open (or create) a .gitignore file and add:

.env

This tells Git to ignore the file, helping prevent accidental exposure of passwords and other secrets.

If you’re working on a team, share the required environment variable names separately instead of sharing the actual .env file.

Check That Django Can Read the Variables

A quick way to confirm everything is working is to open the Django shell:

python manage.py shell

Then try importing one of the variables:

from decouple import config
print(config("DB_NAME"))

If Django prints your database name without any errors, it means the .env file is being read correctly.

Exit the shell by typing:

exit()

Common Issues and Solutions

If Django can’t read the environment variables, check the following:

  • Ensure the .env file is in the same directory as manage.py.
  • Verify that the variable names in .env exactly match those used in settings.py.
  • Make sure there are no extra spaces around the = sign.
  • Confirm that python-decouple is installed inside your active virtual environment.
  • Restart your Django application or Gunicorn service after making changes so the new environment variables are loaded.

Most configuration problems come down to a typo in the variable names or placing the .env file in the wrong location.

Security Best Practices

As your Django project grows, following a few simple security practices can help protect your database and application:

  • Use a dedicated PostgreSQL user instead of the postgres superuser.
  • Create strong, unique passwords for your database accounts.
  • Store secrets in environment variables rather than hardcoding them.
  • Keep your .env file out of version control.
  • Rotate database passwords periodically, especially after team changes.
  • Limit database access to trusted users and applications only.

These small habits significantly reduce the risk of accidentally exposing sensitive information.


Step 7: Run Django Migrations

With PostgreSQL installed, your database created, the PostgreSQL driver configured, and your settings.py updated, it’s time to let Django create its database tables.

This is done using migrations.

If you’re new to Django, think of migrations as instructions that tell Django how your database should look. Instead of manually creating tables, Django generates and applies them automatically based on your project’s models.

When migrations run successfully, it’s one of the clearest signs that Django is communicating with your PostgreSQL database correctly.

Make Sure Your Virtual Environment Is Active

Before running any Django management commands, activate your virtual environment.

For example:

source venv/bin/activate
Your prompt should now include the virtual environment name:
(venv) ubuntu@server:~/myproject$

If you’re not using a virtual environment, you can skip this step.

Navigate to Your Django Project

Move to the directory where the manage.py file is located.

Example:

cd /path/to/your/project

To verify you’re in the correct location, run:

ls

You should see something similar to:

manage.py
requirements.txt
myproject/
venv/

If manage.py isn’t listed, you’re in the wrong directory.

Check for Pending Migrations

Before applying migrations, it’s good practice to let Django check whether any model changes need migration files.

Run:

python manage.py makemigrations

If there are no new model changes, Django may display:

No changes detected

If you’ve recently created or modified models, Django will generate new migration files automatically.

Apply the Migrations

Now apply all pending migrations:

python manage.py migrate

Django will begin creating the required tables inside your PostgreSQL database.

A successful migration usually looks similar to this:

Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying sessions.0001_initial... OK

Depending on your installed applications, you may see additional migrations as well.

Each line ending with OK indicates that Django successfully created or updated the corresponding database tables.

Verify That Tables Were Created

After the migrations complete, you can verify that the tables exist in PostgreSQL.

Connect to your database:

psql -U django_user -d myprojectdb -h localhost

Enter your database password when prompted.

Once connected, list all tables:

\dt

You should see tables similar to:

auth_user
auth_group
django_admin_log
django_content_type
django_migrations
django_session

If these tables are present, Django has successfully created its database schema inside PostgreSQL.

Exit PostgreSQL:

\q

Check Which Database Django Is Using

If you previously used SQLite, you may want to confirm that Django is now connected to PostgreSQL.

Open the Django shell:

python manage.py shell

Run:

from django.db import connection
print(connection.vendor)

Expected output:

postgresql

If you see postgresql, Django is connected to your PostgreSQL database.

Exit the shell:

exit()

If this is a fresh deployment, you’ll probably want access to Django’s admin panel.

Create an administrator account:

python manage.py createsuperuser

Django will ask for:

  • Username
  • Email address
  • Password

Example:

Username: admin
Email address: admin@example.com
Password:
Password (again):

After completion, you’ll see:

Superuser created successfully.

You’ll use these credentials to log in to the Django admin dashboard later.

What Happens During Migration?

When you run the migrate command, Django automatically creates the database tables required by your project and installed applications.

Some of the tables created include:

  • User accounts
  • User groups
  • Permissions
  • Sessions
  • Admin logs
  • Migration history
  • Content types

As your project grows, future migrations will update the database structure whenever you add or modify models.

This migration system is one of Django’s biggest strengths because it keeps your database synchronized with your application code.

Common Migration Errors

If migrations don’t complete successfully, here are a few things to check:

ProblemPossible CauseSolution
password authentication failedIncorrect database passwordVerify your PostgreSQL username and password in settings.py or .env.
database does not existWrong database nameMake sure the database was created and the name matches exactly.
connection refusedPostgreSQL service isn’t runningStart PostgreSQL using sudo systemctl start postgresql.
ModuleNotFoundError: psycopgPostgreSQL driver missingInstall psycopg (or psycopg2-binary) in your virtual environment.
permission deniedDatabase user lacks privilegesGrant the required permissions to the PostgreSQL user.

Most migration failures are caused by configuration errors rather than problems with Django itself.


Step 8: Test the PostgreSQL Connection

At this stage, all the major configuration work is complete. PostgreSQL is installed, Django is configured to use it, and the required database tables have been created successfully.

The final step is to verify that everything works as expected.

Testing the connection ensures that your Django application can communicate with PostgreSQL without any issues. It’s much better to catch configuration problems now than after your application goes live.

Let’s perform a few simple checks.

Start the Django Development Server

The easiest way to test the database connection is to start your Django project.

From your project directory, run:

python manage.py runserver

If everything is configured correctly, you’ll see output similar to:

Watching for file changes with StatReloader
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

This indicates that Django started successfully and was able to connect to PostgreSQL during startup.

Open your browser and visit:

http://127.0.0.1:8000/

If you’re running Django remotely on a VPS, access it using your server’s public IP address and configured port instead.

If your homepage loads without any database-related errors, your PostgreSQL connection is working correctly.

Test the Django Admin Panel

If you created a superuser in the previous step, testing the admin dashboard is another excellent way to confirm the database connection.

Visit:

/admin/

Example:

http://your-server-ip/admin/

Log in using the administrator account you created earlier.

If you can:

  • Sign in successfully
  • View the admin dashboard
  • Browse models
  • Add or edit records

then Django is reading from and writing to your PostgreSQL database without any issues.

Verify the Active Database Connection

You can also confirm which database backend Django is currently using.

Open the Django shell:

python manage.py shell

Run:

from django.db import connection
print(connection.vendor)

Expected output:

postgresql

This confirms that Django is connected to PostgreSQL rather than SQLite.

Exit the shell:

exit()

Check Database Tables Directly

You can also verify the connection from PostgreSQL itself.

Connect to your database:

psql -U django_user -d myprojectdb -h localhost

List all tables:

\dt

You should see Django’s tables, such as:

auth_user
auth_group
django_admin_log
django_content_type
django_migrations
django_session

If these tables are present, PostgreSQL is storing your Django application’s data correctly.

Exit PostgreSQL:

\q

Perform a Simple Database Test

A practical way to confirm everything is working is to create a small piece of data.

For example, if your project already contains a model, open the Django shell:

python manage.py shell

Create a sample object:

from your_app.models import YourModel
YourModel.objects.create(name="Test Record")

Then retrieve it:

YourModel.objects.all()

If Django successfully creates and retrieves the record, it confirms that:

  • The application can connect to PostgreSQL.
  • Data can be written successfully.
  • Data can be read successfully.

Replace your_app and YourModel with the actual names from your project.

Check PostgreSQL Service Status

It’s also worth confirming that PostgreSQL is still running.

Execute:

sudo systemctl status postgresql

A healthy installation should display:

Active: active (running)

If the service is running, Django will be able to communicate with the database whenever it’s needed.

Verify Automatic Startup

Since production servers are restarted occasionally, for updates, maintenance, or unexpected outages, it’s important to ensure PostgreSQL starts automatically after a reboot.

Run:

systemctl is-enabled postgresql

Expected output:

enabled

If you see enabled, PostgreSQL will start automatically whenever the VPS boots.

Signs Everything Is Working Correctly

Your Django and PostgreSQL setup is ready if you can confirm the following:

  • Django starts without database errors.
  • The admin panel loads successfully.
  • Django reports postgresql as the active database backend.
  • PostgreSQL contains Django’s tables.
  • You can create and retrieve records successfully.
  • PostgreSQL is running as a system service.
  • PostgreSQL is configured to start automatically after a reboot.

If every item above checks out, your Django application is successfully connected to PostgreSQL.

What’s Next?

Connecting Django to PostgreSQL is an important milestone, but it’s only one part of preparing a production-ready deployment.

Once you’ve confirmed that everything is working, consider these next steps to improve your application’s performance, security, and reliability:

  • Configure Gunicorn or uWSGI as your application server.
  • Set up Nginx as a reverse proxy.
  • Secure your website with an SSL certificate using Let’s Encrypt.
  • Configure automatic PostgreSQL backups.
  • Enable a firewall and restrict unnecessary ports.
  • Monitor server resources and database performance.
  • Keep Django, PostgreSQL, and your operating system updated with the latest security patches.

With these improvements in place, your Django application will be better prepared to handle real users in a production environment.

The next sections of the article should be:

  1. Common Problems and How to Fix Them
  2. Security Best Practices
  3. Performance Tips for Production
  4. Quick Command Summary
  5. Conclusion
  6. Frequently Asked Questions (FAQs)

These sections will complete the guide by helping readers troubleshoot issues, secure their deployment, optimize PostgreSQL performance, and quickly revisit important commands whenever needed.


Common Problems and How to Fix Them

Even if you follow every step carefully, it’s normal to run into a few issues while connecting Django to PostgreSQL on a VPS. Most problems are caused by small configuration mistakes, such as incorrect credentials, missing packages, or permission issues.

The good news is that these errors are usually straightforward to fix once you know what to look for.

Below are some of the most common problems developers encounter, along with their likely causes and solutions.

Error or IssuePossible CauseHow to Fix It
FATAL: password authentication failedIncorrect PostgreSQL username or passwordDouble-check the values in your .env file or settings.py. Make sure the password matches the one assigned to the PostgreSQL user.
database “myprojectdb” does not existDatabase name is incorrect or the database hasn’t been createdLog in to PostgreSQL and run \l to verify the database exists. Update your Django configuration if the name doesn’t match.
connection refusedPostgreSQL service is stopped or not listeningCheck the service status with sudo systemctl status postgresql. Start it using sudo systemctl start postgresql if necessary.
ModuleNotFoundError: No module named ‘psycopg’PostgreSQL driver isn’t installed in the active virtual environmentActivate your virtual environment and install the required driver using pip install psycopg[binary] or pip install psycopg2-binary.
permission denied for schema publicThe database user doesn’t have permission to create tablesConnect as the PostgreSQL administrator and grant the required privileges on the public schema.
could not connect to serverIncorrect host or port configurationVerify that HOST is set to localhost (or the correct database server) and PORT is 5432 unless you’ve changed it.
Migrations fail unexpectedlyPostgreSQL credentials are incorrect or the database service isn’t availableReview your database configuration and confirm PostgreSQL is running before executing python manage.py migrate.
Django still uses SQLitesettings.py wasn’t updated correctly or an old configuration is being loadedVerify that DATABASES points to PostgreSQL and restart your application after making changes.

Most connection issues can be resolved by carefully reviewing your database credentials, confirming PostgreSQL is running, and ensuring the required Python packages are installed in the correct environment.


Security Best Practices

Getting Django connected to PostgreSQL is only the first step. If your application is running on a public VPS, taking a few extra security measures can help protect your database from unauthorized access and reduce the risk of future problems.

Here are some recommended practices to follow.

Use a Dedicated Database User

Avoid connecting Django with the default postgres superuser.

Instead, create a separate PostgreSQL user specifically for your application and grant only the permissions it needs. This limits the impact of accidental changes or compromised credentials.

Store Credentials Outside Your Source Code

Never leave database passwords directly inside settings.py.

Use environment variables or a .env file so sensitive information remains separate from your application code.

If you’re using Git, always add your .env file to .gitignore to prevent it from being committed accidentally.

Choose Strong Passwords

Your PostgreSQL password should be:

  • At least 16 characters long
  • Unique to your database
  • A mix of uppercase and lowercase letters
  • Include numbers and special characters

Avoid reusing passwords across different services.

Keep PostgreSQL Updated

Security updates often include important bug fixes and vulnerability patches.

Regularly update your VPS packages by running:

sudo apt update
sudo apt upgrade

Keeping PostgreSQL and your operating system up to date helps reduce potential security risks.

Restrict Database Access

If Django and PostgreSQL are running on the same VPS, PostgreSQL usually doesn’t need to accept remote connections.

Using localhost for your database host keeps the database accessible only from the local server, reducing unnecessary exposure.

If remote access is required, allow connections only from trusted IP addresses and secure them with appropriate firewall rules.

Back Up Your Database Regularly

No matter how secure your server is, backups are essential.

Create scheduled backups so you can quickly restore your application if something goes wrong due to hardware failure, accidental deletion, or software issues.

Testing your backup and restore process periodically is just as important as creating the backups themselves.

Monitor Database Activity

Keep an eye on your PostgreSQL logs and server resources.

Monitoring helps you identify unusual activity, performance bottlenecks, or repeated login failures before they become bigger problems.


Performance Tips for Production

Once your Django application starts receiving real traffic, a few performance optimizations can help PostgreSQL handle requests more efficiently.

Keep Indexes Up to Date

Indexes speed up database queries, especially when searching, filtering, or sorting large amounts of data.

Only create indexes where they’re actually needed, as unnecessary indexes can slow down write operations.

Optimize Database Queries

Whenever possible:

  • Retrieve only the fields you need.
  • Use Django’s select_related() and prefetch_related() for related objects.
  • Avoid unnecessary database queries inside loops.

Efficient queries reduce database load and improve response times.

Use Connection Pooling

Opening a new database connection for every request adds unnecessary overhead.

For larger applications, consider using a connection pooler such as PgBouncer to manage PostgreSQL connections more efficiently.

Monitor Slow Queries

As your application grows, some database queries may become slower.

Enable PostgreSQL logging for slow queries and review them periodically to identify opportunities for optimization.

Perform Regular Database Maintenance

PostgreSQL includes maintenance commands that help reclaim storage and update internal statistics.

Routine maintenance improves long-term database performance, especially for applications with frequent inserts, updates, or deletions.

Choose Fast Storage

Running PostgreSQL on SSD or NVMe storage significantly improves read and write performance compared to traditional hard drives.

Many VPS providers now include NVMe storage by default, making it an excellent choice for database workloads.

Allocate Sufficient Server Resources

If your application begins receiving more traffic, monitor CPU, memory, and disk usage.

Scaling your VPS resources when needed is often simpler than troubleshooting performance issues caused by resource limitations.


Quick Command Summary

Here’s a quick reference for the main commands used throughout this guide.

TaskCommand
Connect to VPSssh username@server_ip
Update packagessudo apt update
Install PostgreSQLsudo apt install postgresql postgresql-contrib -y
Check PostgreSQL versionpsql –version
Check PostgreSQL statussudo systemctl status postgresql
Start PostgreSQLsudo systemctl start postgresql
Enable PostgreSQL on bootsudo systemctl enable postgresql
Switch to postgres usersudo -i -u postgres
Open PostgreSQL shellpsql
Create databaseCREATE DATABASE myprojectdb;
Create database userCREATE USER django_user WITH PASSWORD ‘password’;
Grant database privilegesGRANT ALL PRIVILEGES ON DATABASE myprojectdb TO django_user;
Install PostgreSQL driverpip install psycopg[binary]
Create migrationspython manage.py makemigrations
Apply migrationspython manage.py migrate
Create Django superuserpython manage.py createsuperuser
Start Django serverpython manage.py runserver

Having these commands in one place makes it easy to revisit important steps without scrolling through the entire tutorial.


Conclusion

Connecting Django to PostgreSQL on a VPS is one of the first steps toward preparing your application for a production environment. While SQLite works well during development, PostgreSQL provides the performance, reliability, and scalability needed for real world deployments.

In this guide, you installed PostgreSQL, created a dedicated database and user, configured Django to use PostgreSQL, secured your database credentials with environment variables, ran migrations, and verified that everything was working correctly. By following these steps, your Django application is now using a production ready database that’s better equipped to handle growth and concurrent users.

As you continue deploying your application, consider setting up Gunicorn, Nginx, HTTPS with Let’s Encrypt, automated backups, and regular monitoring. These additions will help improve your server’s security, performance, and long term reliability, giving you a solid foundation for hosting Django applications on a VPS.


FAQs

1. Can Django work with PostgreSQL?

Yes. Django has built in support for PostgreSQL through its database backend. After installing a compatible PostgreSQL driver and updating the DATABASES configuration in settings.py, Django can use PostgreSQL for all database operations.

2. Do I need PostgreSQL for every Django project?

No. SQLite is suitable for learning, testing, and small projects. However, PostgreSQL is generally the preferred choice for production deployments because it offers better performance, reliability, and support for concurrent users.

3. Is PostgreSQL better than SQLite for production?

In most cases, yes. PostgreSQL is designed for production environments and provides advanced security, transaction support, scalability, and efficient handling of multiple simultaneous connections.

4. Which PostgreSQL driver should I install for Django?

For new projects, the modern psycopg package is a good choice. Existing projects may continue using psycopg2-binary if it’s already part of their deployment. Always use the driver that’s compatible with your Django version and project requirements.

5. How do I check if Django is connected to PostgreSQL?

You can run: python manage.py shell
Then execute: from django.db import connection
print(connection.vendor)
If the output is postgresql, Django is connected to your PostgreSQL database.

6. Can I migrate an existing Django project from SQLite to PostgreSQL?

Yes. Many developers begin with SQLite during development and later migrate to PostgreSQL for production. The process typically involves creating a PostgreSQL database, updating Django’s database configuration, applying migrations, and transferring any existing data if required.

7. Is PostgreSQL free to use on a VPS?

Yes. PostgreSQL is an opensource relational database management system and can be installed on most Linux VPS servers without licensing fees.

8. Should PostgreSQL run on the same VPS as Django?

For small to medium sized projects, running Django and PostgreSQL on the same VPS is a common and practical setup. As your application grows, you may choose to move PostgreSQL to a dedicated database server for improved scalability and resource isolation.

Sanjeet Chauhan
Sanjeet Chauhan

Passionate about helping websites thrive, Sanjeet Chauhan is a blogger and SEO expert who turns ideas into actionable strategies, sharing tips and insights that boost traffic, improve rankings, & create a strong online presence.

Articles: 35

Leave a Reply

Your email address will not be published. Required fields are marked *