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 SilverSurferdb.sql是否有错误,或环境变量是否正确设置。
2. 检查端口映射与宿主机连通性
- 在Windows终端执行以下命令,确认5432端口是否被容器监听:
若输出包含netstat -ano | findstr :54320.0.0.0:5432,说明端口映射生效;否则重启容器或检查docker-compose配置。 - 用telnet测试端口连通性:
若连接失败,排查Windows防火墙是否阻挡了5432端口,可临时关闭防火墙测试,或添加入站规则允许该端口。telnet localhost 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
相关产品推荐
相关产品推荐

