【问题标题】:PHP app cannot connect to docker mysql container at 127.0.0.1PHP 应用程序无法连接到 127.0.0.1 的 docker mysql 容器
【发布时间】:2020-02-15 14:19:22
【问题描述】:

Mysql 在它自己的 docker-compose.yml 中,因为我想要一个 mysql 服务器启动并运行,任何其他 php 应用程序都可以连接到它。所以我在同一个docker-compose.yml中没有php和mysql。如果我使用 mysql 容器的网关 IP 地址查找它,然后将其硬编码到 php 应用程序中,我可以从 php 应用程序连接到 mysql。 docker inspect mysql-db。但是 docker 会在每次 mysql 重新启动时更改 172... ip 地址,因此不适合开发。

我可以通过mysql -h 127.0.0.1 连接到 mysql 没问题,但是如果我尝试使用 127.0.0.1 从 php 应用程序我得到连接被拒绝。只有使用 172... 网关 IP 地址才能连接。

如何让 mysql 容器监听从主机到 127.0.0.1 的连接?

docker-compose.yml for mysql

version: "3"

services:
  mysql:
    container_name: mysql-db
    image: mysql
    build:
      dockerfile: Dockerfile
      context: ./server/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=admin
    volumes:
      - ./data/mysql:/var/lib/mysql
    ports:
      - 3306:3306

docker-compose.yml for php

version: "3"

services:
  nginx:
    container_name: nginx_myapp
    image: nginx
    build:
      dockerfile: Dockerfile
      context: ./server/nginx
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./app:/var/www/html
    networks:
      - myapp
  php:
    container_name: php_myapp
    image: php:7.3-fpm
    build:
      dockerfile: Dockerfile
      context: ./server/php-fpm
    environment:
      CI_ENV: development
    volumes:
      - ./app:/var/www/html
    networks:
      - myapp

networks:
  myapp:

【问题讨论】:

  • this 有帮助吗?
  • @segFault 我想答案可能在某处,但我在这里接受的答案是一个简单的解决方案,我认为最正确的 docker-compose 简单性。

标签: php mysql docker docker-compose


【解决方案1】:

127.0.0.1 是环回地址。它指向本地主机。在 docker 的上下文中,localhost 是容器本身。您的 php 容器上没有运行 db,因此连接永远不会成功。

您需要做的是在您的 mysql compose 文件中配置默认​​网络,以便您可以预见地控制其名称以方便以后使用(否则它将根据您的 compose 项目名称计算,如果您重命名包含文件夹,该名称可能会更改...):

重要提示:要使以下内容正常工作,您需要使用撰写文件 version >= 3.5

---
version: '3.7'
#...
networks:
  default:
    name: shared_mysql

您现在可以将 shared_mysql 网络用作来自任何其他撰写项目的 external

version: '3.7'

services:
  nginx:
    #...
    networks:
      - myapp
  php:
    #...
    networks:
      - myapp
      - database

networks:
  myapp:
  database:
    external: true
    name: shared_mysql

然后您可以使用服务名称mysql(例如mysql -h mysql -u user -p)从您的php 容器连接到mysql

参考:https://docs.docker.com/compose/networking/

【讨论】:

    【解决方案2】:

    为您提供一些解决方案

    1) 您可以使用相同的卷路径在每个文件中复制 mysql 部分,这样当您启动项目时,您将拥有相同的数据库

    project1
    version: "3.2"
    services:
      mysql:
        volumes:
          - /var/mysql:/var/lib/mysql
      php:
        build:
          context: './php/'
    
    project2
    version: "3.2"
    services:
      mysql:
        volumes:
          - /var/mysql:/var/lib/mysql
      php:
        build:
          context: './php/'
    

    2) 您可以使用 host.docker.internal 或 macos (docker.for.mac.localhost) 直接连接到您的主机更多信息在这里From inside of a Docker container, how do I connect to the localhost of the machine?

    【讨论】:

    • 我曾考虑过通向同一主机目录的卷,但接受的答案是一个简单的解决方案。关于#2的想法,我将如何传递主机IP?你能举个例子吗?这似乎也是一个很好的解决方案。
    • 您是否建议从主机共享相同的绑定挂载mysql数据目录到运行在不同容器中并同时处于活动状态的多个mysql服务器?我希望您那里没有任何关键数据(或良好的备份)。在同一个数据目录上运行不同的服务器是非常危险的,只支持几个数据库引擎,并且在几乎所有情况下都会导致数据损坏,除非您完全知道自己在做什么。有关详细信息,请参阅 dev.mysql.com/doc/refman/8.0/en/multiple-data-directories.html 中的注释(也适用于 5.6 版)。
    • @Zeitounator no in example project1 从不使用 project2(单独的项目)但相同的数据库(卷)存储运行
    • 上述问题第一句:Mysql is in it's own docker-compose.yml as I want a mysql server up and running that any other php application can connect to.
    猜你喜欢
    • 2017-04-11
    • 2019-05-24
    • 2021-04-22
    • 2019-07-27
    • 2020-03-28
    • 2020-12-23
    • 2016-04-26
    • 2016-07-22
    • 2019-07-30
    相关资源
    最近更新 更多