My django project cannot connect to postgres database container. What I should to do?
It crashes on commands python manage.py collectstatic --noinput && python manage.py makemigrations blog && python manage.py migrate.
I know docker run command creates a new container but I have more commands as
one by bash in docker-compose.yml. It should works, shouldn't it?
my Dockerfile:
FROM python:3.6-alpine
MAINTAINER Name <name#domain>
ENV PYTHONUNBUFFERED 1
ENV INSTALL_PATH /heckblog
RUN mkdir -p $INSTALL_PATH
WORKDIR $INSTALL_PATH
COPY requirements.txt requirements.txt
# make available run pip install psycopg2
RUN apk update && \
apk add --virtual build-deps gcc python3-dev musl-dev && \
apk add postgresql-dev
RUN pip3 install -r requirements.txt
# add bash into alpine linux
RUN apk add --update bash && rm -rf /var/cache/apk/*
COPY ./heckblog .
#RUN pip install .
CMD gunicorn -b 0.0.0.0:8000 --access-logfile - "config.wsgi:application"
my docker-compose.yml:
version: '2'
services:
db:
image: postgres:alpine
environment:
POSTGRES_USER: blogdmin
POSTGRES_PASSWORD: password
POSTGRES_DB: heckblog
PGDATA: /tmp/pgdata
volumes:
- postgres_data:/tmp/pgdata
web:
build: .
command: >
bash -c "sleep 10 &&
python manage.py collectstatic --noinput &&
python manage.py makemigrations blog &&
python manage.py migrate &&
echo \"from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin#example.com', 'pass')\" | python manage.py shell &&
gunicorn -b 0.0.0.0:8000 --access-logfile - --reload \"config.wsgi:application\""
volumes:
- ./heckblog:/heckblog
depends_on:
- db
environment:
IN_DOCKER: 1
ports:
- "80:8000"
volumes:
postgres_data:
settings.py:
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'heckblog',
'USER': 'blogdmin',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '', # default port
}
}
...
Output of docker-compose up --build:
web_1 | TCP/IP connections on port 5432?
web_1 | could not connect to server: Connection refused
web_1 | Is the server running on host "localhost" (127.0.0.1) and accepting
web_1 | TCP/IP connections on port 5432?
web_1 |
heckblog_web_1 exited with code 1
I use:
Windows 10
Docker 17.03.0-ce-win1-(10296)
docker-compose version 1.11.2
Django==1.10.6
psycopg2==2.7.1.
Thanks for answers
Each container in docker by default gets its own hostname and IP. When compose spins up the containers for you, it also places all of the containers on a network by default to permit DNS based discovery.
What this means is that your database is not reachable on localhost, but you can reach it by the service name "db". Change this line in your settings.py:
'HOST': 'localhost',
to:
'HOST': 'db',
Here's what worked for me:
in compose:
version: '3.7'
services:
web:
build: .
command: python /code/manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- 8000:8000
environment:
- DB_HOST=db
- DB_NAME=web
- DB_USER=postgres
- DB_PASSWORD=postgres
depends_on:
- db
db:
image: postgres:12-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_DB=web
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
postgres_data:
in settings:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME'),
'USER':os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
'HOST':os.environ.get('DB_HOST'),
'PORT':5432,
}
}
Django settings.py -> Database={host:db} . Other database option remain same. Like
DATABASE_ENGINE=django.db.backends.postgresql
DATABASE_USER=postgres
DATABASE_PASSWORD=1234
DATABASE_NAME=pos
DATABASE_HOST=db
DATABASE_PORT=5432
Docker compose yml file: This settings created for Django, Nginx, Postgres
version: '3.8'
services:
nginx:
restart: unless-stopped
build:
context: .
dockerfile: ./docker/nginx/Dockerfile
ports:
- '81:81'
volumes:
- static_volume:/home/pos/static/
- ./docker/nginx/development:/etc/nginx/conf.d
depends_on:
- backend
backend:
restart: unless-stopped
build:
context: .
dockerfile: ./docker/backend/Dockerfile
image: pos-backend:backend # image_name: image_tag
container_name: pos_backend
volumes:
- ./backend:/home/pos/
- static_volume:/home/pos/static
- media_volume:/home/pos/media
environment:
DJANGO_SETTINGS_MODULE: pos.settings
ports:
- "8000:8000"
command: python manage.py runserver 0.0.0.0:8000
expose:
- 8000
env_file:
- ./backend/.env.dev
depends_on:
- db
db:
image: postgres:12
container_name: pos_db
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=1234
- POSTGRES_DB=pos
ports:
- '5432:5432'
expose:
- 5432
networks:
- default
volumes:
static_volume: {}
media_volume:
postgres_data:
Related
How to fix this error?
nginx: [error] init_by_lua error: /usr/local/share/lua/5.1/kong/cmd/utils/migrations.lua:16: Database needs bootstrapping or is older than Kong 1.0.
To start a new installation from scratch, run 'kong migrations bootstrap'.
To migrate from a version older than 1.0, migrated to Kong 1.5.0 first.
If you still have 'apis' entities, you can convert them to Routes and Services
using the 'kong migrations migrate-apis' command in Kong 1.5.0.
stack traceback:
[C]: in function 'error'
/usr/local/share/lua/5.1/kong/cmd/utils/migrations.lua:16: in function 'check_state'
/usr/local/share/lua/5.1/kong/init.lua:562: in function 'init'
init_by_lua:3: in main chunk
dockerfile files
FROM python:3.10
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
docker-compose files
version: '3.9'
services:
kong-database:
image: postgres:latest
container_name: kong-database
restart: always
ports:
- 15432:5432
networks:
- default
volumes:
- db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=kong
- POSTGRES_USER=kong
- POSTGRES_PASSWORD=kong
kong:
image: kong:latest
container_name: kong
restart: always
ports:
- 18000:8000
- 18443:8443
- 127.0.0.1:8001:8001
- 18444:8444
links:
- kong-database:kong-database
networks:
- default
environment:
- LC_CTYPE=en_US.UTF-8
- LC_ALL=en_US.UTF-8
- KONG_DATABASE=postgres
- KONG_PG_HOST=kong-database
- KONG_PG_USER=kong
- KONG_PG_PASSWORD=kong
- KONG_CASSANDRA_CONTACT_POINTS=kong-database
- KONG_PROXY_ACCESS_LOG=/dev/stdout
- KONG_ADMIN_ACCESS_LOG=/dev/stdout
- KONG_PROXY_ERROR_LOG=/dev/stderr
- KONG_ADMIN_ERROR_LOG=/dev/stderr
- KONG_ADMIN_LISTEN=0.0.0.0:18001, 0.0.0.0:18444 ssl
konga:
image: pantsel/konga
container_name: kong-konga
restart: always
ports:
- 1337:1337
networks:
- default
volumes:
- data:/app/kongadata
links:
- kong:kong
environment:
- NODE_ENV=production
networks:
default:
driver: bridge
volumes:
db:
driver: local
data:
driver: local
setting.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'kong',
'USER': 'kong',
'PASSWORD': 'kong',
'HOST': '127.0.0.1',
'PORT': '15432',
}
}
You can just start postgresql and do the migration with docker command then use your docker compose
Start postgresql:
docker compose up kong-database
then do the migration
docker run --rm --network=default \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_DATABASE=kong" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_PASSWORD=kong" \
kong:latest kong migrations bootstrap
And finally start kong and konga
docker compose up kong konga
Or you can add a kong-migration use the profile donotstart to not start it by default
kong-migration:
image: kong:latest
command: "kong migrations bootstrap"
networks:
- default
restart: on-failure
environment:
- KONG_PG_HOST=kong-database
- KONG_PG_USER=kong
- KONG_PG_PASSWORD=kong
links:
- kong-database
depends_on:
- kong-database
profiles:
- donotstart
then
docker compose up kong-migration
and finally
docker compose up
I'm building an API that fetches data from a MySQL database using Docker. I've tried everything and I always get this error: 2005 (HY000): Unknown MySQL server host 'db' (-3). Here is my docker compose file:
version: '3'
services:
web:
container_name: nginx
image: nginx
volumes:
- ./nginx/nginx.conf:/tmp/nginx.conf
environment:
- FLASK_SERVER_ADDR=backend:9091
- DB_PASSWORD=password
- DB_USER=user
- DB_HOST=db
command: /bin/bash -c "envsubst < /tmp/nginx.conf > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
ports:
- 80:80
networks:
- local
depends_on:
- backend
backend:
container_name: app
build: flask
environment:
- FLASK_SERVER_PORT=9091
- DB_PASSWORD=password
volumes:
- flask:/tmp/app_data
restart: unless-stopped
networks:
- local
depends_on:
- db
links:
- db
db:
container_name: db
image: mysql
restart: unless-stopped
volumes:
- ./mysql:/docker-entrypoint-initdb.d
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=database
- MYSQL_USER=user
- MYSQL_PASSWORD=password
ports:
- 3306:3306
networks:
local:
volumes:
flask:
driver: local
db:
driver: local
Inside the flask directory I have my Dockerfile like so:
FROM ubuntu:latest
WORKDIR /src
RUN apt -y update
RUN apt -y upgrade
RUN apt install -y python3
RUN apt install -y python3-pip
COPY . .
RUN chmod +x -R .
RUN pip install -r requirements.txt --no-cache-dir
CMD ["python3","app.py"]
Finally, on my app.py file I try to connect to the database with the name of the Docker container. I have tried using localhost and it still gives me the same error. This is the part of the code I use to access it:
conn = mysql.connector.connect(
host="db",
port=3306,
user="user",
password="password",
database="database")
What is it that I'm doing wrong?
The containers aren't on the same networks:, which could be why you're having trouble.
I'd recommend deleting all of the networks: blocks in the file, both the blocks at the top level and the blocks in the web and backend containers. Compose will create a network named default for you and attach all of the containers to that network. Networking in Compose in the Docker documentation has more details on this setup.
The links: block is related to an obsolete Docker networking mode, and I've seen it implicated in problems in other SO questions. You should remove it as well.
You also do not need to manually specify container_name: in most cases. For the Nginx container, the Docker Hub nginx image already knows how to do the envsubst processing so you do not need to override its command:.
This should leave you with:
version: '3.8'
services:
web:
image: nginx
volumes:
- ./nginx/nginx.conf:/etc/nginx/templates/default.conf.template
environment: { ... }
ports:
- 80:80
depends_on:
- backend
backend:
build: flask
environment: { ... }
volumes:
- flask:/tmp/app_data
restart: unless-stopped
depends_on:
- db
db:
image: mysql
restart: unless-stopped
volumes:
- ./mysql:/docker-entrypoint-initdb.d
- db:/var/lib/mysql
environment: { ... }
ports:
- 3306:3306
volumes:
flask:
db:
Hello I can not dockerize my django app because I got an error -
listen tcp4 0.0.0.0:5433: bind: address already in use
From the other hand, when I "kill" 5433 port in ubuntu terminal I get this error
Is the server running on host "localhost" (::1) and accepting
web_1 | TCP/IP connections on port 5433?
What can I do to solve this problem and dockerize successfully my app?
Dockerfile
FROM python:3
RUN adduser --system --no-create-home django
ENV PYTHONUNBUFFERED=1
WORKDIR /code
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
ENV PYTHONPATH /code
EXPOSE 8000
USER django
CMD ["./main.py"]
docker-compose
version: "3"
services:
db:
image: postgres
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=fitshop
- POSTGRES_USER=fituser
- POSTGRES_PASSWORD=fitpass
ports:
- "5433:5433"
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
restart: always
ports:
- "8000:8000"
depends_on:
- db
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'fitshop',
'USER': 'fituser',
'PASSWORD': 'fitpass',
'HOST': 'localhost',
'PORT': '5433',
}
}
You should use "db" as host here. In a docker-compose setup each service is started in a separate Container and the /etc/hosts config of all containers is modified so, that each container can find the other containers via the service names.
I`ve got it!. In 'localhost" port of postgres was 5433 but for 'db' as HOST it was default, 5432.
I am trying to run python backend with mysql database in docker container locally and stumble upon the error when I run docker-compose up command
backend_1 | django.db.utils.OperationalError: (2002, "Can't connect
to MySQL server on 'db' (115)")
My Docker file:
FROM python:3.9
ENV PYTHONUNBUFFERED 1
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app
CMD python manage.py runserver 0.0.0.0:8000
docker-compose.yml
version: '3.8'
services:
backend:
restart: always
build:
context: .
dockerfile: Dockerfile
command: 'python manage.py runserver 0.0.0.0:8000'
ports:
- 8000:8000
volumes:
- .:/app
depends_on:
- db
links:
- db
db:
image: mysql:5.7.22
restart: always
environment:
MYSQL_DATABASE: mysql
MYSQL_USER: admin
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: password
volumes:
- .dbdata:/var/lib/mysql
ports:
- 33066:3306
In settings.py
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mysql',
'USER': 'admin',
'PASSWORD': 'password',
'HOST': 'db',
'PORT': '3306',
}
}
In docker-compose.yml I had to add
hostname: 'db'
like that:
version: '3.8'
services:
backend:
restart: always
build:
context: .
dockerfile: Dockerfile
command: 'python manage.py runserver 0.0.0.0:8000'
ports:
- 8000:8000
volumes:
- .:/app
depends_on:
- db
links:
- db
db:
image: mysql:5.7.22
hostname: 'db'
restart: always
environment:
MYSQL_DATABASE: mysql
MYSQL_USER: admin
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: password
volumes:
- .dbdata:/var/lib/mysql
ports:
- 33066:3306
and it worked well
UPDATE:
Not really. When I run docker-compose the second time I get the same error
I'm trying to convert an existing Wagtail site to run with Docker. I have created the image and then run the container, but I'm unable to connect in the browser window. Getting 0.0.0.0 didn’t send any data. ERR_EMPTY_RESPONSE.
Dockerfile:
FROM python:3.6
RUN mkdir /app
WORKDIR /app
COPY ./ /app
RUN pip install --no-cache-dir -r /app/requirements/base.txt
RUN mkdir -p -m 700 /app/static
RUN mkdir -p -m 700 /app/media
ENV DJANGO_SETTINGS_MODULE=mysite.settings.dev DJANGO_DEBUG=on
ENV SECRET_KEY=notsosecretkey
ENV DATABASE_URL=postgres://none
ENV SENDGRID_KEY=sendgridkey
EXPOSE 8080
RUN chmod +x /app/entrypoint.sh \
&& chmod +x /app/start-app.sh
RUN python manage.py collectstatic --noinput
ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["/app/start-app.sh"]
docker-compose.yml:
version: '2'
services:
db:
environment:
POSTGRES_DB: app_db
POSTGRES_USER: app_user
POSTGRES_PASSWORD: changeme
restart: always
image: postgres:9.6
expose:
- "5432"
ports:
- "5432:5432"
app:
container_name: mysite_dev
build:
context: .
dockerfile: Dockerfile
depends_on:
- db
links:
- db:db
volumes:
- .:/app
ports:
- "8080:8080"
environment:
DATABASE_URL: postgres://app_user:changeme#db/app_db
command: python manage.py runserver 0.0.0.0:8080
entrypoint.sh:
#!/bin/sh
set -e
exec "$#"
start-app.sh:
#!/bin/sh
python manage.py runserver 0.0.0.0:8080
dev.py settings file:
from .base import *
DEBUG = True
for template_engine in TEMPLATES:
template_engine['OPTIONS']['debug'] = True
ALLOWED_HOSTS = (
'0.0.0.0',
)
DATABASES = {
'default': db_cache_url.config('DATABASE_URL', extra={'CONN_MAX_AGE': 0, 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'mysite', 'HOST': 'localhost', 'PORT': '5432'}),
}
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
WSGI_APPLICATION = 'mysite.wsgi.application'
try:
from .local import *
except ImportError:
pass
I run docker run -p 8080:8080 app:latest and it works when I run docker ps showing that it's at 0.0.0.0:8080->8080/tcp, but when I go to 0.0.0.0:8080 in the browser window, I get the error. If I remove the DATABASES setting, I see Django errors loading, but then I'm getting settings.DATABASES is improperly configured. Please supply the NAME value. so I think it needs to be there. What am I missing?