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
A found the solution.
First of all, the host must be
mysql
and not the name of my container (which isdatabase
):Inside the phpfpm container (accessible via the command
docker-compose run --rm <container-name> bash
), I had to enable theextension=php_pdo_msql
line in my config filephp.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 mydocker-compose.yml
file the followingDockerfile
:Finally, just build the image with the command
docker-compose build .
(replace the.
by the path to the directory containing thedocker-compose.yml
file).It works perfectly for me.
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!
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.