【问题标题】:How to access host MySQL server in a Docker container?如何访问 Docker 容器中的主机 MySQL 服务器?
【发布时间】:2019-08-14 19:27:28
【问题描述】:

我的主机上有一个 MySQL 服务器,我希望我的 docker 容器连接到它,而不是创建一个 MySQL 容器。

在我的应用程序配置文件中,我使用localhost,就像我在使用 Docker 之前所做的那样,但连接被拒绝。

我正在使用 docker-compose,这是我的.yml

version: "3.2"

services:
    php:
        build: 
            context: './dockerfiles/php/'
            args:
                PHP_VERSION: ${PHP_VERSION}
        networks:
            - backend
        volumes:
            - ${PROJECT_ROOT}/:/var/www/html/
        container_name: acadbase_php

    apache:
        build:
            context: './dockerfiles/apache/'
            args:
                APACHE_VERSION: ${APACHE_VERSION}
        depends_on:
            - php
        networks:
            - frontend
            - backend
        ports:
            - "8080:80"
        volumes:
            - ${PROJECT_ROOT}/:/var/www/html/
        container_name: acadbase_apache

networks:
    frontend:
    backend:

volumes:
    data:

我的./dockerfiles/php/Dockerfile

ARG PHP_VERSION=""
FROM php:${PHP_VERSION:+${PHP_VERSION}-}fpm-alpine

RUN apk update; \
    apk upgrade; \
    apk add libxml2-dev

RUN docker-php-ext-install mysqli soap mbstring xml pdo_mysql

我的./dockerfiles/apache/Dockerfile

ARG APACHE_VERSION=""
FROM httpd:${APACHE_VERSION:+${APACHE_VERSION}-}alpine

RUN apk update; \
    apk upgrade; \
    apk add vim;

COPY acadbase.conf /usr/local/apache2/conf/acadbase.conf
RUN echo "Include /usr/local/apache2/conf/acadbase.conf" \
    >> /usr/local/apache2/conf/httpd.conf

我的.env

PHP_VERSION=7.1
APACHE_VERSION=2.4
PROJECT_ROOT=.

【问题讨论】:

  • 您没有在 docker-compose.yaml 中从 hostport:containerport 进行任何端口映射,这使容器内的进程可以访问主机上可见的端口
  • @ScottStensland 但如果我这样做了,我应该使用什么 IP 与我的应用程序中创建的端口一起执行此连接?
  • none ...查看您当前的 apache 端口设置为“8080:80”,它只是将主机端口 8080 映射到容器端口 80 ...对您的 sql 端口执行类似操作
  • @ScottStensland 我的应用程序配置文件中有这个字符串:'mysql:host=localhost;dbname=admin'。如果我只创建一个新的端口连接“3306:3307”,我将不能使用“localhost”作为主机,因为它指向容器,而不是主机。而且我什至无法创建这样的端口,因为当我这样做时,我得到了Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already in use

标签: php mysql apache docker docker-compose


【解决方案1】:

您可以从具有域的容器连接到主机 - host.docker.internal,其中包含主机的内部 ip。

【讨论】:

  • 我得到了这个异常:PDOException: PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Name does not resolve
  • 我看到了这个话题,我已经得到了主机 IP,问题是当我使用它时,我收到了 504 超时
【解决方案2】:

正如@StrahinjaTasic 和@AvinashReddy 所说,我需要使用我的主机的IP,但它不能正常工作,只是因为我需要在我的MySQL 本地服务器上做更多的事情。

1- 我需要允许数据库用户从容器 IP(或任何地方)进行连接,而不是仅从 localhost。

# use the correct IP if it is not for local development
GRANT ALL PRIVILEGES ON *.* TO '[user]'@'%';

FLUSH PRIVILEGES;

MySQL GRANT 命令详情见:https://dev.mysql.com/doc/refman/5.7/en/grant.html

2- 我需要更改 MySQL 配置文件,让它不仅可以侦听 localhost,还可以侦听容器 IP(或任何地方)。

在我的例子中,配置文件是/etc/mysql/mysql.conf.d/mysqld.conf

# use the correct IP if it is not for local development
bind-address = 0.0.0.0

之后,我将主机的 IP 和数据库用户凭据放入我的应用程序配置文件中,它就可以工作了!

P.S.:要获取容器 IP,请参阅 How to get a Docker container's IP address from the host?

【讨论】:

    【解决方案3】:

    您正在使用主机的环回地址。而是使用网络接口的 inet(ip address)。 “eth0”应该是你的接口名称。

    【讨论】:

    • 我得到了这个异常:PDOException: PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Name does not resolve
    • 你使用的是ip还是主机名?用IP试试。容器内无法解析 DNS 名称
    • 我尝试使用从 /sbin/ip route|awk '/default/ { print $3 }' 获得的 IP,但现在我得到了 504 超时
    【解决方案4】:

    localhost 无法从容器中解析。您应该使用可以从容器访问的本地机器的 IP 地址(例如:192.168.1.10)。还有为什么您不只是将 MySQL 容器添加到您的 .yml 文件并将卷链接添加到您的本地目录以使数据保持不变。如果你愿意,我可以给你举个例子:)

    祝你好运。

    【讨论】:

    • 我无法使用本地机器的 IP 地址,它不工作。而且我知道如何在容器中使用 MySQL,但是这里我们有一个生产数据库服务器,所以我想在我的本地 docker 环境中使用我的本地 MySQL 服务器来帮助我在生产中使用只更改 IP。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-04
    • 2018-01-26
    • 2020-11-22
    • 2016-07-18
    • 2023-01-24
    相关资源
    最近更新 更多