Docker php DPO для MariaDB — Ошибка: не удалось найти драйвер

Сейчас я изучаю PDO, и мне показалось, что лучше изучать его в стеке докеров LEMP (Nginx, php-fpm, MariaDB, phpMyadmin) на моем Ubuntu 18.04LTS.

Это мой php-файл:

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

Как видите, я пытаюсь создать PDO в своем php-коде, чтобы восстановить некоторые данные из моего db. Но каждый раз, когда я получаю это сообщение в своем браузере (Firefox 69.0.2): Error : could not find driver

Я видел это сообщение здесь: "Docker не может подключиться к mariadb с помощью PHP"< /а>. Проблема была очень похожа на мою, но это не сработало для меня.

Примечание: php-fmp и Nginx отлично работают вместе. То же самое для MariaDB и phpMyAdmin.

Вот мой файл docker-compose.yml:

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

Если бы это можно было решить без создания собственных файлов Dockerfile, было бы здорово. Но если я должен, я сделаю это. Это не проблема.


person Bravo2bad    schedule 19.10.2019    source источник


Ответы (3)


docker-compose — это своего рода API для Dockerfile. Вам нужно добавить эти библиотеки (apt-get и т. д.) в Dockerfile.

Dockerfile — ваш друг!

person Coldstar    schedule 20.10.2019
comment
Как именно установка библиотек в контейнере решает проблему OP? - person Ricardo Pieper; 20.10.2019
comment
Потому что отсутствие правильной библиотеки для вашей базы данных, такой как mysqli или pdo, даст ту же ошибку. Обычно авторы контейнеров размещают эти команды в отдельном файле докеров. - person Coldstar; 20.10.2019
comment
Ах я вижу. Видимо, тогда им нужно установить драйвер mysql. Может быть, вы могли бы уточнить это в своем ответе. - person Ricardo Pieper; 21.10.2019

Находится ли ваш PHP-файл внутри контейнера Docker или он работает вне Docker на хост-компьютере?

Если он работает внутри док-контейнера, в какой службе он находится? Обратите внимание, что служба nginx не имеет конфигурации «ссылки», что означает, что она обращается к базе данных только через имя хоста «база данных». Также проверьте порт (в конце этого поста).

Если ваш PHP-файл работает вне, вам нужно использовать localhost вместо mysql в строке подключения, например: 'mysql:host=localhost;dbname=mysql;charset=utf8'. Это потому, что внутренний DNS докера именно такой: внутренний. Вы не можете получить доступ к этому имени хоста (базе данных или mysql) за пределами докера.

Не менее важно, что в вашей строке подключения не указан порт, который в вашем случае равен 7052. Поскольку вы перенаправляете с 7052 на 3306, я думаю, что 3306 является портом mysql по умолчанию, и драйвер предполагает 3306, если вы его не укажете. Всегда полезно четко указывать хосты и порты. Проверьте документацию по строкам подключения к базе данных PHP (поскольку я ничего не знаю о php). Вероятно, это ...;port=7052 или что-то в этом роде.

Кроме того, прочитайте docker-compose links, который вы используете. Сейчас он устарел, поэтому я советую не использовать его в будущих проектах, я даже советую потратить некоторое время на его удаление. Должно пройти от 30 секунд до 5 минут, если все пойдет хорошо, и это больше не будет вас преследовать.

person Ricardo Pieper    schedule 20.10.2019

А нашел решение.

Прежде всего, хост должен быть mysql, а не имя моего контейнера (то есть database):

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

Внутри контейнера phpfpm (доступного через команду docker-compose run --rm <container-name> bash) мне пришлось включить строку extension=php_pdo_msql в моем файле конфигурации php.ini, удалив точку с запятой в начале ее строки.

Чтобы не делать это вручную каждый раз после docker-compose up, я заменил сервис phpfpm в моем docker-compose.yml файле следующим Dockerfile:

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

Наконец, просто создайте образ с помощью команды docker-compose build . (замените . на путь к каталогу, содержащему файл docker-compose.yml).

Он отлично работает для меня.

person Bravo2bad    schedule 29.10.2019