披露:这篇文章的每一个命令和每一条报错,都来自我自己花钱买的那台香港 VPS(1核2G,Debian 12)。文中没有推广链接。它能省事的地方我写,它坑人的地方我也写。
前提:2026 年 11 月 2 日到 3 日,一台 1核2G / 50G / 香港的机器,Debian 12(内核 6.1),宝塔面板 9.0.0 稳定版。命令按当时顺序贴,报错原样贴。这台机器本身的参数和实测数据,我写在恒创香港 VPS 的测评里,这里不重复。
一句话结论:宝塔能把你从裸机到「能打开 WordPress」的时间压缩到二十分钟,但它省的是敲命令的时间,不是该懂的东西。装完有四个默认值必须自己改,否则站会慢、会上传目录能跑 PHP、会把报错直接打给访客看——这三件事面板一件都不会提醒你。
一、装之前,先确认三件事
| 项目 | 要求 | 为什么 |
|---|---|---|
| 系统 | Debian 12 或 Ubuntu 22.04 | 别用 CentOS 7,2024-06-30 已停止维护,mirrorlist.centos.org 早就下线 |
| 内存 | 1G 能跑,2G 舒服 | 面板自己吃 100~200MB,加上 MySQL 和 PHP,1G 会频繁用 swap |
| 端口 | 面板默认 8888 | 多数机房安全组只放行 22 和 80,8888 打不开不是面板的问题 |
我买的那台机器下单页默认只给 CentOS 7.9,装之前先重装成了 Debian 12。这一步不能省——CentOS 7 上装宝塔会遇到一堆镜像失效的报错,而这些报错和宝塔本身没关系。
二、装面板:我第一次跑就撞上死循环
宝塔的官方命令是这条:
wget -O install.sh https://download.bt.cn/install/install_lts.sh
bash install.sh ed8484bec
我通过 SSH 非交互执行(stdin 接的是 /dev/null),结果脚本进入了死循环:CPU 打到 100%,/proc/pid/io 里的 syscr 每秒涨四万多。原因是安装脚本中间有一次「确认安装」的 read,读到 EOF 之后没有退出,而是继续空转。
解法是给它一个永远回车的输入源:
yes | bash install.sh ed8484bec
如果你是手动在终端里装,根本不会遇到这个问题——只有把安装脚本塞进自动化流程才会。这一点值得先说,因为很多人是在「远程执行」的场景下装它的。
第二个坑:装完面板打不开。面板默认监听 8888,云厂商安全组默认只开 22 和 80。两条路,要么去控制台放行 8888,要么走 SSH 隧道:
ssh -p 你的端口 -L 8888:127.0.0.1:8888 root@你的IP
第三个坑,也是最容易误会的一个:装完面板不等于装完环境。面板只是面板,nginx、PHP、数据库一个都没有。登录进去看到的「软件商店」里全是待安装状态。
三、装环境:面板的软件商店在 Debian 上不完全靠得住
我一开始想全用面板的脚本装,省事。命令在 /www/server/panel/install/install_soft.sh,用法是 install_soft.sh <模式> install <软件名> <版本>,模式 1 是极速安装、0 是编译安装。
nginx 1.24 和 PHP 8.2 都装成功了。但数据库卡住了:面板的 mysql.sh 只认 CentOS,里面调 rpm、读 /etc/redhat-release,在 Debian 上直接报语法错误。这不是我配置错了,是脚本没适配。
| 组件 | 我用的版本 | 怎么装 |
|---|---|---|
| nginx | 1.24 | 面板脚本 install_soft.sh 1 install nginx 1.24 |
| PHP | 8.2.35 | 面板脚本,socket 在 /tmp/php-cgi-82.sock |
| 数据库 | MariaDB 10.11.18 | 直接 apt install -y mariadb-server |
用 apt 装数据库的代价是:面板的「数据库」菜单管不到它。对我来说可以接受——我不用面板备份数据库。
装完数据库,PHP 报了一句很笼统的错:「数据库错误」。看起来像权限问题,其实不是。
真正的原因是 socket 路径对不上。Debian 的 MariaDB 监听 /run/mysqld/mysqld.sock,而宝塔编译的 PHP 默认去 /tmp/mysql.sock 找。改 /www/server/php/82/etc/php.ini 两行:
mysqli.default_socket = /run/mysqld/mysqld.sock
pdo_mysql.default_socket = /run/mysqld/mysqld.sock
然后重载 PHP-FPM。改完立刻就好了。
四、建站:有些配置面板不替你写
面板建站会生成 vhost,但如果你像我一样用命令行建、或者要手改,有两个地方必须自己确认。第一是重写规则:
location / {
try_files $uri $uri/ /index.php?$args;
}
少了这一行,WordPress 的固定链接全 404,你会在后台反复改固定链接设置,改到怀疑人生。
第二是重载方式。宝塔的 nginx 不归 systemd 管,systemctl reload nginx 会静默失败——不报错,也不生效。必须用:
/www/server/nginx/sbin/nginx -s reload
ss -lntp | grep nginx
我在这上面浪费了二十分钟:改完 vhost 截图还是旧的,以为是自己写错了,其实是 nginx 根本没重载。后来养成习惯,每次 reload 之后用 ss -lntp 看一眼端口是不是真的在听。
五、上线前必须改的四个默认值
这一节是这篇文章里最值得看的部分。下面四个值,装完都是「能用」的状态,但每一个都会在上线后咬你。
| 默认状态 | 风险 | 怎么改 |
|---|---|---|
display_errors = On |
PHP 的警告直接打在页面上,访客看得见 | 改 Off,同时开 log_errors 写日志 |
| 上传目录的 PHP 可执行 | 别人传一个 .php 上去就能跑 |
vhost 里加 deny all,且必须放在 .php$ 规则之前 |
| 只有 HTTP | 浏览器标「不安全」,登录 Cookie 明文走 | certbot 签证书 |
| WordPress 的 siteurl 是 http | 切 HTTPS 后 301 循环 | 先把 siteurl 和 home 改成 https,再开 443 |
第一个我是真踩了。某天截图发现页面上多了一行:
Warning: Trying to access array offset on value of type null in .../sidebar.php on line 51
这不是我的代码,是主题的,PHP 8 把「从 null 取下标」从静默升级成了警告,而 display_errors 又是开的,于是访客每次访问都能看到。修法有两层:代码层面加判断,配置层面把 display_errors 关掉——只修代码不关开关,哪天插件再抛一个警告,还是照样打在页面上。
第二个更隐蔽。很多人都以为「上传目录不能执行 PHP」是面板默认做好的,但那是宝塔自己的模板里有这条规则,你自己手写的 vhost 里没有:
location ~* ^/wp-content/uploads/.*.(php|phar|phtml|php[0-9])$ {
deny all;
}
location = /wp-config.php {
deny all;
}
顺序很重要:nginx 的正则 location 是先匹配者赢,这两条必须写在 location ~ .php$ 前面,否则不生效。写完记得自己传一个 test.php 上去,访问一下看是不是 403——别猜。
第三个的坑在版本细节:nginx 1.24 不支持 http2 on; 这种写法,那是 1.25.1 之后才有的。1.24 要写成 listen 443 ssl http2;。抄了新版文档的配置贴进 1.24,nginx 会直接启动失败。
六、速度:两个开关,TTFB 从 450ms 到 10ms
1核2G 的机器,默认状态下首页 TTFB 是 450ms 左右。这个数字不算慢,但也不快。我做了两步:
| 阶段 | TTFB | 做了什么 |
|---|---|---|
| 刚装完 | 0.45s | 无 |
| 开 OPcache | 0.09s | php.ini 里加 zend_extension=opcache.so |
| 加 nginx FastCGI 缓存 | 0.01s | 静态命中直接返回,不进 PHP |
OPcache 是性价比最高的一步,改两行配置,动态页面从 450ms 掉到 90ms。FastCGI 缓存更狠,但要小心两件事:
fastcgi_cache_path 必须写在 include vhost/*.conf 之前。写在后面会报 zone "名字" is unknown,因为 vhost 里的 fastcgi_cache 引用它时它还没定义。
还有,缓存必须跳过登录状态和 POST 请求,否则用户在后台点一下,页面可能返回别人的缓存。我的做法是在 php location 里加判断,同时加一个 X-FastCGI-Cache 响应头,用 curl -I 一看就知道这次是 HIT 还是 MISS。
冷水泼在这里:0.01s 是「静态命中」的理想值,不是你的访客真实感受。后台、搜索、带参数的页面都还是 90ms 那一档。这两个数字的意义是「同一台机器上你能压到多低」,不是「你的站有多快」。
七、常见报错对照表
| 现象 | 通常是 | 怎么办 |
|---|---|---|
| 502 Bad Gateway | PHP-FPM 没起,或 vhost 里的 socket 路径写错 | 看 /www/server/php/82/var/log/,再 ls 一下 socket 在不在 |
| 「数据库错误」但密码没错 | socket 路径不一致 | 见第三节,改 php.ini 两行 |
| 面板打不开 | 安全组没放行 8888 | 控制台放行,或 SSH 隧道 |
| 改了配置没变化 | 三个缓存,随便中一个 | nginx 手动 reload、OPcache 60 秒、FastCGI 缓存 10 分钟 |
| 后台改完固定链接全 404 | 少了 try_files |
补上 /index.php?$args |
| 循环重定向 | siteurl 还是 http | 先改 https 再开 443 |
| 装面板脚本卡住、CPU 100% | 非交互执行时 confirm 读到 EOF | yes | bash install.sh |
八、几个常被问到的
1核2G 跑宝塔会卡吗?
能跑,但内存会紧。面板常驻 100~200MB,MariaDB 默认配置又要几百 MB,剩下的才给 PHP。我自己这台实测可用内存 1967MB,装完面板加开 swap 之后,跑一个 WordPress 没问题;再挂 WooCommerce 或论坛就不够了。
宝塔安全吗?
面板本身没出过大的漏洞,但它把管理入口暴露在公网上,这本身就是风险。至少做三件事:改掉默认端口、面板只允许自己的 IP 访问、装完立刻关掉面板上的「一键部署」不用。
面板和网站放同一台机器,面板被攻破怎么办?
那等于整个站被接管,没有中间地带。能接受这个风险再用面板;不能接受就纯命令行,把攻击面压到只剩 SSH 和 nginx。
必须用宝塔吗?纯命令行行不行?
行,而且更可控。纯命令行的代价是装环境要两小时,出问题要自己查。宝塔的代价是黑盒——配置散在 /www/server 下面,面板升级可能覆盖你的手改。
宝塔要钱吗?
免费版够用。专业版主要是监控、防篡改这些,个人站用不上。别在面板上花钱,把钱花在备份上。
装完能直接上线吗?
不能。装完只是「能访问」,第五节的四个默认值一个都没改。把那四个改完,再补一个自动备份,才算能上线。
九、结尾
如果你只是要一台机器跑一个 WordPress,宝塔是划算的:它把装环境从两小时压到二十分钟,而且给了你一个能看懂的后台。愿意接受「黑盒 + 手改可能被覆盖」这个代价,就用它。
我的做法是把所有手改记成一张清单,面板升级后照着重放一遍。这张清单就是这篇文章的第五、第六节——四个默认值、两个加速开关。你抄走就能用。
我接受不了的底线是备份:面板的备份功能只能备到本机,机器一挂就一起没了。所以面板可以装,异地备份不能省。这一条比选哪个面板重要得多。顺带算一笔账:这台机器三年的总花费我单独算过,见VPS 三年总成本,里面也写了备份这笔钱为什么不能省。
本文所有命令都在 Debian 12 + 宝塔 9.0.0 上跑过,版本不同可能对不上。你机器上如果报的错和这里不一样,把完整报错发我,我核实后补进第七节。
发表评论