Php 使用Docker,我得到了一个错误:“quot;SQLSTATE[HY000][2002]没有此类文件或目录;
我正在使用Docker创建一个容器,在Mac上测试基于PHP和MySQL构建的web应用程序。我的PHP应用程序是使用MVC和路由的无脂肪框架构建的。我有两个DockerFile,一个用于MySQL,一个用于PHP。我已经成功地使用了测试Docker应用程序,因此我相信我的映像安装正确 错误的主要部分:Php 使用Docker,我得到了一个错误:“quot;SQLSTATE[HY000][2002]没有此类文件或目录;,php,mysql,docker,docker-compose,dockerfile,Php,Mysql,Docker,Docker Compose,Dockerfile,我正在使用Docker创建一个容器,在Mac上测试基于PHP和MySQL构建的web应用程序。我的PHP应用程序是使用MVC和路由的无脂肪框架构建的。我有两个DockerFile,一个用于MySQL,一个用于PHP。我已经成功地使用了测试Docker应用程序,因此我相信我的映像安装正确 错误的主要部分: Internal Server Error SQLSTATE[HY000] [2002] No such file or directory [fatfree/lib/DB/SQL.php:
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]连接被拒绝
我的PHP Dockerfile:
FROM php:5.6-apache
RUN docker-php-ext-install mysqli pdo pdo_mysql
RUN a2enmod rewrite
FROM mysql:5.7
ENV MYSQL_ROOT_PASSWORD password
ENV MYSQL_DATABASE robohome
COPY ./schema.sql /docker-entrypoint-initdb.d/
My MySQL Dockerfile:
FROM php:5.6-apache
RUN docker-php-ext-install mysqli pdo pdo_mysql
RUN a2enmod rewrite
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;
}
我的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 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)
根据我的研究,我尝试使用
localhost
和127.0.0.1
进行连接,因为它们在技术上是不同的。它也可能与尝试通过套接字而不是TCP进行对话有关。理想情况下,我希望有一个解决方案可以嵌入docker文件,这样我就不必担心如何记住命令或如何做某事。php使用的docker映像与mysql不同。因此,php中的localhost和127.0.0.1并不指向mysql。您应该连接到mysql docker实例的ip
还要确保mysql正在监听所有接口。在mysql.ini中,您需要将listen0.0.0.0放在所有可用接口上进行监听。默认情况下,它只允许从localhost(php docker容器是另一个主机)进行连接。正如有人在评论中指出的,您提供的docker compose文件与您的问题非常相关 docker compose文件中的文档说明 链接服务的容器将可在与别名相同的主机名处访问,如果未指定别名,则可在与服务名称相同的主机名处访问
在您的例子中,数据库容器名为
db
,因此从PHP容器解析db
主机应该指向MySQL容器。在配置文件中将localhost
替换为db
,应该允许PHP容器连接到MySQL。您可以使用此命令
docker inspect-f'{{.Name}-{range.NetworkSettings.Networks}{{.IPAddress}}{{end}}}$(docker ps-aq)
容器将通过其ip相互连接
例如:
我的ip列表是:
/nginx-172.23.0.4
/php-172.23.0.3
/mysql-172.23.0.2
将此ip地址放入配置文件,而不是127.0.0.1。希望它能帮助你 那么,mysql设置为监听什么?端口3306(TCP的默认设置)或套接字文件?根据我上面的评论(您必须向右滚动才能看到)
0.0.0.0:32777->3306/TCP
编辑以包含我的Docker compose文件。除非您需要它,否则不要发布,只需保护另一个端点。把它们联系在一起。我知道php和mysql生活在不同的Docker映像中,但对于我在网上找到的基于它们构建的示例,我没有看到任何这样做的东西。我能够让这个例子工作,这与我的非常相似:我更新了响应。将容器链接在一起是您想要的,然后按链接名称引用。此外,docker compose文件与您的问题比提供的几乎所有其他文件都更相关;)但是,这就是你想把它们都旋转起来并连接起来的地方。是的,我和Docker只玩了大约一个星期,所以我非常缺乏经验。如果我在我的.yml
文件中正确理解了您的评论,我在最后添加了链接:-mysql
,但它没有起作用。我也尝试将php链接到mysql,结果相同。我认为没有必要将.yml文件中的内容链接起来。这是我丢失/不理解的信息;数据库的位置需要与docker compose文件中的名称匹配。我让它工作了!我还想补充一点,我不需要链接
部分。我的问题是,数据库在我的配置文件中的位置是localhost
,而在我的yml文件db
@roundtheworld中它应该是我的服务名称,这是事实,(相当)最近,Docker获得了对basic的支持,允许容器通过名称相互查找;dbname=yourdb',to'dsn'=>'mysql:host=db;dbname=yourdb',现在不推荐使用链接,而是使用用户定义的网络。