Tomasz Kapłoński
Tomasz Kapłoński

Reputation: 1378

Docker PHP MySQL connection refused

I am trying to run a site using multiple container configuration - one for apache, second for mysql and third for myadmin. Everything starts fine, setup runs smooth but when I try to run a PHP application I get mysqli::__construct(): (HY000/2002): Connection refused in system/libraries/drivers/Database/Mysqli.php [54] error.

It seems that there's something wrong with the connection settings but I checked the site through PHP MyAdmin running on separate container and copied the db host IP from there just to be sure. How can I/should I connect from PHP container to MySQL db?

Here's my docker-compose.yml file:

version: '3'
services:
  web:
    build:
      context: ./etc/php
      args:
         - APP_HOST=${APP_HOST}
         - MYSQL_USER=${MYSQL_USER}
         - MYSQL_PASSWORD=${MYSQL_PASSWORD}
         - MYSQL_PORT=${MYSQL_PORT}
         - MYSQL_DATABASE=${MYSQL_DATABASE}
    ports:
      - ${APP_PORT}:80
      - ${APP_PORT_SSL}:443
    volumes:
      - ./var/bin/:/tmp/bin/
      - ./app/:/var/www/html/
      - ./log/apache2/:/var/log/apache2/
      - ./etc/php/conf/:/usr/local/etc/php/conf.d/
    environment:
      - VIRTUAL_HOST=${VIRTUAL_HOST}
  db:
    build:
      context: ./etc/mysql
      args:
        - MYSQL_DATABASE=${MYSQL_DATABASE}
        - MYSQL_USER=${MYSQL_USER}
        - MYSQL_PASSWORD=${MYSQL_PASSWORD}
        - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
        - DUMP_FILE=${DUMP_FILE}
    volumes:
      - ./etc/mysql/conf:/etc/mysql/conf/conf.d
      - ./data:/var/lib/mysql
      - ./log/:/var/log/
    ports:
      - "${MYSQL_PORT}:3306"
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      MYSQL_ROOT_PASSWORD: root
    ports:
      - ${MYADMIN_PORT}:80
    environment:
      - VIRTUAL_HOST=phpmyadmin.localhost

And the .env with variables:

VIRTUAL_HOST=foo.local

APP_PORT=80
APP_PORT_SSL=443
MYADMIN_PORT=8081

APP_HOST=foo.local
ADMIN_APP_HOST=admin-foo.local

MYSQL_DATABASE=foo_local
MYSQL_USER=root
MYSQL_HOST=172.26.0.2
MYSQL_PASSWORD=root
MYSQL_ROOT_PASSWORD=root
MYSQL_PORT=3306

Oh, and here's the code I try to run:

 $this->link = $socket ? new mysqli(null, $user, $pass, $database, $port, $socket) :
new mysqli($host, $user, $pass, $database, $port);

Output of echo $host.'<br>'.$user.'<br>'.$pass.'<br>'.$database.'<br>'.$port.'<br>'.$socket; is following:

172.26.0.2
root
root
hq_local
3306

Upvotes: 9

Views: 16044

Answers (5)

jerryurenaa
jerryurenaa

Reputation: 4712

all you need to do is to specify the value of the host in mysql the official environment variable is MYSQL_ROOT_HOST: localhost if you do not do that then the host becomes the name of the service which in your case it is db.

Upvotes: 1

gdm
gdm

Reputation: 7978

Put everything in .env file and call the environment variables from there. Don´t worry about changing code if you write it as:

$mylink = mysqli_connect(
    env("DB_HOST"),
    env("DB_USER"),
    env("DB_PASS"),
    env("DB_NAME"),
    env("DB_PORT",3306)
)

Upvotes: 0

Abraham
Abraham

Reputation: 9885

You can always use host.docker.internal as IP, therefore you can use something like this:

$db = new \PDO('mysql:host=host.docker.internal;port=3306;dbname=db', 'root', 'pass');

Upvotes: 10

patilnitin
patilnitin

Reputation: 1171

Check out the /etc/hosts configuration inside your web service container for container linkage.

docker exec -it <container_name> cat /etc/hosts

Docker network won't be assigning the same IP to db container that you have specified for the MYSQL_HOST all the time. So better ti use the conatiner name in order to connect from web container.

Also, based on the context that you have specified in docker-compose.yml, try this:

new mysqli('etc/mysql', $user, $pass, $database, $port);

Upvotes: 2

Kilian
Kilian

Reputation: 1781

check your container IP with a docker inspect [container name] but write IP in a file is not very good. Replace IP by name of your db container.

Upvotes: 16

Related Questions