phpMyAdmin报“tmp directory is not writable”真因是PHP的is_writable()返回false,需验证:php -r "var_dump(is_writable('/tmp'));",再检查挂载选项、SELinux上下文或容器用户映射是否阻断写入。
phpMyAdmin报“tmp directory is not writable”怎么确认真因
不是配置写错了,也不是chmod 777没用——而是is_writable()在php层面返回false。这个函数不只看文件权限,还受挂载选项(如noexec)、selinux上下文、容器卷挂载方式影响。直接运行:
php -r "var_dump(is_writable('/tmp'));",如果输出bool(false),说明问题不在phpmyadmin配置,而在系统层。
$cfg['TempDir']必须设成绝对路径且属主匹配PHP进程用户
LNMP里PHP常以www-data(Debian/Ubuntu)或nginx(CentOS/RHEL)身份运行,不是root,也不是apache。错误做法是把$cfg['TempDir']设成./tmp或/tmp——前者被忽略,后者可能被SELinux或noexec拦截。
- 先查PHP进程用户:
ps aux | grep php-fpm或看phpinfo()里的User/Group - 建真实可用目录:
sudo mkdir -p /var/lib/phpmyadmin/tmp - 赋权必须对准PHP用户:
sudo chown www-data:www-data /var/lib/phpmyadmin/tmp(Ubuntu)或sudo chown nginx:nginx /var/lib/phpmyadmin/tmp(CentOS) - 在
config.inc.php里加:$cfg['TempDir'] = '/var/lib/phpmyadmin/tmp';(结尾别加斜杠)
SELinux环境下/tmp或自定义TempDir被拒的修复要点
LNMP跑在RHEL/CentOS上时,即使chown和chmod都对了,error_log里仍见Permission denied,八成是SELinux拦路。它认的是安全上下文,不是传统权限。
- 查拒绝记录:
ausearch -m avc -ts recent | grep httpd_t,看是否涉及tmp_t或mysqld_socket - 放行MySQL连接:
setsebool -P httpd_can_connect_mysql 1(Unix socket场景) - 修正目录上下文:
semanage fcontext -a -t httpd_tmp_t "/var/lib/phpmyadmin/tmp(/.*)?",再restorecon -Rv /var/lib/phpmyadmin/tmp - 别用
chcon硬改——重启或restorecon会覆盖;必须用semanage fcontext注册永久规则
Docker容器里/tmp失效的典型表现与对策
LNMP容器镜像默认没配$cfg['TempDir'],而镜像内/tmp常是tmpfs,重启即丢。phpMyAdmin启动时尝试写缓存失败,但不会报错,只默默退回到无缓存模式——页面能进,但打开大库明显卡顿。
- 容器启动时挂载持久化卷:
-v /host/path/phpmyadmin-tmp:/var/lib/phpmyadmin/tmp - 确保容器以对应用户运行:
--user www-data(或nginx),否则chown白做 - 检查挂载点是否带
noexec:mount | grep /host/path/phpmyadmin-tmp,有就换挂载点 - 验证PHP是否认可:
docker exec -it <container> php -r "var_dump(is_writable('/var/lib/phpmyadmin/tmp'));"</container>
is_writable()背后那几层抽象:文件系统挂载参数、SELinux策略、容器用户映射——它们全得对齐,缺一不可。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











