必须将hostname改为127.0.0.1以强制走TCP连接,避免localhost触发Unix socket导致“No such file or directory”错误;同时需授权用户如'ci_user'@'%'并清除CI4缓存。

hostname 写成 localhost 就会连不上
Linux 下 localhost 强制走 Unix socket,而 Docker 容器里根本没这个 socket 文件;Windows 或 macOS 也存在解析歧义。结果就是报错 mysqli::real_connect(): (HY000/2002): No such file or directory 或直接 Connection refused。
必须改成 127.0.0.1 —— 这个地址明确走 TCP/IP,绕过 socket 路径问题。CI3 和 CI4 都适用:
- CI3:改
application/config/database.php中的$db['default']['hostname'] = '127.0.0.1'; - CI4:改
app/Config/Database.php中的'hostname' => '127.0.0.1'
MySQL 用户没授权容器 IP 访问
Docker 容器有自己独立的网络命名空间,localhost 在容器内指自己,不是宿主机或另一个容器。所以即使你用 127.0.0.1,如果 MySQL 用户只允许 'root'@'localhost',也会报 Access denied for user 'root'@'172.18.0.2'(IP 是容器实际地址)。
进 MySQL 容器执行授权(开发环境可用 %,生产请限定具体 IP):
CREATE USER 'ci_user'@'%' IDENTIFIED BY 'strong_password'; GRANT ALL PRIVILEGES ON your_db.* TO 'ci_user'@'%'; FLUSH PRIVILEGES;
验证是否生效:SELECT User, Host FROM mysql.user WHERE User = 'ci_user';,必须看到 ci_user 对应 % 或具体容器网段 IP。
CI4 配置了 PDO 却漏写 DSN 字段
CI4 用 PDO 驱动时,'DBDriver' => 'PDO' 只是声明驱动类型,真正连接靠 'DSN' 字段。漏配或格式错,会静默失败或报泛泛的“Unable to connect”。
正确写法(注意大小写、分号、charset):
'DSN' => 'mysql:host=127.0.0.1;dbname=your_db;charset=utf8mb4',
常见错误:
-
host=localhost→ 改成host=127.0.0.1 - 少写
mysql:前缀 → 必须有 - 用单引号包住整个 DSN 却在内部用了单引号 → PHP 解析出错
- 没设
'DBDebug' => true→ 错误信息被吞掉,看不出真实原因
配置改了但缓存没清,CI4 仍读旧值
CI4 启动时会把数据库配置编译进缓存(writable/cache),改完 app/Config/Database.php 不清缓存,等于白改。现象是死活连不上,且错误提示和你刚改的配置对不上。
务必执行:
php spark cache:clear
如果用的是 Apache 或 Nginx + PHP-FPM,还要确认 Web 服务器进程没卡在旧配置里——最简单办法是重启 PHP-FPM 服务(sudo systemctl restart php-fpm)或整个 Web 服务。
真正容易被忽略的点:Docker 环境下,php spark 命令是在应用容器里执行的,不是在宿主机;如果容器没挂载代码卷或缓存目录权限不对,cache:clear 可能无声失败。先 docker exec -it your-app-container ls -l writable/cache 看目录是否存在且可写。


















