Use a Database with Django#

The Django container you built last week contains a SQLite database. SQLite is a great database for simple applications but it doesn’t scale. Databases in cloud applications is a complicated subject that we’ll start thinking about this week. The first thing to know is that your precious application data cannot live in a container’s writable layer!

Setup#

The Django container will communicate with a container running the Postgres DBMS over a private Docker network. The Postgres container should not expose any ports to the host, it’s completely hidden from the outside world for security. Let’s create a Docker network:

$ docker network create django 

Verify your network is there:

$ docker network list
NETWORK ID     NAME      DRIVER    SCOPE
9850eee009e7   bridge    bridge    local
28e6c097494d   django    bridge    local
a99d5edd9623   host      host      local
81a76cda7c70   none      null      local

Add your existing Django container to the django network. This enables communication with the DBMS.

$ docker network connect django django

Explore Dockerhub#

Search Dockerhub for the official Postgres container. There are key questions you need answers for:

  1. What versions are available and what should I use?

  2. How do I configure the container?

  3. How do I set the db’s root password?

  4. Do I need to create a schema or extra users?

  5. Where is the data stored?

Answer these questions before you continue.

Start Postgres#

Let’s start the container:

$ docker run -d --name postgres --network django -e POSTGRES_PASSWORD=django -e POSTGRES_DB=mysite postgres:14.1

Connect From the Django Container#

Containers on the same network can connect to each other by name. The Django container needs some extra software to be able to access the database:

root@69545ebcd7a2:/# apt install postgresql-client
root@69545ebcd7a2:/# pip install psycopg2-binary

Tip

Make a note of the apt and pip lines. You’ll need to make sure these packages are installed in your Dockerfile

Verify that you can make the connection using Python’s REPL:

>>> import psycopg2 
>>> psycopg2.connect("host='postgres' user='postgres' password='django'")
<connection object at 0x7facdfe98540; dsn: 'user=postgres password=xxx host=postgres', closed: 0>
>>> quit() 

Configure Django#

Django’s database configuration is found in mysite/settings.py. Alter the DATABASES variable with the new configuration:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'mysite',
        'USER': 'postgres',
        'PASSWORD': 'django',
        'HOST': 'postgres',
    },
}

Warning

The database contains all of the user and other information from Django. When you switch databases all of the information is lost. You now have to re-initialize the new database which will be empty to start with.

Let’s get Django to rebuild the new database:

root@69545ebcd7a2:/app/mysite# python3 manage.py migrate 
root@69545ebcd7a2:/app/mysite# python3 manage.py makemigrations

Congratulations! You should be able to run and see your migrated Django installation:

root@69545ebcd7a2:/app/mysite# python3 manage.py runserver 0.0.0.0:80