4

I have a local Docker compose stack with MariaDB, PHP-FPM and Nginx running on my machine for local development. I can successfully access the webpages served by Nginx on http://localhost:8080/ on my browser. I can also successfully connect to the database using TablePlus, a local GUI DB browser, on host 127.0.0.1, port 8889. It works with user root and password root (but weirdly enough not with any other user set as the MYSQL_USER, MYSQL_PASSWORD env variables I catch in the Docker compose).

Anyway, when I try to connect with PHP/PDO using the following PHP code, same credentials:

$db = new PDO('mysql:host=localhost;port=8889;dbname=words', 'root', 'root');

...I get Error: SQLSTATE[HY000] [2002] No such file or directory

EDIT: and when I use:

$db = new PDO('mysql:host=127.0.0.1;port=8889;dbname=words', 'root', 'root');

...I get Error: SQLSTATE[HY000] [2002] Connection refused

Why?

(Here is my Docker compose file:

version: "3"

services:

  mariadb:
    image: mariadb:10.5
    container_name: mariadb-10.5
    restart: unless-stopped
    ports:
      # port 3306 is the default port for mariadb, forwarded to 8889 on the local machine
      - 8889:3306
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}

  php-fpm:
    image: bitnami/php-fpm:7.4
    container_name: phpfpm-7.4
    restart: unless-stopped
    ports:
      - 9000:9000
    volumes:
      - ${WWW_DOCUMENT_ROOT}:/app

  nginx:
    image: bitnami/nginx:1.20
    container_name: nginx-1.20
    restart: always
    ports:
      - 8080:8080
    volumes:
      - ./nginx/logs:/opt/bitnami/nginx/logs/
      - ./nginx/server-blocks/default.conf:/opt/bitnami/nginx/conf/server_blocks/default.conf:ro
      - ${WWW_DOCUMENT_ROOT}:/app
    depends_on:
      - mariadb
      - php-fpm

)

bolino
  • 867
  • 1
  • 10
  • 27
  • 1
    When the host name is "localhost", PHP PDO uses a Unix domain socket instead of a TCP socket. Try using "127.0.0.1" instead. – Tim Roberts Feb 23 '22 at 02:39
  • Try some of these things: https://stackoverflow.com/questions/20723803/pdoexception-sqlstatehy000-2002-no-such-file-or-directory First remarks also make me think flush / restart of database might not be a bad option. – ficuscr Feb 23 '22 at 02:40
  • Sorry, forgot to say I also tried with 127.0.0.1. I edited my question. – bolino Feb 23 '22 at 02:45
  • The user credentials in the database are tied to client `user@localhost` or `user@10.%` for eg. as to differing responses. Firewall, Selinux, probably need to narrow it down more, I'm also ignorant to any Docker aspects. – ficuscr Feb 23 '22 at 02:49
  • I still don't understand why I would work with a GUI client and not PHP/PDO with same credentials. – bolino Feb 23 '22 at 02:59
  • 1
    See [this question](https://stackoverflow.com/questions/71124488/connection-refused-mariadb-in-docker), ports are ignored for connections between containers, so use 3306, and the host name is the mariadb container name `mariadb-10.5`. `MYSQL_USER` does create a `$MYSQL_USER@%` user so that will be accessible. – danblack Feb 23 '22 at 03:44
  • @danblack Well spotted! It works. I think you should post a StackOverflow answer with this – bolino Feb 23 '22 at 03:55
  • 1
    glad to help. Just too short on time to do it properly. You're welcome to do so. – danblack Feb 23 '22 at 05:19

1 Answers1

3

As answered by @danblack, since the connection to the DB is done from inside a Docker container to another container:

  1. Connections between containers always use not remapped ports. So the connection to the DB container needs to use internal, MariaDB standard port 3306 - not the remapped, exposed 8889 port.

  2. The host name of the DB must be the DB container name (in this case, the MariaDB container name mariadb-10.5), not 127.0.0.1 or localhost.

So all in all the PHP/PDO connection object becomes:

$db = new PDO('mysql:host=mariadb-10.5;dbname=words', 'root', 'root');
bolino
  • 867
  • 1
  • 10
  • 27