You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django连接Docker中PostgreSQL数据库失败求助

Django连接Docker中PostgreSQL的连接问题排查

问题概述

在Windows系统上使用venv虚拟环境本地运行Django项目,Docker容器部署PostgreSQL数据库。运行python manage.py makemigrations时无法建立连接,出现超时错误;使用psql连接也遇到类似问题。尝试过localhost、0.0.0.0、本地IP(172.16.98.1)及容器名作为HOST均无效,使用localhost和127.0.0.1时还触发Unicode解码错误。

现有配置

Django settings.py数据库配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'SilverSurfer',
        'USER': 'postgres',
        'PASSWORD': "root",
        'HOST': "host.docker.internal",
        'PORT': '5432',
    }
}

Docker Compose配置

version: "3.9"

services:
  db:
    image: postgres:15.0
    environment:
      POSTGRES_DB: SilverSurfer
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: root
    ports:
      - "5432:5432"
    volumes:
      - ./db.sql:/docker-entrypoint-initdb.d/db.sql

数据库容器运行状态

CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS          
528ad4e3232f   postgres:15.0   "docker-entrypoint.s…"   37 minutes ago   Up 37 minutes   
PORTS                    NAMES
0.0.0.0:5432->5432/tcp   02_db-db-1

报错信息

使用localhost/127.0.0.1时的Unicode解码错误栈:

(myenv) PS C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend> python manage.py makemigrations
Traceback (most recent call last):
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\manage.py", line 22, in <module>
    main()
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\core\management\__init__.py", line 442, in execute_from_command_line       
    utility.execute()
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\core\management\__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\core\management\base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\core\management\base.py", line 458, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\core\management\base.py", line 106, in wrapper
    res = handle_func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\core\management\commands\makemigrations.py", line 156, in handle
    loader.check_consistent_history(connection)
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\db\migrations\loader.py", line 313, in check_consistent_history
    applied = recorder.applied_migrations()
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\db\migrations\recorder.py", line 81, in applied_migrations
    if self.has_table():
       ^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\db\migrations\recorder.py", line 57, in has_table
    with self.connection.cursor() as cursor:
         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\db\backends\base\base.py", line 330, in cursor
    return self._cursor()
           ^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\db\backends\base\base.py", line 306, in _cursor
    self.ensure_connection()
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\db\backends\base\base.py", line 289, in ensure_connection
    self.connect()
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\db\backends\base\base.py", line 270, in connect
    self.connection = self.get_new_connection(conn_params)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\django\db\backends\postgresql\base.py", line 275, in get_new_connection
    connection = self.Database.connect(**conn_params)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Abdul\Software_Projekte\SilverSurfer\04_Backend\myenv\Lib\site-packages\psycopg2\__init__.py", line 122, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 91: invalid start byte

排查解决思路

1. 验证容器内PostgreSQL可用性

  • 进入容器内部直接连接数据库,确认服务正常:
    docker exec -it 02_db-db-1 psql -U postgres -d SilverSurfer
    
    若能成功连接,说明数据库本身无问题;若失败,检查初始化脚本db.sql是否有错误,或环境变量是否正确设置。

2. 检查端口映射与宿主机连通性

  • 在Windows终端执行以下命令,确认5432端口是否被容器监听:
    netstat -ano | findstr :5432
    
    若输出包含0.0.0.0:5432,说明端口映射生效;否则重启容器或检查docker-compose配置。
  • 用telnet测试端口连通性:
    telnet localhost 5432
    
    若连接失败,排查Windows防火墙是否阻挡了5432端口,可临时关闭防火墙测试,或添加入站规则允许该端口。

3. 修复Unicode解码错误

  • 该错误通常由psycopg2处理连接参数时的编码问题导致:
    • 检查settings.py中是否存在非UTF-8字符(如密码中的特殊字符),尝试将密码改为纯ASCII字符。
    • 在PowerShell中设置UTF-8编码后再运行Django命令:
      $OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
      python manage.py makemigrations
      

4. 调整PostgreSQL的访问控制配置

  • 进入容器,修改pg_hba.conf允许宿主机访问:
    docker exec -it 02_db-db-1 bash
    echo "host all all 0.0.0.0/0 scram-sha-256" >> /var/lib/postgresql/data/pg_hba.conf
    
  • 检查postgresql.conf中的listen_addresses是否设置为*:
    sed -i "s/listen_addresses = 'localhost'/listen_addresses = '*'/g" /var/lib/postgresql/data/postgresql.conf
    
  • 重启容器使配置生效:
    docker restart 02_db-db-1
    

5. 容器间通信的配置(若计划Django也容器化)

  • 在docker-compose中添加自定义网络,并将Django和DB服务加入同一网络:
    version: "3.9"
    networks:
      django_db_net:
        driver: bridge
    
    services:
      db:
        image: postgres:15.0
        environment:
          POSTGRES_DB: SilverSurfer
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: root
        volumes:
          - ./db.sql:/docker-entrypoint-initdb.d/db.sql
        networks:
          - django_db_net
      web:
        build: .
        command: python manage.py runserver 0.0.0.0:8000
        ports:
          - "8000:8000"
        depends_on:
          - db
        networks:
          - django_db_net
    
  • Django settings.py中HOST设为db(DB服务名):
    DATABASES = {
        'default': {
            # ...其他配置
            'HOST': "db",
            # ...其他配置
        }
    }
    

内容的提问来源于stack exchange,提问作者user23705833

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 15:30:55