Set up a Docker and Django Postgres Environment (Part 2)

Introduction

This article is the second installment of our tutorial series describing how to set up a Docker and Django Postgres environment. Our goal is to create a Docker container that runs a Django web application and uses PostgreSQL for the application database. In the first article, we created a Django project folder inside of a Python virtual environment for the Docker container. Now, let’s pick up where we left off and set up the Django project, build the Docker container and configure both so that they can access a Postgres database.

Setup the Django project

We’ll begin by navigating to the Django project directory inside the Docker project folder. Inside the Django folder, there should be another directory for the project. Make sure to cd into it using the following command:

cd postgres_docker

Terminal screenshot creating a Django project inside of a Python virtual environment

Edit the settings for the Django project

At this point, if you list your files and directories using the ls command, you should see the settings.py Python script for the Django project. Open an IDE that has Python syntax support, such as Sublime or Visual Studio Code, and edit the file. You can use the subl command shown below to edit the file in Sublime or use code to open the file in VS Code:

subl settings.py

In order to use a PostgreSQL database and its psycopg2 adapter for Python in our Django app, we’ll need to modify some settings. This is because Django assumes that MySQL will be used for the app’s database. Scroll down to the section containing the DATABASES dict object and modify the sqlite3 value that’s located in the ENGINE key. This change will enable django.db.backends to allow a PostgreSQL database using the psycopg2 adapter.

The DATABASES variable should now look like the following:

# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'djangoproject',
'USER': 'orkb',
'PASSWORD': 'mypass123',
'HOST': 'localhost',
'PORT': '',
}
}

Screenshot of the Django project's settings.py file for the Postgres Docker container

Now, let’s change the empty Python list assigned to the ALLOWED_HOSTS environment settings. Make sure to enter the appropriate domains and IP addresses for your environment. It should look something like the following:

ALLOWED_HOSTS = ['0.0.0.0', 'localhost', '172.28.1.4', '172.28.0.0']

Deactivate the Python venv

When you’re done, save the changes to settings.py and close the editor. Switch back to the terminal and exit the virtual Python environment (venv) using the following command:

deactivate

Build the Docker container

You should now be outside of your Python virtual environment for the Django project. Type cd .. (or cd.. if you’re using a Windows command prompt) to go up one directory level to the location of the Dockerfile and docker-compose.yml files.

Edit the Docker Compose file

You’ll need to use your IDE to edit the docker-compose.yml file and add the following YAML:

version: "3.2"

services
:

# container name
postgres-cont
:

build
:
context
: ${PWD}

# open ports for Postgres and Django
ports
:
- "5432:5432"
- "8000:8000"

# bind mount volumes
volumes
:
- $PWD/pg-data/:/var/lib/postgresql/data
- $PWD/django-app/:/usr/src/django-app/

# configure Postgres environment variables
environment
:
- POSTGRES_USER=orkb
- POSTGRES_DB=djangoproject
- POSTGRES_PASSWORD=mypass123

networks
:
postgres-net
:
ipv4_address
: 172.28.1.4

networks
:
postgres-net
:
ipam
:
driver
: default
config
:
- subnet
: 172.28.0.0/16

The YAML syntax shown above will create a network for our container and give it an explicit IP address. It will also bind-mount volumes and create some environmental settings for the Postgres server.

Edit the Django Dockerfile

Next, let’s edit the Dockerfile in our project. We’ll add the following commands, which will pull from the latest postgres image and install Python 3.7:

FROM postgres:latest

# install Python 3
RUN apt-get update && apt-get install -y python3 python3-pip
RUN apt-get -y install python3.7-dev
RUN apt-get install postgresql-server-dev-10 gcc python3-dev musl-dev

# install psycopg2 library with PIP
RUN pip3 install psycopg2

# install the Django library
RUN pip3 install Django

# add the 'postgres' admin role
USER postgres

# expose Postgres port
EXPOSE 5432

# expose port for Django
EXPOSE 8000

This Dockerfile will expose the Django and Postgres ports, and it will use Python’s PIP package manager to install Django and psycopg2 for our docker container.

Build with Docker Compose

At this point, we’re ready to pull the Postgres image from Docker Hub and build the container. Make sure you’re still in the same directory as the docker-compose.yml file when you execute the command shown below. This command will pull the Postgres image and build the customized container for Django as it spins it up:

docker-compose up --build

NOTE: It may take a few minutes while you wait for Docker to pull the image and build the container.

While it’s building the containers, it should automatically create the pg-data folder for the PostgreSQL database data and create the djangoproject database for you.

Run the Django project

Let’s open another terminal tab while the docker-compose command builds and runs the Postgres container in the foreground. We’ll use this other tab or terminal window to execute commands within the Docker container itself.

Access the Docker container

After the container has finished building, use the docker ps command in the new tab to get the container ID:

docker ps

Use the first three digits of the alphanumeric ID to enter the container with the docker exec command. Here’s an example of what this command would look like:

docker exec -it a78 /bin/bash

NOTE: Docker will randomly generate an alphanumeric container ID for you, so make sure to replace the a78 value with the first three digits of your own ID when executing these commands.

Once you’re inside the container, navigate to the location of the Django project directory:

cd /usr/src/django-app/

Set up and run the Django application

If you use the ls command, you should see a manage.py Python script. You can use the python3 command to execute commands with the script.

For example, you can use the makemigrations command to migrate any packages to the project:

python3 manage.py makemigrations

It will either say No changes detected or migrate the necessary packages.

You can then apply these packages and migrate with the following command:

python3 manage.py migrate

NOTE: You must migrate the packages or you will get a Python Traceback error when you attempt to use the next createsuperuser command.

Access Docker Container with exec and managing Django project inside container

We can then use the script’s createsuperuser command to create a new user:

python3 manage.py createsuperuser

Change postgres to your new username. The process should look something like this:

postgres@ae1e87a8c780:/usr/src/postgres_docker$ python3 manage.py createsuperuser
Username (leave blank to use 'postgres'): orkb
Email address:
Password:
Password (again):
Superuser created successfully.

Our last step will be to run the Django server from within the container:

python3 manage.py runserver 0.0.0.0:8000

You should see the following response:

postgres@a871593dd2f2:/usr/src/postgres_docker$ python3 manage.py runserver 0.0.0.0:8000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
January 07, 2020 - 16:20:59
Django version 3.0.2, using settings 'postgres_docker.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

Let’s see if everything is working. Just navigate to http://0.0.0.0:8000 in a browser tab and you should see the Django welcome page.

Screenshot of

Press CTRL+C in the terminal window to shut down the Django server, and then type exit to leave the container. Then use the following command to shut down the container safely; make sure you execute this command while you’re in the same directory as the docker-compose.yml file:

docker-compose down

Conclusion

This concludes the second part of our series describing how to setup a Docker, Django, and Postgres development environment. If you’ve been following along with our step-by-step instructions, you should have a working Django welcome page that you can view in your browser. You’re now prepared to build your own Django web app that runs in a Docker container and uses PostgreSQL as its database.

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.