如何解决Docker-Compose中的‘driver failed programming external connectivity’错误
我之前也踩过旧版本Docker的这个端口绑定残留坑,结合你的情况,咱们一步步来排查解决:
1. 彻底清理相关容器与残留进程
首先确保所有关联容器完全停止,避免残留的容器进程占用资源:
docker-compose down
然后精准清理残留的docker-proxy进程(比killall更彻底):
# 列出所有docker-proxy进程,找到对应PID ps aux | grep docker-proxy # 强制杀死目标进程,替换<PID>为实际进程号,比如你的3042 sudo kill -9 <PID>
2. 清理Docker残留网络配置
旧版本Docker的网络栈经常会留下端口绑定的残留信息,即使容器停了也不会自动释放。可以清理所有未被使用的网络:
docker network prune
执行时会提示确认,输入y即可——这个操作只会清理无容器关联的闲置网络,不会影响正常运行的容器。
3. 临时换端口验证问题
修改你的docker-compose.yml,把主机侧的端口临时换成3307,验证是否是原端口的绑定残留问题:
pe-db: image: mariadb:10.3 ports: - 3307:3306 # 临时修改主机端口 environment: MYSQL_DATABASE: dev_db MYSQL_PASSWORD: password MYSQL_USER: dev MYSQL_ROOT_PASSWORD: root_password
再运行docker-compose up,如果能正常启动,说明问题确实出在3306端口的Docker内部残留绑定上。
4. 根源解决方案:升级Docker版本
你使用的Docker 19.03.2和docker-compose 1.19.0都是2019年的旧版本,这类端口绑定不释放的bug在后续的稳定版中已经被修复。建议升级到较新的稳定版本(比如Docker 20.10.x系列或更高),同时把docker-compose也升级到v2.x的兼容版本,这能从根源上避免这类问题反复出现。
额外说明
你看到的tcp6 0 0 :::3306 :::* LISTEN 3042/docker-proxy是Docker代理的IPv6端口绑定,旧版本Docker在处理IPv6端口时很容易出现残留绑定的情况——即使杀死docker-proxy进程,重启Docker守护进程后也可能重新加载残留的网络配置,导致端口再次被占用,所以清理网络配置和升级版本是最有效的解决方式。
内容的提问来源于stack exchange,提问作者k0pernikus

