7

I wrote this docker-compose project. The docker-compose.yml looks like this:

version: '3.1'

services:
  db:
    image: mysql
    restart: always
    environment:
      - MYSQL_DATABASE=mgsv
      - MYSQL_USER=mgsv_user
      - MYSQL_PASSWORD=mgsvpass
      - MYSQL_ROOT_PASSWORD=mysql123
    volumes:
      - ./mysql:/docker-entrypoint-initdb.d

  www:
    build: ./mGSV 
    restart: always
    ports:
      - 8080:80

The index.php looks like this:

<?php
echo "Hello World!";
//mysqli_connect("localhost","my_user","my_password","my_db");
$con = mysqli_connect("localhost","mgsv_user","mgsvpass","mgsv");

// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }
  else {
     echo "done";
  }
?>

And the Dockerfile is based on a PHP container and looks like this.

FROM php:5-apache

RUN apt-get update  && apt-get install -y --no-install-recommends \
                openjdk-7-jdk \
                maven  \
        git \
        && rm -rf /var/lib/apt/lists/*

RUN docker-php-source extract \
    && docker-php-ext-install mysql mysqli pdo pdo_mysql \
    && docker-php-source delete

RUN cd /var/www/html/ && git clone https://github.com/qunfengdong/mGSV.git

# Move the folder 'mgsv' to DocumentRoot of Apache web server. By default, the DocumentRoot of Apache is /var/www/ (speak to the system administrator to know the exact DocumentRoot).
RUN cd /var/www/html/mGSV \
    && mkdir tmp \
    && chmod -R 777 tmp

RUN cd /var/www/html/mGSV && sed -i.bak "s|'gsv'|'mgsv_user'|" lib/settings.php \ 
    && sed -i.bak "s|$database_pass = ''|$database_pass = 'mgsvpass'|" lib/settings.php \
    && sed -i.bak "s|cas-qshare.cas.unt.edu|localhost|" lib/settings.php

RUN cp /var/www/html/mGSV/Arial.ttf /usr/share/fonts/truetype/

RUN cd /var/www/html/mGSV/ws \
    && tar -xzf mgsv-ws-server.tar.gz

RUN cd /var/www/html/mGSV/ws/mgsv-ws-server \ 
    && mvn package

RUN cp -f /var/www/html/mGSV/ws/mgsv-ws-server/target/ws-server-1.0RC1-jar-with-dependencies.jar /var/www/html/mGSV/ws/

RUN cd /var/www/html/mGSV/ws \ 
    && echo "mgsv_upload_url=http://localhost/mgsv" > config.properties \
    && echo "ws_publish_url=http\://localhost\:8081/MGSVService" >> config.properties \
    && java -jar ws-server-1.0RC1-jar-with-dependencies.jar &

COPY ./index.php /var/www/html/
RUN a2enmod rewrite

When using http://localhost:8080/ this is the output which I got:

Hello World!
Warning: mysqli_connect(): (HY000/2002): No such file or directory in /var/www/html/index.php on line 4
Failed to connect to MySQL: No such file or directory

What did I miss?

Thank you in advance.

2 Answers 2

8

I believe the issue here is that localhost is not your database host. If that PHP script is running in the "www" docker container, localhost most likely does not have a listening MySQL server. IIRC, the "file not found" error from mysqli is due to not finding the MySQL socket on localhost. I also do not see that you are exposing any ports for the "db" image, so I am not sure how "www" is supposed to connect to a database running inside it.

You would want to find what the address to the "db" docker container is, and what port it is listening on, then reference that in your mysqli_connect() function. An easier method, if you have a recent version of docker, would be to add your containers to the same Docker network and reference them by name.

EDIT: Docker Networking

You should read up on the networking feature in the official documentation as it is very useful. You can probably use the following docker-compose.yml (not tested):

version: '3.1'

services:
  db:
    image: mysql
    restart: always
    environment:
      - MYSQL_DATABASE=mgsv
      - MYSQL_USER=mgsv_user
      - MYSQL_PASSWORD=mgsvpass
      - MYSQL_ROOT_PASSWORD=mysql123
    volumes:
      - ./mysql:/docker-entrypoint-initdb.d
    networks:
      - web-db-net

  www:
    build: ./mGSV 
    restart: always
    ports:
      - 8080:80
    networks:
      - web-db-net

networks:
    web-db-net:

Then change your connect line to refer to the db container by name (you would also need to specify port if not using the MySQL default, 3306):

$con = mysqli_connect("db","mgsv_user","mgsvpass","mgsv");

EDIT2: fixed docker-compose.yml so that networks actually works

8
  • I'm running docker-ce 18.03. How would it be possible to add the containers to the same Docker network and reference them by name? Mar 23, 2018 at 4:16
  • I made an edit to show some docker networking Mar 23, 2018 at 18:19
  • Thank you but I got ERROR: In file './docker-compose.yml', network must be a mapping, not a string.. What did I miss? Mar 24, 2018 at 8:43
  • as I mentioned, it was not tested. I just tested it and noticed my mistake. In the networks key, put a colon (:) at the end of the network name to make it a mapping. i have edited the code in my answer to reflect what I just tested. Mar 24, 2018 at 21:58
  • Thank you, but I got again Warning: mysqli_connect(): (HY000/2002): No such file or directory in /var/www/html/index.php on line 4 Failed to connect to MySQL: No such file or directory. Any idea? Mar 24, 2018 at 23:59
1

Use 127.0.0.1 instead of localhost.

localhost has special meaning in mysqli (from MySqli Quick Start Guide - Connections):

The hostname localhost has a special meaning. It is bound to the use of Unix domain sockets. It is not possible to open a TCP/IP connection using the hostname localhost you must use 127.0.0.1 instead.

I.e. if you use localhost mysqli will try to use unix sockets instead of using TCP networking. Since the mysql server is not running locally, the unix socket file does not exist. Now the error makes sense.

1
  • This is a very useful answer for my setup, in which I do not use a docker-compose configuration. Thanks!
    – Daniel N.
    May 3, 2022 at 14:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .