无法使用 PHP PDO 连接到本地 MariaDB 运行 Docker
Can't connect to local MariaDB running with Docker with PHP PDO
我的机器上有一个本地 Docker 组合堆栈,其中包含 MariaDB、PHP-FPM 和 Nginx 运行,用于本地开发。
我可以在我的浏览器上成功访问 http://localhost:8080/ 上 Nginx 服务的网页。
我还可以在主机 127.0.0.1、端口 8889 上使用本地 GUI 数据库浏览器 TablePlus 成功连接到数据库。它适用于用户 root
和密码 root
(但很奇怪,不能与任何其他用户设置为 MYSQL_USER、MYSQL_PASSWORD env 变量我在 Docker compose 中捕获)。
无论如何,当我尝试使用以下 PHP 代码连接 PHP/PDO 时,相同的凭据:
$db = new PDO('mysql:host=localhost;port=8889;dbname=words', 'root', 'root');
...我得到 Error: SQLSTATE[HY000] [2002] No such file or directory
编辑:当我使用时:
$db = new PDO('mysql:host=127.0.0.1;port=8889;dbname=words', 'root', 'root');
...我得到 Error: SQLSTATE[HY000] [2002] Connection refused
为什么?
(这是我的 Docker 撰写文件:
version: "3"
services:
mariadb:
image: mariadb:10.5
container_name: mariadb-10.5
restart: unless-stopped
ports:
# port 3306 is the default port for mariadb, forwarded to 8889 on the local machine
- 8889:3306
volumes:
- ./mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
php-fpm:
image: bitnami/php-fpm:7.4
container_name: phpfpm-7.4
restart: unless-stopped
ports:
- 9000:9000
volumes:
- ${WWW_DOCUMENT_ROOT}:/app
nginx:
image: bitnami/nginx:1.20
container_name: nginx-1.20
restart: always
ports:
- 8080:8080
volumes:
- ./nginx/logs:/opt/bitnami/nginx/logs/
- ./nginx/server-blocks/default.conf:/opt/bitnami/nginx/conf/server_blocks/default.conf:ro
- ${WWW_DOCUMENT_ROOT}:/app
depends_on:
- mariadb
- php-fpm
)
正如 @danblack 的回答,因为与数据库的连接是从一个 Docker 容器内部连接到另一个容器:
容器之间的连接始终使用未重新映射的端口。因此与数据库容器的连接需要使用内部的 MariaDB 标准端口 3306 - 而不是重新映射的公开的 8889 端口。
数据库的主机名必须是数据库容器名称(在本例中,
MariaDB 容器名称 mariadb-10.5
),而不是 127.0.0.1
或 localhost
.
总而言之,PHP/PDO 连接对象变为:
$db = new PDO('mysql:host=mariadb-10.5;dbname=words', 'root', 'root');
我的机器上有一个本地 Docker 组合堆栈,其中包含 MariaDB、PHP-FPM 和 Nginx 运行,用于本地开发。
我可以在我的浏览器上成功访问 http://localhost:8080/ 上 Nginx 服务的网页。
我还可以在主机 127.0.0.1、端口 8889 上使用本地 GUI 数据库浏览器 TablePlus 成功连接到数据库。它适用于用户 root
和密码 root
(但很奇怪,不能与任何其他用户设置为 MYSQL_USER、MYSQL_PASSWORD env 变量我在 Docker compose 中捕获)。
无论如何,当我尝试使用以下 PHP 代码连接 PHP/PDO 时,相同的凭据:
$db = new PDO('mysql:host=localhost;port=8889;dbname=words', 'root', 'root');
...我得到 Error: SQLSTATE[HY000] [2002] No such file or directory
编辑:当我使用时:
$db = new PDO('mysql:host=127.0.0.1;port=8889;dbname=words', 'root', 'root');
...我得到 Error: SQLSTATE[HY000] [2002] Connection refused
为什么?
(这是我的 Docker 撰写文件:
version: "3"
services:
mariadb:
image: mariadb:10.5
container_name: mariadb-10.5
restart: unless-stopped
ports:
# port 3306 is the default port for mariadb, forwarded to 8889 on the local machine
- 8889:3306
volumes:
- ./mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
php-fpm:
image: bitnami/php-fpm:7.4
container_name: phpfpm-7.4
restart: unless-stopped
ports:
- 9000:9000
volumes:
- ${WWW_DOCUMENT_ROOT}:/app
nginx:
image: bitnami/nginx:1.20
container_name: nginx-1.20
restart: always
ports:
- 8080:8080
volumes:
- ./nginx/logs:/opt/bitnami/nginx/logs/
- ./nginx/server-blocks/default.conf:/opt/bitnami/nginx/conf/server_blocks/default.conf:ro
- ${WWW_DOCUMENT_ROOT}:/app
depends_on:
- mariadb
- php-fpm
)
正如 @danblack 的回答,因为与数据库的连接是从一个 Docker 容器内部连接到另一个容器:
容器之间的连接始终使用未重新映射的端口。因此与数据库容器的连接需要使用内部的 MariaDB 标准端口 3306 - 而不是重新映射的公开的 8889 端口。
数据库的主机名必须是数据库容器名称(在本例中, MariaDB 容器名称
mariadb-10.5
),而不是127.0.0.1
或localhost
.
总而言之,PHP/PDO 连接对象变为:
$db = new PDO('mysql:host=mariadb-10.5;dbname=words', 'root', 'root');