当Docker容器无法连接到宿主机上的数据库时,通常涉及网络配置问题。以下是常见原因及解决方法:
在容器内连接宿主机数据库时,不要使用localhost
或127.0.0.1
,而应该使用:
host.docker.internal
(Docker 18.03+)host.docker.internal
ip addr show
或ifconfig
查看)确保数据库服务监听所有网络接口(而不仅是localhost):
-- MySQL示例
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
修改数据库配置文件(如MySQL的my.cnf
):
bind-address = 0.0.0.0
使用host网络模式(最简单但不推荐生产环境):
docker run --network=host your_image
这样容器将共享宿主机的网络栈,可以直接访问localhost
使用bridge网络(推荐): 确保容器和宿主机在同一网络,或正确配置端口映射
如果数据库运行在宿主机上,确保容器可以访问宿主机的端口:
# 运行容器时映射宿主机端口
docker run -p 3306:3306 your_image
检查并调整防火墙规则:
# Ubuntu示例
sudo ufw allow 3306
# CentOS示例
sudo firewall-cmd --zone=public --add-port=3306/tcp --permanent
sudo firewall-cmd --reload
确保数据库用户有从远程主机连接的权限:
CREATE USER 'username'@'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON database.* TO 'username'@'%';
FLUSH PRIVILEGES;
在docker-compose.yml中,可以使用extra_hosts
:
services:
your_service:
extra_hosts:
- "host.docker.internal:host-gateway"
在容器内测试网络连接:
docker exec -it your_container bash
apt-get update && apt-get install -y telnet # 如无telnet
telnet host.docker.internal 3306
检查宿主机是否监听端口:
netstat -tuln | grep 3306
检查容器网络配置:
docker inspect your_container | grep IPAddress
通过以上步骤,应该能够解决大多数Docker容器连接宿主机数据库的问题。如果问题仍然存在,可能需要根据具体环境进一步排查。