如何用Docker-Compose运行两个MySQL实例?端口配置遇阻求助
兄弟,我太懂你这种折腾多数据库实例的痛苦了!之前我也在Docker里搞双MySQL踩过一堆坑,结合你的情况,给你梳理几个最可能出问题的点和解决方案:
1. 别搞混宿主机和容器内部端口
很多人犯的低级错误:以为要改MySQL容器内部的端口,其实完全没必要!MySQL默认在容器内监听3306,你只需要把宿主机端口映射成6603就行,容器内部还是用3306,这样不用改任何MySQL配置,省心又不容易错。
正确的端口映射写法:
ports: - "6603:3306"
左边是宿主机端口,右边是容器内的MySQL默认端口,这样外部(包括Python容器)要访问第二个实例时,从宿主机连就用localhost:6603,如果是Docker内部的Python容器,直接用服务名+容器内端口(比如mysql2:3306)就行。
2. 绝对不能共用数据卷
两个MySQL实例必须用独立的数据卷/本地目录,要是共用一个,轻则启动失败,重则数据直接损坏!
在docker-compose里给每个实例分配单独的卷:
# 第一个实例的卷 volumes: - mysql_data_1:/var/lib/mysql # 第二个实例的卷 volumes: - mysql_data_2:/var/lib/mysql
然后在compose文件末尾声明这两个卷:
volumes: mysql_data_1: mysql_data_2:
如果用本地目录挂载,也要指定不同的路径,比如./mysql_data_1:/var/lib/mysql和./mysql_data_2:/var/lib/mysql。
3. 环境变量别乱设,尤其是端口相关的
如果你没改容器内的MySQL端口,别瞎设MYSQL_TCP_PORT这个环境变量,它会强制MySQL在容器内监听指定端口,要是你映射的宿主机端口和这个不匹配,直接就连接失败了。
如果确实要改容器内端口(其实完全没必要),那得同步改三个地方:
- 设置
MYSQL_TCP_PORT: 6603 - 端口映射改成
"6603:6603" - 确保Python连接字符串用
mysql2:6603
4. 网络要打通,别让Python容器找不到新实例
确保你的Python容器和两个MySQL实例在同一个Docker网络里,这样Python才能用服务名(比如mysql1、mysql2)直接访问,不用绕宿主机IP。
在compose里统一配置网络:
networks: app_network: driver: bridge
然后每个服务都加入这个网络:
networks: - app_network
给你个完整的可运行示例
直接抄这个改改参数就能用,绝对不会踩坑:
version: '3.8' services: # 原有的MySQL实例(宿主机3306) mysql1: image: mysql:8.0 container_name: mysql_primary environment: MYSQL_ROOT_PASSWORD: myrootpass123 MYSQL_DATABASE: app_db_1 MYSQL_USER: app_user MYSQL_PASSWORD: apppass123 ports: - "3306:3306" volumes: - mysql_data_1:/var/lib/mysql restart: unless-stopped networks: - app_network # 新的MySQL实例(宿主机6603) mysql2: image: mysql:8.0 container_name: mysql_secondary environment: MYSQL_ROOT_PASSWORD: myrootpass456 MYSQL_DATABASE: app_db_2 MYSQL_USER: app_user_2 MYSQL_PASSWORD: apppass456 ports: - "6603:3306" volumes: - mysql_data_2:/var/lib/mysql restart: unless-stopped networks: - app_network # Python脚本容器 python_app: build: ./your_python_project # 换成你的Python项目目录或者镜像名 container_name: python_script volumes: - ./your_scripts:/app depends_on: - mysql1 - mysql2 networks: - app_network volumes: mysql_data_1: mysql_data_2: networks: app_network: driver: bridge
最后排查小技巧
如果还是报错,先看容器日志找具体原因:
docker logs mysql_secondary
常见的日志报错比如:宿主机端口被占用(用netstat -tulpn | grep 6603检查)、数据卷权限问题(删除旧卷再重建)、MySQL版本兼容性问题(尽量用同一个镜像版本)。
内容的提问来源于stack exchange,提问作者simmons

