2016-10-16 2 views
5

Я использую Docker для создания контейнера для тестирования моего веб-приложения, построенного на PHP и MySQL на моем Mac. Мое приложение PHP построено с использованием Fat-Free Framework для MVC и маршрутизации. У меня есть два Dockerfiles, один для MySQL и один для PHP. Я успешно использовал тестовые приложения Docker, поэтому считаю, что мои изображения установлены правильно.Использование Docker Я получаю сообщение об ошибке: «SQLSTATE [HY000] [2002] Нет такого файла или каталога»

Основная часть ошибки:

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

Примечание, если соединение с использованием 127.0.0.1 вместо localhost я получаю немного другую ошибку, которая говорит: SQLSTATE[HY000] [2002] Connection refused

Мой 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/ 

Мой Controller.php файл, где ошибка упоминается строка 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; 
    } 

Эти MYSQL_* значения вытягивают из .ini файла:

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

Мой Docker сочинить файл:

version: '2' 

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

Я запускаю это, делая docker-compose up --build -d. Выход тогда я могу получить от docker ps является:

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 

Если я бегу на переднем плане вместо этого, я получаю следующий результат:

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 [email protected]' ignored in --skip-name-resolve mode. 
mysql_1 | 2016-10-16T20:21:18.456354Z 0 [Warning] 'proxies_priv' entry '@ [email protected]' ignored in --skip-name-resolve mode. 
mysql_1 | 2016-10-16T20:21:18.480237Z 0 [Warning] 'tables_priv' entry 'sys_config [email protected]' 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) 

Из моих исследований, я попытался подключения, используя как localhost и 127.0.0.1, поскольку они технически обрабатываются по-разному. Это также может быть связано с попыткой поговорить через сокеты вместо TCP. В идеале я хотел бы получить решение, которое я могу испечь в своих Dockerfiles, поэтому мне не нужно беспокоиться о запоминании команд или о том, как я что-то сделал.

+1

Ну, что такое mysql для прослушивания? Порт 3306 (по умолчанию для TCP) или файл сокета? – Devon

+0

Основываясь на моем комментарии выше (вам нужно прокрутить право, чтобы увидеть его) '0.0.0.0:32777-> 3306/tcp' – roundtheworld

+0

Отредактировано для включения моего файла Docker compose. – roundtheworld

ответ

24

Как указал кто-то в комментариях, предоставленный вами файл докеры очень важен для вашего вопроса.

Документация links в докеров-Compose файлов говорит

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

В вашем случае, контейнер базы данных называется db, поэтому разрешения db хоста из PHP контейнера должен указать вам на контейнере MySQL.Замена localhost с db в вашем файле конфигурации должна позволить контейнеру PHP подключаться к MySQL.

+1

Это была информация, которую я отсутствовал/не понимал; что местоположение моей базы данных должно совпадать с именем в моем файле-файле-докере. Я заработал! – roundtheworld

+1

Я также хотел добавить, что мне не нужен раздел 'links'. Моя проблема была на 100% фактом, что расположение базы данных в моем файле конфигурации было «localhost», когда оно должно было быть именем моей службы в моем yml-файле 'db'. – roundtheworld

+1

@roundtheworld Это правда, (справедливо) недавно, Docker получил поддержку базового [DNS] (https://docs.docker.com/engine/userguide/networking/default_network/configure-dns/), который позволяет контейнерам находить друг друга по имени. – R0MANARMY

1

php живет на другом изображении докеров, чем в mysql. поэтому localhost и 127.0.0.1 из php не указывают на mysql. вы должны подключиться к ip экземпляра docker mysql.

также убедитесь, что mysql прослушивает все интерфейсы. В mysql.ini вам нужно поставить listen 0.0.0.0 для прослушивания всех доступных интерфейсов. По умолчанию он разрешает соединения только с localhost (а контейнер док-станции php - другой хост).

+1

Не публикуйте, если вам это не нужно в другом месте, просто еще одна конечная точка, которую вам нужно защитить. Свяжите их вместе. https://docs.docker.com/compose/compose-file/#links – user2105103

+0

Я понимаю, что php и mysql живут в разных изображениях Docker, но для образца, который я нашел в Интернете, который я построил, я не видел ничего такого сделал это. Я смог привести этот пример к работе, который очень похож на мой: https://github.com/mikesir87/docker-compose-demo – roundtheworld

+0

Я обновил ответ. Связывание контейнеров вместе - это то, что вы хотите, а затем ссылку по имени ссылки. – user2105103

Смежные вопросы