Starting a new Django project with PostgresSQL and Docker
Tags: django, python, docker, postgres
Published: 2024-07-03 15:36:37

## Initial project setup:

```bash
$ mkdir client-management
$ cd client-management
$ python3 -m venv .venv
$ source .venv/bin/activate
(.venv) $
(.venv) $ python3 -m pip install django~=5.0
(.venv) $ django-admin startproject django_project .
(.venv) $ python manage.py runserver 

```

Visit http://127.0.0.1:8000/ to confirm the successful install and then quit the server.

```bash
(.venv) $ touch requirements.txt
(.venv) $ pip freeze > requirements.txt
```

## Docker

Use Docker to streamline local development with PostgreSQL

- Read more about security before deployment
- <https://docs.docker.com/engine/security/rootless/>

After installing Django , deactivate the virtual environment and set up Docker. View my `Dockerfile` `docker-compose.yml` and `.dockerignore` files by visiting my repository on [GitHub here](https://github.com/Samuel-Lubliner/client-management).

```bash
(.venv) $ deactivate
$
$ touch Dockerfile docker-compose.yml .dockerignore
$ docker-compose up
```

### About Docker

- Docker Image: a read-only template with instructions for creating a container
- Supported Python images: <https://hub.docker.com/_/python/>
- `Dockerfile`: defines the custom image
- Docker container: running instance of a Docker image.
- `docker-compose.yml`: additional instructions for the container

### Docker flow:

1. create a new virtual environment and install Django
2. create a new Django project within it
3. add `Dockerfile` with custom image instructions
4. add `.dockerignore`
5. build the image
6. add `docker-compose.yml`
7. Spin up containers with `docker-compose up`
8. Stop the container:
  - Press `Control + c` 
  - Run `docker-compose down`

### Detached mode

- runs containers in the background. Use it for a single command line tab. Run `docker-compose up -d`
- Error output won’t always be visible in detached mode. See the current output by running `docker-compose logs`

### Docker vs  local commands

- Preface traditional commands with `docker-compose exec [service]`

For example:

```bash
$ docker-compose exec web python manage.py migrate
$ docker-compose exec web python manage.py createsuperuser
```

## Psycopg

Psycopg is a database adapter. Start off with the binary version for quick installation. Update if the project needs performance boost. Learn more:

- <https://www.psycopg.org/psycopg3/docs/basic/install.html#binary-installation>

- <https://docs.djangoproject.com/en/5.0/ref/databases/>

### Install Psycopg

First stop running the Docker container by running `docker-compose down`. Docker replaces the virtual environment. The Docker host replaces the local operating system. Since I am using docker, I won’t install locally. Instead, I will just update requirements.txt with the `psycopg[binary]` package at the bottom of the file.

## About `docker-compose.yml`

`docker-compose.yml` specifies two separate containers running within Docker.

1. web for the Django local server
2. db for the PostgreSQL database.

Docker containers are ephemeral. Information is lost when the container stops running. In `docker-compose.yml`, the `postgres_data` volumes mount binds to the local computer.

## Configure PostgreSQL

- Configure the environment to use trust authentication for the database. For a databases with many users, be more explicit with permissions.
- Update the `DATABASES` config in `django_project/settings.py` file to use PostgreSQL
- Now build the new image and start the two containers in detached mode by running `docker-compose up -d --build`.
- Refresh the Django welcome page at <http://127.0.0.1:8000/> to show Django has successfully connected to PostgreSQL via Docker. Remember to `docker-compose down` to save computer resources when you are finished.

## Up next

Before migrating, I will add a custom user model.