关于 Docker MySQL 在 Laravel 活 ThinkPHP 中终端无法链接怎么解决?

203 天前
 tlerbao

问题

在 laravel 或 thinkphp 可能需要执行 php artisan 或 php think 来执行 migrate

但是我的会报错

[InvalidArgumentException]
  There was a problem connecting to the database: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddr
  info failed: nodename nor servname provided, or not known

PHP 代码中的 hostname 填 mysql (容器名),可以正常正常链接,但是填 127.0.0.1 不行

在 navicat 中却可以使用 127.0.0.1 链接,不太懂

我的 docker-composer 中的 MySQL 配置

  mysql:
    image: mysql:${MYSQL5_VERSION}
    container_name: mysql
    ports:
      - "${MYSQL5_HOST_PORT}:3306"
    volumes:
      - ${MYSQL5_CONF_FILE}:/etc/mysql/conf.d/mysql.cnf:ro
      - ${DATA_DIR}/mysql5:/var/lib/mysql/:rw
    restart: always
    networks:
      - default
    environment:
      MYSQL_ROOT_PASSWORD: "${MYSQL5_ROOT_PASSWORD}"
      TZ: "$TZ"
1021 次点击
所在节点    程序员
9 条回复
airycanon
203 天前
为了方便你理解,可以把 php 容器和 mysql 容器看成是“两台机器”(实际上并不是,而是独立的网络命名空间),
127.0.0.1:3306 连接的是 php “这台机器” 的 3306 端口,连接不到 mysql 所在的“机器”。

而 navicat 是在宿主机上运行的,可以连接 127.0.0.1:3306 是因为 docker 做了端口映射,你的 compose 配置有这样一段:
ports:
- "${MYSQL5_HOST_PORT}:3306"

表示把 mysql 容器的 3306 端口映射到宿主机的 3306 端口,你在宿主机上通过 127.0.0.1:3306 连接就会转发到 mysql 容器上。
512357301
203 天前
所以其实可以填宿主机的 IP 地址,类似 192.168.x.x
darklinden
203 天前
ports:
- "127.0.0.1: 3306":"3306"
tlerbao
203 天前
@airycanon 先感谢,为何没有所以呢,前面讲非常好,就没有然后了,哈哈哈。
tlerbao
203 天前
@512357301 @airycanon @darklinden
然后我发现昨天我换到了 orbstack 后,他有个 mysql.xx.orb.local 的容器域名
发现 php 的 database.php 里的 hostname 填这个就程序和终端的 php artisan 都正常了,。。。。
liuguang
203 天前
容器内的 127.0.0.1 和宿主的 127.0.0.1 是不同的,有网络隔离。所以 php 访问不到宿主的 127.0.0.1 。
PHP 里 hostname 填 mysql 是走的 docker 的 network ,实际是 mysql 的虚拟 IP 。
而在 navicat 中,也就是容器外部,当然是走宿主的网络了,因为你 docker 开了 ports 端口映射了。
miaotaizi
203 天前
有个项目 叫做 laradock 可以照着抄
darklinden
203 天前
@tlerbao #5

1. 使用我上面发的 mysql port 绑定

ports:
- "127.0.0.1: 3306":"3306"

compose 3+ 貌似可用,可以直接宿主机访问 127.0.0.1:3306 ,是一个新 trick

2. 或者在 compose 里为 mysql 添加 ip 配置

networks:
mysql_net:
ipv4_address: 10.0.0.1

并添加网络配置

networks:
app_net:
driver: bridge
ipam:
config:
- subnet: 10.0.0.0/8

宿主机可以直接访问 10.0.0.1

3. docker network 使用 host 模式 而不是 bridge 模式也可以,但是无法在 compose 内多个容器互相访问

4. 如果你的 php 也是在 compose 里面配置,可以 php 添加

depends_on:
- mysql

然后 php 容器内使用域名 mysql 访问 mysql 容器的 ip

对于 bridge 类型的容器网络,简单看作是虚拟机网段就可以了
tlerbao
192 天前
@darklinden #8
- "127.0.0.1: 3306":"3306" 这种写法在 compose 2 好像是非法的,格式不对,而且我好像没在 github 上看到 compose 3 呢哈哈

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/983590

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX