容器内Django可连PostgreSQL,外部运行无法解析DB主机‘db’
问题原因及解决方案
核心原因
Docker Compose会自动创建专属内部网络,服务名db是该网络内的内部域名,只有同属这个Docker网络的容器(比如你的web服务容器)能通过DNS解析到对应的PostgreSQL容器IP。而容器外的宿主机不在这个Docker网络里,本地DNS无法识别db这个主机名,因此抛出域名解析失败的错误。
解决方法
方法1:临时修改配置(快速测试)
直接修改Django配置文件(如settings.py)里的数据库HOST为localhost,但需满足两个前提:
docker-compose.yml中已给db服务配置端口映射:services: db: image: postgres:13 ports: - "5432:5432" # 将容器内5432端口映射到宿主机同端口 # 其他配置...- PostgreSQL容器允许宿主机连接:
- 进入容器:
docker exec -it <容器ID/名称> bash - 修改
/var/lib/postgresql/data/pg_hba.conf,添加:host all all 0.0.0.0/0 md5 - 修改
/var/lib/postgresql/data/postgresql.conf,设置:listen_addresses = '*' - 重启容器:
docker restart <容器ID/名称>
- 进入容器:
方法2:用环境变量区分环境(推荐)
在Django的settings.py中通过环境变量动态读取数据库HOST,避免频繁修改配置:
import os DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ.get('DB_NAME', 'your_db_name'), 'USER': os.environ.get('DB_USER', 'your_db_user'), 'PASSWORD': os.environ.get('DB_PASSWORD', 'your_db_pass'), 'HOST': os.environ.get('DB_HOST', 'db'), # 默认用容器内域名,本地开发可覆盖 'PORT': os.environ.get('DB_PORT', '5432'), } }
容器外启动项目前,在终端设置环境变量:
export DB_HOST=localhost # 按需设置其他变量,如DB_USER、DB_PASSWORD python manage.py runserver
方法3:让宿主机解析db域名
修改宿主机的/etc/hosts文件,添加一行:
127.0.0.1 db
这样宿主机可直接将db解析到本地,配合端口映射使用即可,无需修改Django配置。
内容的提问来源于stack exchange,提问作者J. Donič
相关产品推荐
相关产品推荐

