如何从Docker容器连接宿主机MySQL数据库
问题描述
我正在打包应用并尝试将其部署到服务器上。服务器上已安装并运行MySQL数据库,我的Express Node.js应用需要与该数据库通信。
该Express应用将在Docker容器内运行,对应的Dockerfile如下:
FROM node:20-alpine COPY . /app WORKDIR /app EXPOSE 3001 CMD npm install && npm run build && npm run start
这是我用于读取环境变量的.env文件:
DATABASE_HOST= "localhost" # string ex: localhost | ip DATABASE_PORT= 3306 # number DATABASE_NAME= "mydatabase" # string DATABASE_USERNAME= "myuser" # string DATABASE_PASSWORD= "mypassword" # string
由于我还有前端项目,我使用Docker Compose来运行容器:
$ docker compose up
对应的docker-compose.yml文件:
services: webadmin: build: ./web ports: - 3000:3000 api: build: ./api ports: - 3001:3001
请问如何实现从Docker容器连接到宿主机的MySQL数据库?
解决方案
要实现Docker容器内的Express应用连接宿主机MySQL,需完成以下关键步骤:
1. 修正.env中的数据库主机地址
容器内的localhost指向容器自身,而非宿主机。需替换DATABASE_HOST为以下值之一:
- Docker 18.03+(跨平台):使用
host.docker.internal,这是Docker提供的指向宿主机的特殊域名 - 直接指定宿主机IP:使用宿主机的局域网IP或公网IP(确保容器能访问该IP)
修改后的.env示例(注意移除多余引号,避免解析错误):
DATABASE_HOST=host.docker.internal DATABASE_PORT=3306 DATABASE_NAME=mydatabase DATABASE_USERNAME=myuser DATABASE_PASSWORD=mypassword
2. 配置MySQL允许外部连接
默认MySQL仅允许本地localhost连接,需调整配置并授权用户:
- 编辑MySQL配置文件(常见路径:
/etc/mysql/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf),将bind-address改为0.0.0.0(允许所有IP访问),或指定容器所在子网IP - 重启MySQL服务:
sudo systemctl restart mysql - 登录MySQL,授权目标用户从外部访问:
其中GRANT ALL PRIVILEGES ON mydatabase.* TO 'myuser'@'%' IDENTIFIED BY 'mypassword'; FLUSH PRIVILEGES;%表示允许该用户从任意IP连接,也可指定容器所在的具体IP段以提升安全性。
3. 开放宿主机防火墙3306端口
若宿主机启用防火墙(如ufw、firewalld),需允许3306端口的入站流量:
- Ubuntu/Debian(ufw):
sudo ufw allow 3306 - CentOS/RHEL(firewalld):
sudo firewall-cmd --add-port=3306/tcp --permanent sudo firewall-cmd --reload
4. 可选:使用宿主机网络模式(不推荐)
若上述方法仍有问题,可让容器直接使用宿主机网络(会失去容器网络隔离性),修改docker-compose.yml的api服务:
services: webadmin: build: ./web ports: - 3000:3000 api: build: ./api ports: - 3001:3001 network_mode: "host" # 添加此行
此时容器共享宿主机网络,.env中的DATABASE_HOST可设为localhost。
内容的提问来源于stack exchange,提问作者Islam Y-
相关产品推荐
相关产品推荐

