簡體   English   中英

Django 與 Docker 上的 postgreSQL DB - django.db.utils.OperationalError:無法連接到服務器:連接被拒絕

[英]Django with postgreSQL DB on Docker - django.db.utils.OperationalError: could not connect to server: Connection refused

我正在關注關於“Dockerizing”Django + PgSQL + gunicorn + nginx 的本教程

相關信息

  1. 主機操作系統是 Ubuntu 20.0.4 LTS
  2. Docker-desktop:Docker 版本 20.10.16,構建 aa7e414

這是我到目前為止的設置:

(相關部分)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

撰寫.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:      

來自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

通過運行遷移嘗試輸出: 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?

所以我決定對我的主機做一些調查

sudo netstat -tulpn | grep LISTEN 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 顯然在端口 5432 上運行(所以 Django 消息具有誤導性 - 我認為)。 我嘗試按如下方式連接到容器上的 Db:

sudo docker compose exec db psql -U myusername thedbname

psql (14.3) 鍵入“幫助”以獲得幫助。

數據庫名稱=#

很明顯,PG 正在容器中運行——那么,是什么導致 Db 連接被拒絕? - 我該如何修復它,以便我可以運行我的遷移,並在我的本地機器上訪問 http://localhost:8000 上的 Django 項目?

如果您不需要從主機訪問 postgres,則不需要端口映射。

容器可以一起通信,因為它們應該是使用服務名稱的同一網絡的一部分,在您的情況下,您可以嘗試使用db ,它是您的 postgres 容器的名稱,而不是 localhost。

要回答您的確切問題,要從 docker 容器訪問主機,您需要訪問host.docker.internal host.docker.internal將指向您的主機 localhost。

請參閱此 SO 帖子

對於 Linux,您可能仍需要添加:

extra_hosts:
    - "host.docker.internal:host-gateway"

到您的 docker-compose 的網絡服務。

我仍然建議使用第一種方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM