Deploying a Django Project, Part 3: Configuring Project Settings and Creating a PostgreSQL Database - Practicality Beats Purity

Deploying a Django Project, Part 3: Configuring Project Settings and Creating a PostgreSQL Database

If you have been following along with this tutorial series, you should now have a server, or Droplet on Digital Ocean, with an admin-level user and basic requirements installed. In Part 3, we will continue by configuring some project settings on our local system and using the python-decouple library to save our sensitive information in an environment file. We will also log back in to our server and create a PostgreSQL database to handle our project data.

 

Configuring Django Project Settings

Before continuing the deployment process on our production server, now is a good time to make some necessary changes to your project settings file. On your local computer, open up your Django project in your text editor of choice (I like VS Code myself but it's up to you) and open your settings.py file.

The first setting we will change is DEBUG. Now is the time to change it to False. Now that your project is being deployed in a production environment, you do not want to leave debug mode on! This leaves your server vulnerable to attacks. So go ahead and change DEBUG to False.

DEBUG = False

The next setting we will change is ALLOWED_HOSTS. If you have followed the steps in Part 1 of this tutorial series and already have your custom domain name set up, then you can add it here. If it has been long enough, and your nameservers are pointing to Digital Ocean, your website will be ready to load via your domain name. In this case, change your ALLOWED_HOSTS setting to the following, using your own custom domain name:

ALLOWED_HOSTS = ['yourcustomdomainname.com', 'www.yourcustomdomainname.com']

Note that you want to add your domain both with and without the www subdomain. This way, your site will load whether the user types in www or not. Moreover, some browsers add the www subdomain automatically, so you need your site to load in those cases.

If you have not set up a custom domain name, or if you want to continue before your domain registrar has finished setting up your new nameservers, then add your Droplet's IP address to the ALLOWED_HOSTS setting (e.g. '123.456.78.910'). Remember to add the IP as a string!

ALLOWED_HOSTS = ['<your_server's_IP_address>']

If you do add your server's IP address directly, then note that you will want to remove it as soon as you have your custom domain name set up.

Next up, we need to configure the project settings to use the PostgreSQL database that we will set up on our server. Scroll down in your settings.py file until you find the DATABASES setting. You can delete the original settings and replace them, but I prefer to keep the original settings for when debug mode is on (i.e. when I am working in my local development environment). This will allow your project to keep its access to your local SQLite database that Django creates by default in development. That way, you can keep using your SQLite database on your local computer for continued development if you want to add features, debug, or make improvements down the road.

With all that said, change your DEBUG settings to look like this:

if DEBUG:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': ,
            'USER': ,
            'PASSWORD': ,
            'HOST': 'localhost',
            'PORT': '',
        }
    }

Notice that in debug mode, which should only ever be active in your local development environment, you can still access your SQLite database. In production, where debug mode should always be deactivated, you will access the PostgreSQL database that we will create soon.

Also note that I have left the NAMEUSER, and PASSWORD settings blank for now. We will fill those in soon. The PORT setting can simply be left as an empty string.

Finally, a note on static files. You may have your static files configured in different ways, and this is where many bugs come up in my experience. The way I have configured my static files settings is as follows:

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')

This is not the only way to configure static files, but it has worked for me. In this way, when you run the collectstatic command further in the deployment process, Django will create a new static_root directory where your static files will be hosted from on the server.

 

Storing Sensitive Information in an Environment File

To finish configuring our settings, we need to store some of our sensitive information in a separate environment file. Now, there are different ways to protect your sensitive information, such as using environment variables, but in this tutorial we will be using the Python library python-decouple. For development, you can use environment variables on your local system, and you can even use the same process with your Ubuntu server, but python-decouple is much simpler to deal with. For example, if you create environment variables on your Ubuntu server, they will not be accessible to certain Django processes, which will create bugs that are difficult to resolve (speaking from experience). This issue is completely obviated by using python-decouple, which saves your sensitive information in a separate .env file within your project directory, rather than in environment variables on your system.

Install python-decouple in your local environment with the following command. Make sure you are in your local project with your virtual environment active (assuming you are using one).

pip install python-decouple

With python-decouple installed, let's create a .env file for our sensitive information. In your text editor, create a new file called .env (don't forget the dot!) in your root project directory (the same directory where your manage.py file should be located).

In the file, add variable names for your sensitive information. You can name them whatever you'd like, but here is a typical example:

SECRET_KEY=
DB_NAME=
DB_USER=
DB_PASSWORD=

Now go back to your settings.py file. At the top, add the following import statement:

from decouple import config

Now we can replace all our sensitive variables in our settings with references to those variables in our .env file. First, copy the important values into your .env file. These should include your project SECRET_KEY as well as your database name, user, and password. Note that spaces are not used between the variable name, the assignment operator, and the values. Your .env file should look something like this:

SECRET_KEY=r)x3&r7z-r-bs=mn%umnw5h)$$njo^ptn8uxmk*0#79_9==%ry
DB_NAME=example_db
DB_USER=example_user
DB_PASSWORD=testing123

Make sure you save your .env file. In settings.py, your SECRET_KEY setting should look like the following:

SECRET_KEY = config('SECRET_KEY')

The config function from python-decouple links your project settings to the variables you created in your .env file. Let's change our database settings as well to add our database name, user, and password:

if DEBUG:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': config('DB_NAME'),
            'USER': config('DB_USER'),
            'PASSWORD': config('DB_PASSWORD'),
            'HOST': 'localhost',
            'PORT': '',
        }
    }

Finally, and very importantly, we need to add our .env file to our .gitignore file. Assuming you are using Git to store your project on a remote repository, such as GitHub, you do not want the sensitive information in your .env file to be pushed to that remote repository. To accomplish this, simply add .env to the end of your .gitignore file.

.env

Now your project settings should be fully configured for deployment and your settings.py file is safe to be pushed to a remote repository.

 

Installing Gunicorn and Psycopg2

Before leaving our local development environment, we need to install two additional dependencies to be able to use Gunicorn and our PostgreSQL database. Psycopg2 is an adaptor that allows Django to communicate with PostgreSQL. We can install both with the following command. Again, make sure you are in your local development environment on your local system with your virtual environment active (assuming you are using one).

pip install gunicorn psycopg2-binary

Finally, we need to add these to a requirements.txt file, which will allow us to easily install all our project dependencies on our Ubuntu server, or Droplet. If you already have a requirements.txt file, that's fine. If not, that's also fine. Run the following command in either case:

pip freeze > requirements.txt

This will either create a requirements.txt file with the names and versions of all your project dependencies, or it will update that existing file with any new dependencies.

 

Create a PostgreSQL Database on Your Server

Now that we have our project settings configured for production, with all the necessary dependencies, we can set up our PostgreSQL database on our server, or Droplet. SSH into your server if you are logged out. Remember that you can SSH into your admin-level user with the following command in a terminal (or PowerShell, etc.).

ssh example_user@<your_server's_IP_address>

Once you are logged in to your user in your server, we are ready to set up our database. Log in to a PostgreSQL session with the following command:

sudo -u postgres psql

You may have to input your user's password to run this sudo-level command. Essentially, you are now logged in to PostgreSQL with a default user named postgres. You should now see a prompt like this:

postgres=#

You are now logged in to the admin-level postgres user in PostgreSQL, and you can now begin to set up our database. First, create a database for your Django project. Here, I name the database example_db. You can name it whatever you want, but it must be the same name you entered as the database name in your .env file. Make sure all your SQL statements end in a semicolon, by the way, or you may experience problems.

# CREATE DATABASE example_db;

Next, you should create a user and password for your database. Again, this should be the same username and password that you set up in your .env file for the database. Make sure you use a secure password in your own project (not testing123!).

# CREATE USER example_user WITH PASSWORD 'testing123';

There are a few other settings you should configure before you are done with PostgreSQL. Type in each of these commands in turn:

# ALTER ROLE example_user SET client_encoding TO 'utf8';
# ALTER ROLE example_user SET default_transaction_isolation TO 'read committed';
# ALTER ROLE example_user SET timezone TO 'UTC';

Finally, give your user administrative privileges for your database:

# GRANT ALL PRIVILEGES ON DATABASE example_db TO example_user;

Now you are finished with PostgreSQL, and your database is ready to be used by your Django project on your server. Pretty easy! Log out of PostgreSQL with the following command:

# \q

That's it for Part 3 of this tutorial series. You've set up your project for production and configured your PostgreSQL database. In Part 4, we'll finish setting up our project on our Ubuntu server, and we'll copy our project to our server through our remote repository with Git. We'll also set up Gunicorn and NGINX. By the end of Part 4, our project will be live on our custom domain! You can find Part 4 here.

-------------------------------

Full Deploying a Django Project tutorial series:

Part 1: Creating and Managing a Custom Domain Name

Part 2: Setting Up the Server

Part 3: Configuring Project Settings and Creating a PostgreSQL Database

Part 4: Clone Your Project onto the Server

Part 5: Launch Your Project with Gunicorn and NGINX

Part 6: SSL/TLS Certificate and Continuing Development

 

Additional resources:

https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-20-04

https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-20-04

https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04

Comments
Kvvilldaype May, 9, 2021: 3:25
1 2 Аминоэтил пиперазин 99 процентов купить онлайн Интернет магазин ХИММЕД Tegs: 1 2 Аминоэтил 2 метил 5 нитроимидазол дигидрохлорид моногидрат 98 процентов купить онлайн Интернет магазин ХИММЕД https://chimmed.ru/products/1-2-aminoethyl-2-methyl-5-nitroimidazole-dihydrochloride-monohydrate-98-id=301999 Натрий сульфит 98 процентов ACS reagent безводный купить онлайн Интернет магазин ХИММЕД Натрий сульфит 98 5 процентов безводный чда купить онлайн Интернет магазин ХИММЕД Натрий сульфат порошок безводный 99 процентов чда купить онлайн Интернет магазин ХИММЕД
Sdvilldaype May, 21, 2021: 12:46
Завод Электромедоборудование Tegs: Загорский оптико механический завод https://chimmed.ru/manufactors/catalog?name=%D0%97%D0%B0%D0%B3%D0%BE%D1%80%D1%81%D0%BA%D0%B8%D0%B9+%D0%BE%D0%BF%D1%82%D0%B8%D0%BA%D0%BE-%D0%BC%D0%B5%D1%85%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9+%D0%B7%D0%B0%D0%B2%D0%BE%D0%B4 Dalian Welchem Industry And Trade Datalogic Dayang Chemicals
Add a new comment