V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tlerbao
V2EX  ›  程序员

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

  •  
  •   tlerbao · 191 天前 · 1004 次点击
    这是一个创建于 191 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题

    在 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"
    
    9 条回复    2023-10-31 16:29:44 +08:00
    airycanon
        1
    airycanon  
       191 天前
    为了方便你理解,可以把 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
        2
    512357301  
       191 天前 via Android
    所以其实可以填宿主机的 IP 地址,类似 192.168.x.x
    darklinden
        3
    darklinden  
       191 天前
    ports:
    - "127.0.0.1: 3306":"3306"
    tlerbao
        4
    tlerbao  
    OP
       191 天前
    @airycanon 先感谢,为何没有所以呢,前面讲非常好,就没有然后了,哈哈哈。
    tlerbao
        5
    tlerbao  
    OP
       191 天前
    @512357301 @airycanon @darklinden
    然后我发现昨天我换到了 orbstack 后,他有个 mysql.xx.orb.local 的容器域名
    发现 php 的 database.php 里的 hostname 填这个就程序和终端的 php artisan 都正常了,。。。。
    liuguang
        6
    liuguang  
       191 天前
    容器内的 127.0.0.1 和宿主的 127.0.0.1 是不同的,有网络隔离。所以 php 访问不到宿主的 127.0.0.1 。
    PHP 里 hostname 填 mysql 是走的 docker 的 network ,实际是 mysql 的虚拟 IP 。
    而在 navicat 中,也就是容器外部,当然是走宿主的网络了,因为你 docker 开了 ports 端口映射了。
    miaotaizi
        7
    miaotaizi  
       190 天前
    有个项目 叫做 laradock 可以照着抄
    darklinden
        8
    darklinden  
       190 天前
    @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
        9
    tlerbao  
    OP
       179 天前
    @darklinden #8
    - "127.0.0.1: 3306":"3306" 这种写法在 compose 2 好像是非法的,格式不对,而且我好像没在 github 上看到 compose 3 呢哈哈
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   887 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:36 · PVG 04:36 · LAX 13:36 · JFK 16:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.