Cannot connect django to postgres running inside docker container - django

My django app is not dockerized, but I run postgres inside docker container using docker-compose.yml script. After docker-compose up I can connect to db with dbeaver, but not with django app. Every time I'm getting an error:
django.db.utils.OperationalError: could not translate host name "db" to address:
Temporary failure in name resolution
File docker-compose.yml:
version: "3.9"
services:
db:
image: postgres:13
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"
- POSTGRES_USER="postgres"
- POSTGRES_PASSWORD="postgres"
- POSTGRES_DB="postgres"
ports:
- 5432:5432
volumes:
postgres_data
Django project file config/settings.py:
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': env.str("DB_NAME"),
'USER': env.str("DB_USER"),
'PASSWORD': env.str("DB_PASS"),
'HOST': env.str("DB_HOST"),
'PORT': env.decimal("DB_PORT")
}
}

It was some kind of pipenv error. When I restarted terminal and executed pipenv shell again and then python manage.py runserver everything worked just fine

Related

failed to connect with Postgres container in Django

django.db.utils.OperationalError: connection to server at "db" (172.18.0.2), port 5432 failed: FATAL: the database system is starting up
I have an issue connecting to the Postgres contaner. I was trying in different ways like setting passwords only in the docker-compose file. Still am stuck.
docker-compose.yml
version: '3'
services:
db:
image: postgres:alpine
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_USER=user
- POSTGRES_DB=userdb
volumes:
- django_db:/var/lib/postgresql/data
container_name: db
singup:
build: .
command: python manage.py runserver 0.0.0.0:8000
ports:
- 8000:8000
container_name: singup
depends_on:
- db
volumes:
django_db:
database setting
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'userdb',
'USER': 'user',
'PASSWORD': 'password',
'HOST': 'db',
}
}
This is a timing issue, even thought you have the below line
singup:
depends_on:
- db
It's just waiting for db container to be up and running, not neccessarily Postgres.
To avoid this, use a tool such as wait-for-it, dockerize, sh-compatible wait-for, or RelayAndContainers template. These are small wrapper scripts which you can include in your application’s image to poll a given host and port until it’s accepting TCP connections.
For example, to use wait-for-it.sh or wait-for to wrap your service’s command:
singup:
depends_on:
- db
command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
Repo of wait-for-it: https://github.com/vishnubob/wait-for-it

could not translate host name to "db" to address: Unknown host

I'm attempting to follow the guide provided by: https://docs.docker.com/compose/django/
Whenever I attempt to makemigrations, it gives me the Unknown host error given in the title. I'm trying to use PostgreSQL with Django and Wagtail as its CMS
My docker-compose.yml looks like:
version: "3.9"
services:
db:
image: postgres
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
and my settings in the settings.py file look like:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': 'db',
'PORT': 5432,
}
}
Am I missing anything?
Your code can run in two different environments, and hard-coding the connection information might not be correct.
You mention in a comment that you're running something like:
docker-compose up -d db
python manage.py makemigrations
In this environment python is running outside of Docker. If you add ports: [5432:5432] to the database configuration in the docker-compose.yml file, the database will be accessible via (probably) localhost. On the other hand, when you run docker-compose up, the application runs inside Docker and the database will be reachable at db.
You can use an environment variable to configure this. I find it useful to give these variables default values that would be useful for a developer, and set them to different values in my deployment setup (the docker-compose.yml).
DATABASES = {
'default': {
...
'HOST': os.getenv('DB_HOST', 'localhost'),
...
}
}
version: "3.9"
services:
db:
ports:
- '5432:5432' # makes this accessible from your development environment
...
web:
environment:
- DB_HOST=db
...

Struggling with connection between Django and Postgres within Docker containers

I've been hitting the following error for awhile now and can't seem to fix it...
django.db.utils.OperationalError: could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port 5432?
Multiple resources stated it was simply due to the HOST setting within my DATABASES, but the following is what I am working with and still can't get it to work:
DATABASES = {
'default': {
'HOST': 'db',
'ENGINE': 'django_postgrespool2',
'NAME': os.environ.get('PROJECT_HEARSAY_DB_NAME'),
'USER': os.environ.get('PROJECT_HEARSAY_DB_USER'),
'PASSWORD': os.environ.get('PROJECT_HEARSAY_DB_PASSWORD'),
'PORT': os.environ.get('PROJECT_HEARSAY_DB_PORT'),
}
}
Here is the Dockerfile for my Django app:
FROM python:3
ENV PYTHONUNBUFFERED 1
COPY . /app
WORKDIR /app
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
Here is the Dockerfile for my Postgresql DB:
FROM postgres
And here is the docker-compose.yml that I am working with:
version: "3"
services:
postgresql:
build:
context: ./db
container_name: db.postgresql
ports:
- 5432:5432
environment:
POSTGRES_DB: "db_name"
POSTGRES_USER: "username"
POSTGRES_PASSWORD: "password"
django:
restart: always
build:
context: ./api
command: bash -c "./manage.py migrate && ./manage.py runserver 0.0.0.0:8000"
container_name: api.django
ports:
- 8000:8000
depends_on:
- postgresql
I'm curious if anyone here could shed some light on what I am doing wrong.
Thank you.
Your container name is db.postgresql, so your connection string should be db.postgresql or postgresql in the host name.
DATABASES = {
'default': {
'HOST': 'db.postgresql',
'ENGINE': 'django_postgrespool2',
'NAME': os.environ.get('PROJECT_HEARSAY_DB_NAME'),
'USER': os.environ.get('PROJECT_HEARSAY_DB_USER'),
'PASSWORD': os.environ.get('PROJECT_HEARSAY_DB_PASSWORD'),
'PORT': os.environ.get('PROJECT_HEARSAY_DB_PORT'),
}
}
you can verify the connection
docker exec api.django bash -c "nslookup db.postgresql"
You will get the Postgres container IP inside your Django container.

Running Django migrations on dockerized project

I have a Django project running in multiple Docker containers with help of docker-compose. The source code is attached from directory on my local machine. Here's the compose configuration file:
version: '3'
services:
db:
image: 'postgres'
ports:
- '5432:5432'
core:
build:
context: .
dockerfile: Dockerfile
command: python3 manage.py runserver 0.0.0.0:8000
ports:
- '8001:8000'
volumes:
- .:/code
depends_on:
- db
Although the application starts as it should, I can't run migrations, because every time I do manage.py makemigrations ... I receive:
django.db.utils.OperationalError: could not translate host name "db" to address: nodename nor servname provided, or not known
Obviously I can open bash inside the core container and run makemigrations from there, but then the migration files are created inside the container which is very uncomfortable.
In my project's settings the database is configured as:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'HOST': 'db',
'PORT': '5432',
}
}
As docker postgres image is accessible at localhost:5432 I tried changing database host in settings to:
'HOST': '0.0.0.0'
But then when firing up the containers with docker-compose up I'm receiving:
...
django.db.utils.OperationalError: could not connect to server:
Connection refused
Is the server running on host "0.0.0.0" and accepting
TCP/IP connections on port 5432?
...
How should I configure database in settings.py so that Django can access it to create migrations?
Your docker-compose configurations are not correct. You forgot to link services
version: '3'
services:
db:
image: 'postgres'
ports:
- '5432:5432'
core:
build:
context: .
dockerfile: Dockerfile
command: python3 manage.py runserver 0.0.0.0:8000
ports:
- '8001:8000'
volumes:
- .:/code
depends_on:
- db
links: # <- here
- db

Dockerized Django REST Framework / Postgresql - Disallowed host

When I try to execute the following command:
sudo docker-compose up
I get the following error inside my terminal:
Here is what my docker file looks like:
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /agent-technologies
WORKDIR /agent-technologies
COPY . /agent-technologies
RUN pip install -r requirements.txt
EXPOSE 8000
Here is what my docker-compose.yml looks like:
version: '3'
services:
db:
image: postgres
environment:
- POSTGRES_USER=stefan_radonjic
- POSTGRES_PASSWORD=cepajecar995
- POSTGRES_DB=agent_technologies_db
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/agent-technologies
ports:
- "8000:8000"
links:
- db
depends_on:
- db
And finally here are settings of PostgresSQL DB I have previously created :
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'agent_technologies_db',
'USER': 'stefan_radonjic',
'PASSWORD': 'cepajecar995',
'HOST': 'db',
'PORT': '',
}
}
The error is quite self explanatory.. You didn't set your ip in your ALLOWED_HOSTS setting. Try adding these to your settings file:
ALLOWED_HOSTS = ['*'] # wildcard, allows all
Or if you want to be explicit:
ALLOWED_HOSTS = ['0.0.0.0'] # explicit
Your django app is trying to connect to 'localhost' database, but as it is inside its own container -- localhost is not right uri to reach database.
Dockercompose will resolve your namequeries to database if you will refer to is by db container name. In your case it is "db"
As text on picture reads -- you have to add "0.0.0.0" into your ALLOWED_HOSTS variable inside your settings module.
Be sure that you've read django documentation carefully. It is pretty vigorous.