Docker can't connect to mariadb with PHP

2020-07-12 03:29发布

问题:

I'm new to Docker and have been trying to figure out how I can connect to my MariaDB container with PHP with no success.

I tried to search on stackoverflow and google but couldn't find any useful info, so I am hoping you guys could help me out.

The weird thing is that when I try to connect to MariaDB with JetBrains DataGrip with localhost, mysql, root, admin I can connect to the database but not with PDO.

I really hope you could help me out, thanks for your time.

Here are the following project files:

This is my docker-compose.yml file

version: "3.1"
services:

  nginx:
    image: nginx:alpine
    container_name: nginx
    volumes:
      - ./config/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
    ports:
      - "80:80"
    links:
       - php

  php:
    image: php:7.1-fpm
    container_name: php
    links:
      - mariadb:mysql
    volumes:
      - ./public:/public
    ports:
      - "9000:9000"

  mariadb:
    image: mariadb:10.1
    container_name: database
    environment:
      MYSQL_ROOT_PASSWORD: admin
    ports:
      - "3306:3306"

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpmyadmin
    links:
      - mariadb
    ports:
      - 8183:80
    environment:
      PMA_HOST: mariadb
      PMA_USER: root
      PMA_PASSWORD: admin
      PMA_ARBITRARY: 1

My nginx.conf file:

server {
    listen 80 default;

    client_max_body_size 108M;

    access_log /var/log/nginx/application.access.log;


    root /public;
    index index.php;

    if (!-e $request_filename) {
        rewrite ^.*$ /index.php last;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PHP_VALUE "error_log=/var/log/nginx/application_php_errors.log";
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        include fastcgi_params;
    }

}

And my index.php file

<?php

    $servername = "localhost";
    $username = "root";
    $password = "admin";
    $database = "mysql";

    try {
        $conn = new PDO("sqlite:host=".$servername.";dbname=" . $database, $username, $password);
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $sql = $conn->prepare("SELECT * FROM testDB");
        $sql->execute();

        while($result = $sql->fetch(PDO::FETCH_ASSOC)){
            $result['myTestData'];
        }

    }
    catch(PDOException $e) {
        echo "Connection failed: " . $e->getMessage();
    }

?>

回答1:

This is because you are trying to reach database server with hostname localhost from your php container, which resolves to the php container itself (same with 127.0.0.1).

You should change your $servername variable to be equal to your mariadb service name in your compose file, e.g. "mariadb".

In your case every container, being in a single default network, is resolved by its service name (among other things), that's why you don't need links, which are somewhat deprecated.

Also (just in case) make sure that your db container is actually started and ready to receive connections. It takes a while to start for the first time.



回答2:

Try creating your own Dockerfile to install the mysql ext. Put it aside the docker compose yml:

FROM php:7.1-fpm

RUN docker-php-ext-install pdo pdo_mysql

docker-compose.yml:

 php:
    build: .
    container_name: php
    links:
      - mariadb:mysql
    volumes:
      - ./public:/public
    ports:
      - "9000:9000"