web-dev-qa-db-fra.com

En utilisant Docker, j'obtiens l'erreur: "SQLSTATE [HY000] [2002] Aucun fichier ou répertoire de ce type"

J'utilise Docker pour créer un conteneur pour tester mon application web construite sur PHP et MySQL sur mon Mac. Mon PHP application est construite en utilisant Fat-Free Framework pour MVC et routage. J'ai deux Dockerfiles, un pour MySQL et un pour PHP. J'ai utilisé les applications Docker de test avec succès, donc je crois que mes images sont installées correctement.

La partie principale de l'erreur:

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')

Remarque, si je me connecte à l'aide de 127.0.0.1 au lieu de localhost J'obtiens une erreur légèrement différente qui dit: SQLSTATE[HY000] [2002] Connection refused

Mon PHP Dockerfile:

FROM php:5.6-Apache

RUN docker-php-ext-install mysqli pdo pdo_mysql
RUN a2enmod rewrite

My Dockerfile MySQL:

FROM mysql:5.7

ENV MYSQL_ROOT_PASSWORD password
ENV MYSQL_DATABASE robohome

COPY ./schema.sql /docker-entrypoint-initdb.d/

Ma Controller.php fichier où l'erreur mentionne la ligne 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;
    }

Ceux MYSQL_* les valeurs sont extraites d'un .ini fichier:

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

Mon fichier de composition Docker:

version: '2'

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

Je gère cela en faisant docker-compose up --build -d. La sortie que je peux alors obtenir de docker ps est:

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

Si je cours au premier plan à la place, j'obtiens la sortie suivante:

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)

D'après mes recherches, j'ai essayé de me connecter en utilisant à la fois localhost et 127.0.0.1 car ils sont techniquement traités différemment. Cela pourrait également être lié à essayer de parler via des sockets au lieu de TCP. Idéalement, je voudrais une solution que je puisse faire cuire dans mes Dockerfiles, donc je n'ai pas à me soucier de me souvenir des commandes ou de la façon dont j'ai fait quelque chose.

20
roundtheworld

Comme quelqu'un l'a souligné dans les commentaires, le fichier docker-compose que vous avez fourni est très pertinent pour votre question.

La documentation pour links dans les fichiers docker-compose dit

Les conteneurs du service lié seront accessibles à un nom d'hôte identique à l'alias ou au nom du service si aucun alias n'a été spécifié.

Dans votre cas, le conteneur de base de données est nommé db, donc la résolution de l'hôte db à partir du conteneur PHP devrait vous diriger vers le conteneur MySQL. Remplacement de localhost avec db dans votre fichier de configuration devrait permettre au conteneur PHP de se connecter à MySQL.

63
R0MANARMY

php vit sur une image docker différente de mysql. donc localhost et 127.0.0.1 de php ne pointent pas vers mysql. vous devez vous connecter à l'ip de l'instance de docker mysql.

assurez-vous également que mysql écoute sur toutes les interfaces. Dans mysql.ini, vous devez mettre listen 0.0.0.0 pour écouter sur toutes les interfaces disponibles. Par défaut, il autorise uniquement les connexions depuis localhost (et le conteneur docker php est un hôte différent).

1
edlerd