ThinkPHP项目在Linux部署成功的关键是三点:public目录设为Web根、runtime目录可写、Nginx正确转发请求至index.php;同时需确保PHP≥7.4(TP6.1+)或≥8.0.0(TP8),并启用mbstring、openssl、pdo等扩展,且FPM用户对runtime有完整属主权限。

ThinkPHP项目能直接跑在Linux服务器上,但常见失败不是因为框架本身,而是public目录没设为Web根、runtime不可写、或Nginx没把请求正确转发给index.php。只要这三点对了,80%的部署问题就消失了。
确认PHP版本和必需扩展是否启用
ThinkPHP 6.1+ 要求 PHP ≥ 7.4,TP8 则强制要求 PHP ≥ 8.0.0。光看php -v输出还不够,得验证扩展是否真正加载:
-
php -m | grep -E "mbstring|openssl|pdo|pdo_mysql|curl|fileinfo"—— 缺任何一个都可能报错或功能异常 -
php --ini查看生效的php.ini路径,编辑它确保extension=mbstring等行前面没有分号 - 如果用Ubuntu且PHP是ppa源安装的,注意
php8.1-fpm和php8.1-cli配置文件可能不同,Nginx走的是FPM,所以重点改/etc/php/8.1/fpm/php.ini
Nginx配置必须指向public目录并重写URL
错误做法是把整个项目根目录(含app、config)设为root,这会导致敏感文件被直接访问。正确做法是只暴露public子目录,并让所有非静态资源请求都落到index.php:
-
root必须设为/var/www/your-project/public,不是/var/www/your-project - 推荐用
try_files替代if (!-e $request_filename):Nginx官方明确说if在location块中行为不可靠 -
fastcgi_param SCRIPT_FILENAME值要用$realpath_root而非$document_root,否则软链接目录下会报“No input file specified”
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
权限、缓存和环境变量三个关键动作不能跳
部署后页面空白或500,大概率卡在这三步:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
立即学习“PHP免费学习笔记(深入)”;
-
chmod -R 755 runtime/—— ThinkPHP运行时日志、缓存、模板编译全存在这里,www-data用户必须有写权限;chmod -R 755 public/static/如果用了静态资源自动构建 -
composer install --optimize-autoloader --no-dev—— 生产环境不要装phpunit、symfony/var-dumper这些开发依赖,也别留.env.example或README.md在上线目录里 -
.env文件必须存在且权限为644,内容里APP_DEBUG=false和数据库配置要准确;如果用config/app.php硬编码,记得删掉debug相关逻辑,否则app_debug设为false也可能被覆盖
最容易被忽略的细节:runtime目录结构和FPM用户匹配
ThinkPHP启动时会尝试创建runtime/log、runtime/cache等子目录,但如果父目录runtime本身是root创建、权限设成755,而PHP-FPM是以www-data身份运行,就会因无法创建子目录导致白屏——此时nginx error.log里通常只有FastCGI sent in stderr: "Primary script unknown"这种误导性错误。
解决方法不是盲目加777,而是先查FPM用户:ps aux | grep php-fpm 看worker进程属主,再执行:sudo chown -R www-data:www-data runtime/。另外,首次访问前手动mkdir -p runtime/{log,cache,view,session}并touch runtime/.gitignore,能避开很多权限衍生问题。


















