简体   繁体   English

带有apache2 / php5的Docker无法连接到主机上的mysql

[英]Docker with apache2/php5 cannot connect to mysql on host machine

I am trying to spin up a container to run a legacy webapp that needs php5.3 . 我试图启动一个容器来运行需要php5.3的旧版Webapp。 I want the container to access the mysql server on the host (ie, the computer hosting the docker container). 我希望容器访问主机(即托管Docker容器的计算机)上的mysql服务器。 The mysql server is confirmed up and running, and I can log into it from the host computer. 确认mysql服务器已启动并正在运行,我可以从主机登录到该服务器。

My Dockerfile looks like this: 我的Dockerfile看起来像这样:

FROM ubuntu:12.04

VOLUME ["/var/www"]
VOLUME ["/etc/ssl"]

RUN apt-get update && \
    apt-get install -y \
      apache2 \
      php5 \
      php5-cli \
      libapache2-mod-php5 \
      php5-gd \
      php5-ldap \
      php5-mysql \
      php5-pgsql

COPY ./apache2.conf /etc/apache2/apache2.conf
COPY ./000-default.conf /etc/apache2/sites-available/000-default.conf
COPY ./site1 /etc/apache2/sites-available/site1
COPY ./site2 /etc/apache2/sites-available/site2
COPY ./apache2-foreground.sh /var/apache2-foreground.sh

RUN a2ensite site1
RUN a2ensite site2

RUN a2enmod rewrite
RUN a2enmod ssl

EXPOSE 80
EXPOSE 443

CMD ["bash", "/var/apache2-foreground.sh"]

The apache2-foreground.sh script comes from here . apache2-foreground.sh脚本来自此处

I deploy the container using this command: 我使用以下命令部署容器:

docker run --detach \
       --name legacy-php5.3 \
       --net="host" \
       -p 80:80 \
       -p 443:443 \
       -v /etc/ssl:/etc/ssl \
       -v /var/www:/var/www \
       my/php5.3

The --net="host" argument, if I understand correctly, should make the host's localhost accessible to the container. 如果我理解正确,-- --net="host"参数应使容器可以访问主机的localhost主机。 However, the container cannot connect to the mysql server on the host. 但是,容器无法连接到主机上的mysql服务器。 The php command echo mysql_error() tells me Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) . php命令echo mysql_error()告诉我Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

If I " ssh " into the container, and run $ mysql -h localhost -u <my_user> -p , then it tells me ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) . 如果我“ ssh ”到容器中,并运行$ mysql -h localhost -u <my_user> -p ,那么它会告诉我ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

On the host computer, the socket file is there: 在主机上,套接字文件在其中:

$ ls -l /var/run/mysqld/mysqld.*
-rw-r----- 1 mysql mysql 6 Sep  6 12:16 /var/run/mysqld/mysqld.pid
srwxrwxrwx 1 mysql mysql 0 Sep  6 12:16 /var/run/mysqld/mysqld.sock
-rw------- 1 mysql mysql 6 Sep  6 12:16 /var/run/mysqld/mysqld.sock.lock

What am I doing wrong? 我究竟做错了什么?

localhost is the unix socket within the container and not a tcp connection to the localhost IP address. localhost是容器中的Unix套接字,不是到本地主机IP地址的tcp连接。 To access the unix socket on the host you'd need -v /var/run/mysqld:/var/run/mysqld to map the socket on host into the container. 要访问主机上的unix套接字,您需要-v /var/run/mysqld:/var/run/mysqld将主机上的套接字映射到容器中。 You'll also need VOLUME /var/run/mysqld in the Dockerfile . 您还需要在Dockerfile VOLUME /var/run/mysqld

Alternately use TCP by specifying 127.0.0.1 as the host for your application along with --net="host" in the docker run command line. 通过将127.0.0.1与--net="host" docker run命令行中的--net="host"一起指定为应用程序的主机来使用TCP。

Yes, you understand it correctly but before going into detail I will mention important statement about host network. 是的,您正确理解了它,但是在详细介绍之前,我将提到有关主机网络的重要声明。

The host networking driver only works on Linux hosts, and is not supported on Docker for Mac, Docker for Windows, or Docker EE for Windows Server. 主机网络驱动程序仅在Linux主机上有效,而Mac的Docker,Windows的Docker或Windows Server的Docker EE不支持该主机网络驱动程序。

https://docs.docker.com/network/network-tutorial-host/ https://docs.docker.com/network/network-tutorial-host/

Now in Linux, it's working as you expect. 现在在Linux中,它可以按预期工作。

Run nginx for testing 运行nginx进行测试

docker run --rm -it --network host --name my_nginx nginx:alpine

Goto your container... 转到您的容器...

docker exec -it my_nginx ash

If you cat /etc/hosts 如果您使用cat /etc/hosts

You will all the host file inside the container is same as the host file of the Host Machine. 容器内的所有主机文件都将与主机的主机文件相同。

Now, run the other test image, just a public image from docker registry. 现在,运行另一个测试映像,只是docker注册表中的公共映像。

docker run --name="hello-world" -d -p 8080:8080 kornkitti/express-hello-world

If you do inside nginx container 如果您在Nginx容器中进行操作

apk add curl
curl localhost:8080

A hello world response from nodejs container. 来自nodejs容器的hello world响应。

For mysql It also working... 对于mysql它也可以工作...

mysql -h localhost -u root -ptest

In case of window or Mac you can add the following. 如果是Windows或Mac,则可以添加以下内容。

docker run --rm -it --add-host=db.local.com:(host__ip_address) --name my_nginx nginx:alpine

And connect to mysql from containers like 并从类似的容器连接到mysql

mysql -h db.local.com -u root -ptest

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM