2

I have used cookiecutter-django for my django projects. I am using docker to run the project locally. The project is running well. However, i could not explore postgres while using docker.

Here are the steps i followed to run the project

docker-compose -f local.yml build

docker-compose -f local.yml up -d

docker-compose run django python manage.py makemigrations

docker-compose run django python manage.py migrate

local.yml looks like following

version: '3'

volumes:
  local_postgres_data: {}
  local_postgres_data_backups: {}

services:
  django: &django
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: travel_local_django
    depends_on:
      - postgres
      - mailhog
    volumes:
      - .:/app
    env_file:
      - ./.envs/.local/.django
      - ./.envs/.local/.postgres
    ports:
      - "8000:8000"
    command: /start

  postgres:
    build:
      context: .
      dockerfile: ./compose/production/postgres/Dockerfile
    image: travel_production_postgres
    volumes:
      - local_postgres_data:/var/lib/postgresql/data
      - local_postgres_data_backups:/backups
    env_file:
      - ./.envs/.local/.postgres


compose/production/postgres/Dockerfile

FROM postgres:11.3

COPY ./compose/production/postgres/maintenance /usr/local/bin/maintenance
RUN chmod +x /usr/local/bin/maintenance/*
RUN mv /usr/local/bin/maintenance/* /usr/local/bin \
    && rmdir /usr/local/bin/maintenance


.envs/.local/.postgres

# PostgreSQL
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=simplifytour
POSTGRES_USER=debug
POSTGRES_PASSWORD=debug

when i did docker-compose -f local.yml ps, i get the container related to this project. I then executed the postgres container with command docker exec -it travel_postgres_1 sh. There i tried running the command like psql, psql -U postgres but nothing worked for me. I wanted to explore the postgres like listing the tables, connecting to the database etc.

Did i miss any steps? How can i use postgres container?

Serenity
  • 3,884
  • 6
  • 44
  • 87

3 Answers3

2

TL;DR

If you want to access the containered postgres installation you'd have to add the port mapping to your configuration:

  postgres:
    build:
      context: .
      dockerfile: ./compose/production/postgres/Dockerfile
    image: travel_production_postgres
    volumes:
      - local_postgres_data:/var/lib/postgresql/data
      - local_postgres_data_backups:/backups
    env_file:
      - ./.envs/.local/.postgres
    ports:
      - "5432:5432"

Note how the port mapping was added in the last two lines.

If you have a local postgres installation, you may want to use a different host port, though (e.g. "8001:5432"). More details further below.

The changes will take effect, after a restart of the container: docker-compose -f local.yml up. There is no need to start the postgres container separately (due to the depends_on: -postgres setting in the django-service it will be started by docker whenever the django-service is started).

Explanation:

The change to the ports-section allows you to connect to port 5432 and reach the service in the container, which is bound to the same port. The order of the ports is "HOST_PORT:CONTAINER_PORT", which makes it possible, to map different ports to each other. If e.g. you already have a postgres installation up and running locally (so on your host machine), this may be necessary. When your local postgres installation uses port 5432 already, you can expose your container to a different port instead and that way still distinguish and access both postgres instances.

Why is postgres not available by default?

If it was just for django, to forward these ports is not necessary, due to the way docker compose works:

"By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name."

From the docker docs: Networking in Compose

So the django container can reach the postgres container without any port forwarding thanks to the network handling done by docker compose. In order for a port to become accessible from your host machine, it therefore has to be forwarded explicitly (as it is done e.g. with the django service itself, to allow the development server to be reachable under port 8080).

Sidenote: While you may safely change the local-configuration, be careful about changes to the production configuration. Every additional port you use may also be abused. So only add ports here, if you are aware of the (security) consequences.

Kim
  • 1,361
  • 3
  • 18
  • 24
0

You can use django dbshell:

docker-compose run django python manage.py dbshell

or, if django container is already running:

docker exec -it django python manage.py dbshell
zbusia
  • 571
  • 2
  • 7
0

In addition to the previous answers, I also needed to ensure that the postgres client was installed within my container. For us this is installed as and when required rather than adding to our Dockerfile.

So from within the containers terminal run apt-get install -y postgresql-client then ./manage.py dbshell successfully deposits me in the postgres shell.

whatapalaver
  • 865
  • 13
  • 25