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:
1 | cd postgres_docker |
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:
1 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 | # 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': '', } } |
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:
1 | 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:
1 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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:
1 | 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:
1 | 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:
1 | 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:
1 | 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:
1 | 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:
1 | 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.
We can then use the script’s createsuperuser
command to create a new user:
1 | python3 manage.py createsuperuser |
Change postgres
to your new username. The process should look something like this:
1 2 3 4 5 6 | 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:
1 | python3 manage.py runserver 0.0.0.0:8000 |
You should see the following response:
1 2 3 4 5 6 7 8 9 | 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.
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:
1 | 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