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?

7
  • which os you are using? mean your host os? Commented Sep 7, 2018 at 4: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" Commented Sep 7, 2018 at 4:51
  • @danblack is it better to declare the VOLUME in the Dockerfile or in the docker run...? Commented Sep 7, 2018 at 4:55
  • 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. Commented Sep 7, 2018 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. Commented Sep 7, 2018 at 13:07

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.