skip to Main Content

I’m learning PDO now and I found it better to learn it in a LEMP docker stack (Nginx, php-fpm, MariaDB, phpMyadmin) on my Ubuntu 18.04LTS.

This is my php file:

<?php
try {
  $mydb = new PDO('mysql:host=database;dbname=mysql;charset=utf8', 'root', 'admin');
} catch (Exception $e) {
  die('Error : ' . $e->getMessage());
}
?>             

As you can see, I try to make a PDO in my php code to recover some datas from my db.
But everytime I got that message on my browser (Firefox 69.0.2):
Error : could not find driver

I saw that post here: “Docker can’t connect to mariadb with PHP”. The problem was quite similar to mine but it didn’t work for me.

Note: php-fmp and Nginx work perfeclty together. Same for MariaDB and phpMyAdmin.

Here is my docker-compose.yml file:

version: "3"
services:

  nginx:
    image: tutum/nginx
    ports:
      - "7050:80"
    links:
      - phpfpm
    volumes:
      - ./nginx/default:/etc/nginx/sites-available/default
      - ./nginx/default:/etc/nginx/sites-enabled/default

      - ./logs/nginx-error.log:/var/log/nginx/error.log
      - ./logs/nginx-access.log:/var/log/nginx/access.log

  phpfpm:
    image: php:fpm
    links:
      - database:mysql
    ports:
      - "7051:9000"
    volumes:
      - ./public:/usr/share/nginx/html

  database:
    image: mariadb
    environment:
      MYSQL_ROOT_PASSWORD: admin
    ports:
      - "7052:3306"

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    restart: always
    links:
      - database:mysql
    ports:
      - "7053:80"
    environment:
      PMA_HOST: mysql
      PMA_USER: root
      PMA_PASSWORD: admin
      PMA_ARBITRARY: 1

If it is possible to solve this without building my own Dockerfiles, it would be great.
But if I must, I will. This isn’t a problem.

3

Answers


  1. Chosen as BEST ANSWER

    A found the solution.

    First of all, the host must be mysql and not the name of my container (which is database):

    $mydb = new PDO('mysql:host=mysql;dbname=mysql;charset=utf8', 'root', 'admin');
    

    Inside the phpfpm container (accessible via the command docker-compose run --rm <container-name> bash), I had to enable the extension=php_pdo_msql line in my config file php.ini by removing the semicolon at the beginning of its line.

    To avoid doing this manually every time after a docker-compose up, I replaced the phpfpm service in my docker-compose.yml file the following Dockerfile:

    FROM php:fpm
    RUN docker-php-ext-install pdo pdo_mysql
    

    Finally, just build the image with the command docker-compose build . (replace the . by the path to the directory containing the docker-compose.yml file).

    It works perfectly for me.


  2. docker-compose is an “api” of sorts for a Dockerfile. You need to add those libraries (apt-get etc…) in the Dockerfile

    Dockerfile is your friend!

    Login or Signup to reply.
  3. Is your PHP file inside a docker container or is it running outside docker, in the host machine?

    If it is running inside the docker container, which service is it in? Please note that the nginx service does not have the “links” configuration, meaning it only accesses the database through the “database” hostname. Check the port as well (in the end of this post).

    If your PHP file is running outside, then you have to use localhost instead of mysql in your connection string, like so: 'mysql:host=localhost;dbname=mysql;charset=utf8'. This is because docker’s internal DNS is just that: internal. You can’t access this hostname (database or mysql) outside docker.

    Equally important, your connection string is not specifying the port, which is 7052 in your case. Since you’re redirecting from 7052 to 3306, I think 3306 is mysql’s default port, and the driver assumes 3306 if you do not specify it. It’s always a good idea to be explicit about hosts and ports. Check the documentation on PHP databse connection strings about it (as I know nothing about php). It’s probably ...;port=7052 or something.

    Also, read up on docker-compose links, which you are using. It’s deprecated now, so I advise to not use it in future projects, I even advise to spend some time removing it. Should take like 30 seconds to 5 minutes if everything goes well, and it won’t haunt you anymore.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search