I am following this tutorial on 'Dockerizing' Django + PgSQL + gunicorn + nginx .
Relevant info
- host machine OS is Ubuntu 20.0.4 LTS
- Docker-desktop: Docker version 20.10.16, build aa7e414
This is my setup so far:
(relevant portions of) settings.py
import os
from pathlib import Path
from decouple import config
import dj_database_url
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config('DEBUG', cast=bool)
ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=lambda v: [s.strip() for s in v.split(',')])
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': config('DATABASE_NAME'),
'USER': config('DB_USER_NAME'),
'PASSWORD': config('DB_USER_PWD'),
'HOST': config('DB_HOST'),
'PORT': config('DB_PORT'),
}
}
# required for db to work on Heroku
db_from_env = dj_database_url.config(conn_max_age=600)
DATABASES['default'].update(db_from_env)
my-django-proj/my-django-proj/.env
ALLOWED_HOSTS=0.0.0.0,localhost,127.0.0.1,www.example.com,example.com,example.herokuapp.com
# Docker compose seems to need this
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
DEBUG=True
DATABASE_NAME=thedbname
DB_USER_NAME=myusername
DB_USER_PWD=thepassword
DB_HOST=localhost
DB_PORT=5432
Dockerfile
# pull official base image
FROM python:3.9.6-alpine
# set work directory
WORKDIR /usr/src/app
#############################
# set environment variables #
#############################
# Prevents Python from writing pyc files to disc (equivalent to python -B option)
ENV PYTHONDONTWRITEBYTECODE 1
# Prevents Python from buffering stdout and stderr (equivalent to python -u option)
ENV PYTHONUNBUFFERED 1
# install psycopg2 dependencies
RUN apk update \
&& apk add postgresql-dev gcc python3-dev musl-dev
# install dependencies
RUN pip install --upgrade pip
COPY ./my-django-proj/requirements.txt ./my-django-proj/
RUN pip install -r ./my-django-proj/requirements.txt
# copy project
COPY ./my-django-proj ./my-django-proj
compose.yml
services:
web:
build: .
command: python my-django-proj/manage.py runserver 0.0.0.0:8000
volumes:
- ./my-django-proj/:/usr/src/app/my-django-proj/
ports:
- 8000:8000
env_file:
- ./my-django-proj/my-django-proj/.env
depends_on:
- db
db:
image: postgres:14.3-alpine
restart: always
container_name: postgres14_3
#user: postgres
ports:
- 5432:5432
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=myusername
- POSTGRES_PASSWORD=thepassword
- POSTGRES_DB=thedbname
volumes:
postgres_data:
Output log from sudo docker compose up -d --build
postgres14_3 |
postgres14_3 | 2022-06-01 12:03:35.017 UTC [1] LOG: starting PostgreSQL 14.3 on x86_64-pc-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 64-bit
postgres14_3 | 2022-06-01 12:03:35.017 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres14_3 | 2022-06-01 12:03:35.017 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres14_3 | 2022-06-01 12:03:35.022 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres14_3 | 2022-06-01 12:03:35.028 UTC [50] LOG: database system was shut down at 2022-06-01 12:03:34 UTC
postgres14_3 | 2022-06-01 12:03:35.032 UTC [1] LOG: database system is ready to accept connections
Migration attempt output by running: sudo docker compose exec web python my-django-proj/manage.py migrate --noinput
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
self.connect()
File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
self.connection = self.get_new_connection(conn_params)
File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
connection = Database.connect(**conn_params)
File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 122, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Address not available
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
So I decided to do a bit of investigation on my host machine
output of sudo netstat -tulpn | grep LISTEN
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 118855/docker-proxy
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 1017/redis-server 1
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 934/memcached
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 754/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 997/sshd: /usr/sbin
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 72912/cupsd
tcp 0 0 0.0.0.0:5432 0.0.0.0:* LISTEN 118727/docker-proxy
tcp6 0 0 :::44543 :::* LISTEN 58417/code
tcp6 0 0 :::8000 :::* LISTEN 118862/docker-proxy
tcp6 0 0 ::1:6379 :::* LISTEN 1017/redis-server 1
tcp6 0 0 :::22 :::* LISTEN 997/sshd: /usr/sbin
tcp6 0 0 ::1:631 :::* LISTEN 72912/cupsd
tcp6 0 0 :::5432 :::* LISTEN 118734/docker-proxy
PG is obviously running on port 5432 (so the Django message is misleading - I think). I try to connect to the Db on the container as follows:
sudo docker compose exec db psql -U myusername thedbname
psql (14.3) Type "help" for help.
thedbname=#
So clearly, PG is running in the container - so, what is causing the Db connection to be refused? - and how do I fix it, so that I can run my migrations, and access the Django project on http://localhost:8000 on my local machine?