Using Docker I get the error: "SQLSTATE[HY000] [2002] No such file or directory"

58,715

Solution 1

As someone pointed out in the comments, the docker-compose file you provided is very relevant to your question.

The documentation for links in docker-compose files says

Containers for the linked service will be reachable at a hostname identical to the alias, or the service name if no alias was specified.

In your case, the database container is named db, so resolving db host from the PHP container should point you at the MySQL container. Replacing localhost with db in your config file should allow the PHP container to connect to MySQL.

Solution 2

You can use this command

docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

Containers will connect with each other by their ip For example: My ip list is:

/nginx - 172.23.0.4

/php - 172.23.0.3

/mysql - 172.23.0.2

Put this ip-address into your config file instead of 127.0.0.1. Hope that it will help you!

Solution 3

php lives on a different docker image than mysql. thus localhost and 127.0.0.1 from php do not point to mysql. you should connect to the ip of the mysql docker instance.

also make sure mysql is listening on all interfaces. In mysql.ini you need to put listen 0.0.0.0 to listen on all available interfaces. By default it only allow connections from localhost (and the php docker container is a different host).

Solution 4

Containers for the linked service will be reachable at a hostname identical to the alias, or the service name if no alias was specified.

In your case, the database container is named db, so resolving db host from the PHP container should point you at the MySQL container. Replacing localhost with db in your config file should allow the PHP container to connect to MySQL.

Share:
58,715
roundtheworld
Author by

roundtheworld

Updated on July 26, 2022

Comments

  • roundtheworld
    roundtheworld almost 2 years

    I'm using Docker to create a container to test my web app built on PHP and MySQL on my Mac. My PHP app is built using Fat-Free Framework for MVC and routing. I have two Dockerfiles, one for MySQL and one for PHP. I've used test Docker applications successfully, so I believe my images are installed correctly.

    The main part of the error:

    Internal Server Error
    
    SQLSTATE[HY000] [2002] No such file or directory
    
    [fatfree/lib/DB/SQL.php:466] PDO->__construct('mysql:host=127.0.0.1;port=3306;dbname=robohome','root','password',array(1002=>'SET NAMES utf8;'))
    [fatfree/app/Controllers/Controller.php:24] DB\SQL->__construct('mysql:host=127.0.0.1;port=3306;dbname=robohome','root','password')
    

    Note, if I connect using 127.0.0.1 instead of localhost I get a slightly different error that says: SQLSTATE[HY000] [2002] Connection refused

    My PHP Dockerfile:

    FROM php:5.6-apache
    
    RUN docker-php-ext-install mysqli pdo pdo_mysql
    RUN a2enmod rewrite
    

    My MySQL Dockerfile:

    FROM mysql:5.7
    
    ENV MYSQL_ROOT_PASSWORD password
    ENV MYSQL_DATABASE robohome
    
    COPY ./schema.sql /docker-entrypoint-initdb.d/
    

    My Controller.php file where the error mentions line 24:

    <?php
    
    namespace Controllers;
    
    class Controller
    {
        protected $f3;
        protected $db;
    
        public function __construct()
        {
            $f3 = \Base::instance();
            $this->f3 = $f3;
    
            $mysqlServerName = $f3->get("MYSQL_SERVERNAME");
            $mysqlDatabseName = $f3->get("MYSQL_DBNAME");
    
            //$container = \DI\ContainerBuilder::buildDevContainer(); <-Not used currently
    
            //Below is line 24 referred to in the error
            $db = new \DB\SQL(
                "mysql:host={$mysqlServerName};port=3306;dbname={$mysqlDatabseName}",
                $f3->get("MYSQL_USERNAME"),
                $f3->get("MYSQL_PASSWORD")
            );
    
            $this->db = $db;
        }
    

    Those MYSQL_* values are pulled from an .ini file:

    MYSQL_SERVERNAME = "localhost" <-This is what I've tried changing to 127.0.0.1
    MYSQL_USERNAME = "root"
    MYSQL_PASSWORD = "password"
    MYSQL_DBNAME = "robohome"
    

    My Docker compose file:

    version: '2'
    
    services:
      web:
        build: ./docker/php
        ports:
          - 80:80
        volumes:
          - .:/var/www/html/
        links:
          - db
      db:
        build: ./docker/mysql
        ports:
          - 3306
    

    I run this by doing docker-compose up --build -d. The output I can then get from docker ps is:

    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
    f35066a16586        robohomeweb_mysql   "docker-entrypoint.sh"   3 minutes ago       Up 2 seconds        0.0.0.0:32777->3306/tcp   robohomeweb_mysql_1
    86d34eb34583        robohomeweb_php     "apache2-foreground"     3 minutes ago       Up 2 seconds        0.0.0.0:80->80/tcp        robohomeweb_php_1
    

    If I run in the foreground instead, I get the following output:

    Building php
    Step 1 : FROM php:5.6-apache
     ---> 8f9b7e57129a
    Step 2 : RUN docker-php-ext-install mysqli pdo pdo_mysql
     ---> Using cache
     ---> fadd8f9e7207
    Step 3 : RUN a2enmod rewrite
     ---> Using cache
     ---> 9dfed7fdc60f
    Successfully built 9dfed7fdc60f
    Building mysql
    Step 1 : FROM mysql:5.7
     ---> eda6a4884645
    Step 2 : ENV MYSQL_ROOT_PASSWORD password
     ---> Using cache
     ---> 759895ac5772
    Step 3 : ENV MYSQL_DATABASE robohome
     ---> Using cache
     ---> e926c5ecc088
    Step 4 : COPY ./schema.sql /docker-entrypoint-initdb.d/
     ---> Using cache
     ---> cf5d00aa8020
    Successfully built cf5d00aa8020
    Starting robohomeweb_php_1
    Starting robohomeweb_mysql_1
    Attaching to robohomeweb_mysql_1, robohomeweb_php_1
    php_1    | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message
    php_1    | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message
    php_1    | [Sun Oct 16 20:21:17.944575 2016] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.10 (Debian) PHP/5.6.26 configured -- resuming normal operations
    php_1    | [Sun Oct 16 20:21:17.946919 2016] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
    mysql_1  | 2016-10-16T20:21:18.036272Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
    mysql_1  | 2016-10-16T20:21:18.038330Z 0 [Note] mysqld (mysqld 5.7.16) starting as process 1 ...
    mysql_1  | 2016-10-16T20:21:18.043331Z 0 [Note] InnoDB: PUNCH HOLE support available
    mysql_1  | 2016-10-16T20:21:18.043603Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
    mysql_1  | 2016-10-16T20:21:18.043951Z 0 [Note] InnoDB: Uses event mutexes
    mysql_1  | 2016-10-16T20:21:18.044077Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
    mysql_1  | 2016-10-16T20:21:18.044260Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.3
    mysql_1  | 2016-10-16T20:21:18.044414Z 0 [Note] InnoDB: Using Linux native AIO
    mysql_1  | 2016-10-16T20:21:18.045150Z 0 [Note] InnoDB: Number of pools: 1
    mysql_1  | 2016-10-16T20:21:18.045620Z 0 [Note] InnoDB: Using CPU crc32 instructions
    mysql_1  | 2016-10-16T20:21:18.047629Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
    mysql_1  | 2016-10-16T20:21:18.057705Z 0 [Note] InnoDB: Completed initialization of buffer pool
    mysql_1  | 2016-10-16T20:21:18.059988Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
    mysql_1  | 2016-10-16T20:21:18.074670Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
    mysql_1  | 2016-10-16T20:21:18.101209Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
    mysql_1  | 2016-10-16T20:21:18.101433Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
    mysql_1  | 2016-10-16T20:21:18.354806Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
    mysql_1  | 2016-10-16T20:21:18.356928Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
    mysql_1  | 2016-10-16T20:21:18.357158Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
    mysql_1  | 2016-10-16T20:21:18.358049Z 0 [Note] InnoDB: Waiting for purge to start
    mysql_1  | 2016-10-16T20:21:18.412987Z 0 [Note] InnoDB: 5.7.16 started; log sequence number 12179647
    mysql_1  | 2016-10-16T20:21:18.414470Z 0 [Note] Plugin 'FEDERATED' is disabled.
    mysql_1  | 2016-10-16T20:21:18.421833Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
    mysql_1  | 2016-10-16T20:21:18.424144Z 0 [Note] InnoDB: Buffer pool(s) load completed at 161016 20:21:18
    mysql_1  | 2016-10-16T20:21:18.425607Z 0 [Warning] Failed to set up SSL because of the following SSL library error: SSL context is not usable without certificate and private key
    mysql_1  | 2016-10-16T20:21:18.427018Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
    mysql_1  | 2016-10-16T20:21:18.427581Z 0 [Note] IPv6 is available.
    mysql_1  | 2016-10-16T20:21:18.427749Z 0 [Note]   - '::' resolves to '::';
    mysql_1  | 2016-10-16T20:21:18.428019Z 0 [Note] Server socket created on IP: '::'.
    mysql_1  | 2016-10-16T20:21:18.456023Z 0 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
    mysql_1  | 2016-10-16T20:21:18.456354Z 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
    mysql_1  | 2016-10-16T20:21:18.480237Z 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
    mysql_1  | 2016-10-16T20:21:18.488758Z 0 [Note] Event Scheduler: Loaded 0 events
    mysql_1  | 2016-10-16T20:21:18.490880Z 0 [Note] mysqld: ready for connections.
    mysql_1  | Version: '5.7.16'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
    

    From my research, I've tried connecting using both localhost and 127.0.0.1 since they're technically treated differently. It could also be something related to trying to talk via sockets instead of TCP. Ideally I would like a solution that I can bake into my Dockerfiles so I don't have to worry about remembering commands or how I did something.