0

I am trying to spin up a container to run a legacy webapp that needs php5.3. I want the container to access the mysql server on the host (i.e., the computer hosting the docker container). The mysql server is confirmed up and running, and I can log into it from the host computer.

My Dockerfile looks like this:

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.

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. However, the container cannot connect to the mysql server on the host. The php command echo mysql_error() tells me 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).

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?

reynoldsnlp
  • 1,072
  • 1
  • 18
  • 45
  • which os you are using? mean your host os? – Adiii Sep 07 '18 at 04:27
  • 2
    `localhost` is the unix socket within the container. To use the socket on the host you'd need `-v /var/run/mysqld:/var/run/mysqld` to map the socket on host into the container. Alternately use TCP by specifying 127.0.0.1 as the host for you application along with `--net="host"` – danblack Sep 07 '18 at 04:51
  • @danblack is it better to declare the VOLUME in the `Dockerfile` or in the `docker run...`? – reynoldsnlp Sep 07 '18 at 04:55
  • You'd probably need both. Being explicit in the `Dockerfile` shows you're explicitly intending this to happen. – danblack Sep 07 '18 at 04:57
  • Possible duplicate of [From inside of a Docker container, how do I connect to the localhost of the machine?](https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach) – David Maze Sep 07 '18 at 09:54
  • 1
    @DavidMaze I saw that question, but the answer lacks details about my socket problem. danblack's comment above solved the problem. I wish it were an answer so I could accept it. – reynoldsnlp Sep 07 '18 at 13:05
  • 1
    MySQL has some broken behavior around `localhost`: even though it's a valid DNS name, if you request a network connection to `localhost` it will try to make a Unix socket connection instead. But (as the linked question suggests) you don't want `localhost` here in any case. – David Maze Sep 07 '18 at 13:07

2 Answers2

1

localhost is the unix socket within the container and not a tcp connection to the localhost IP address. 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. You'll also need VOLUME /var/run/mysqld in the Dockerfile.

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.

danblack
  • 12,130
  • 2
  • 22
  • 41
0

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.

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

Now in Linux, it's working as you expect.

Run nginx for testing

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

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 run --name="hello-world" -d -p 8080:8080 kornkitti/express-hello-world

If you do inside nginx container

apk add curl
curl localhost:8080

A hello world response from nodejs container.

For mysql It also working...

mysql -h localhost -u root -ptest

In case of window or Mac you can add the following.

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 -h db.local.com -u root -ptest
Adiii
  • 54,482
  • 7
  • 145
  • 148