2016-10-16 18 views
5

Tôi đang sử dụng Docker để tạo vùng chứa để kiểm tra ứng dụng web của tôi được xây dựng trên PHP và MySQL trên máy Mac của tôi. Ứng dụng PHP của tôi được xây dựng bằng cách sử dụng Khung miễn phí cho MVC và định tuyến. Tôi có hai Dockerfiles, một cho MySQL và một cho PHP. Tôi đã sử dụng thành công các ứng dụng Docker thử nghiệm, vì vậy tôi tin rằng hình ảnh của tôi được cài đặt chính xác.Sử dụng Docker Tôi gặp lỗi: "SQLSTATE [HY000] [2002] Không có tập tin hoặc thư mục"

Phần chính của các lỗi:

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

Lưu ý, nếu tôi kết nối sử dụng 127.0.0.1 thay vì localhost tôi nhận được một lỗi nhẹ khác nhau mà nói: 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/ 

tập tin của tôi Controller.php lỗi ở đâu đề cập đến dòng 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; 
    } 

Những MYSQL_* giá trị được lấy ra từ một .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 soạn file:

version: '2' 

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

Tôi chạy điều này bằng cách thực hiện docker-compose up --build -d. Kết quả sau đó tôi có thể nhận được từ docker ps là:

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 

Nếu tôi chạy ở mặt trước thay vào đó, tôi nhận được kết quả như sau:

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) 

Từ nghiên cứu của tôi, tôi đã cố gắng kết nối sử dụng cả hai localhost127.0.0.1 vì chúng được xử lý kỹ thuật khác nhau. Nó cũng có thể là một cái gì đó liên quan đến cố gắng để nói chuyện qua ổ cắm thay vì TCP. Lý tưởng nhất là tôi muốn một giải pháp mà tôi có thể nướng vào Dockerfiles của tôi vì vậy tôi không phải lo lắng về việc ghi nhớ các lệnh hoặc làm thế nào tôi đã làm một cái gì đó.

+1

Vâng, mysql được thiết lập để lắng nghe điều gì? Cổng 3306 (mặc định cho TCP) hoặc tệp ổ cắm? – Devon

+0

Dựa trên nhận xét của tôi ở trên (bạn phải cuộn sang phải để xem nó) '0.0.0.0:32777-> 3306/tcp' – roundtheworld

+0

Đã chỉnh sửa để bao gồm tệp soạn thảo Docker của tôi. – roundtheworld

Trả lời

24

Như một người nào đó đã chỉ ra trong nhận xét, tệp docker-compose bạn đã cung cấp rất phù hợp với câu hỏi của bạn.

Các tài liệu cho links trong các tập tin Docker-soạn nói

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

Trong trường hợp của bạn, container cơ sở dữ liệu được đặt tên db, vì vậy giải quyết db máy chủ từ container PHP nên chỉ cho bạn tại container MySQL.Thay thế localhost bằng db trong tệp cấu hình của bạn sẽ cho phép vùng chứa PHP kết nối với MySQL.

+1

Đó là phần thông tin mà tôi đã bỏ lỡ/không hiểu; rằng vị trí của cơ sở dữ liệu của tôi cần phải khớp với tên của nó trong tập tin docker-compose của tôi. Tôi hiểu rồi! – roundtheworld

+1

Tôi cũng muốn thêm rằng tôi không cần phần 'liên kết'. Vấn đề của tôi là 100% thực tế rằng vị trí của cơ sở dữ liệu trong tệp cấu hình của tôi là 'localhost' khi nó phải là tên của dịch vụ của tôi trong tệp yml của tôi' db'. – roundtheworld

+1

@roundtheworld Đó là sự thật, (khá) gần đây, Docker đã nhận được hỗ trợ cho [DNS] cơ bản (https://docs.docker.com/engine/userguide/networking/default_network/configure-dns/) cho phép các vùng chứa tìm thấy nhau bằng tên. – R0MANARMY

1

php sống trên một hình ảnh docker khác với mysql. do đó localhost và 127.0.0.1 từ php không trỏ đến mysql. bạn nên kết nối với ip của instance mysql docker.

cũng đảm bảo rằng mysql đang nghe trên tất cả các giao diện. Trong mysql.ini, bạn cần phải đặt lắng nghe 0.0.0.0 để nghe trên tất cả các giao diện có sẵn. Theo mặc định, nó chỉ cho phép các kết nối từ localhost (và thùng chứa docker php là một host khác).

+1

Không xuất bản trừ khi bạn cần ở nơi khác, chỉ cần một điểm cuối khác mà bạn cần bảo mật. Liên kết chúng với nhau. https://docs.docker.com/compose/compose-file/#links – user2105103

+0

Tôi hiểu rằng php và mysql sống trong các hình ảnh Docker khác nhau, nhưng đối với mẫu của tôi tìm thấy trực tuyến mà tôi xây dựng, tôi không thấy bất cứ điều gì đã làm điều đó. Tôi đã có thể lấy ví dụ này để làm việc rất giống với tôi: https://github.com/mikesir87/docker-compose-demo – roundtheworld

+0

Tôi đã cập nhật phản hồi. Liên kết các thùng chứa với nhau là những gì bạn muốn, sau đó tham chiếu theo tên liên kết. – user2105103

Các vấn đề liên quan