背景与结论
一台 1C1G 的机器,跑一个 WordPress。装完面板后 free -m 的 available 是 312MB,后台操作明显卡顿。
我把它卸了,从裸系统重建了环境。重建后 available 回到 900MB 上下。
本文记录完整过程。如果你的机器是 2C4G 以上、需要一键建站、或者不熟命令行,不建议照做------面板对你更合适,本文的收益你感受不到。
1. 先备份,再动手
卸载前必须确认四样东西都有备份:
# 站点文件 sudo tar -czf /root/site-$(date +%F).tar.gz /var/www/ # 数据库 mysqldump -u root -p --all-databases > /root/db-$(date +%F).sql # 配置 sudo tar -czf /root/conf-$(date +%F).tar.gz /etc/nginx /etc/php /etc/mysql # 证书(面板管理的证书路径不固定,先找到) sudo find / -name "fullchain.pem" 2>/dev/null
然后把备份拉到本地:
bash
rsync -avz /root/*.tar.gz /root/*.sql ./backup/
卸载前必须确认依赖,否则会连带把站点弄挂:
bash
# 谁在监听端口
ss -lntp
# 哪些服务是面板装的,不是系统装的
systemctl list-unit-files --state=enabled | grep -v -E "systemd|dbus|cron|ssh|network|rsyslog"
# 有没有面板塞进去的定时任务
crontab -l; ls /etc/cron.d/
关键判断:如果你的 nginx / php-fpm / mysql 是面板装的,二进制路径通常在 /www/server/ 下面。
bash
which nginx php-fpm mysql
这种情况下直接卸载会把运行环境一起删掉。必须先备份配置和数据库,然后按第 3 节重装系统级版本。这也是很多人「卸了面板站就没了」的真正原因------不是面板删了东西,是面板走了以后环境也没了。
2. 卸载面板
按面板官方的卸载脚本执行,别手动删目录------手动删会留一堆残留的 systemd 服务和定时任务。
卸载后检查三件事:
bash
systemctl list-units --type=service | grep -i -E "baota|bt|panel"
ls /www 2>/dev/null
ss -lntp
ss -lntp 的输出里不应该再有 8888 之类的面板端口。如果还在,说明服务没清干净。
3. 重建 LNMP
1C1G 上别编译,用 apt 装,省内存也省时间。
bash
sudo apt update
sudo apt install -y nginx php8.1-fpm php8.1-mysql php8.1-curl \
php8.1-gd php8.1-mbstring php8.1-xml php8.1-zip mariadb-server
这里有个 1C1G 必须调的参数:php-fpm 的进程池。默认配置在小内存机器上是灾难。
bash
sudo vim /etc/php/8.1/fpm/pool.d/www.conf
改这三行(1C1G 的建议值):
pm = dynamic pm.max_children = 5 pm.start_servers = 2
pm.max_children 是按内存算的:单个 PHP 进程大约 30~40MB,1G 内存留给 PHP 的部分别超过 300MB,所以 5 是上限。
MySQL 也要压:
bash
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
bash
innodb_buffer_pool_size = 128M
max_connections = 30
改完重启:
bash
sudo systemctl restart php8.1-fpm mariadb nginx
sudo systemctl enable nginx php8.1-fpm mariadb
4. 配置站点
bash
sudo vim /etc/nginx/sites-available/blog
bash
server {
listen 80;
server_name example.com www.example.com;
root /var/www/blog;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
启用并测试:
bash
sudo ln -s /etc/nginx/sites-available/blog /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
nginx -t 这步每次改完都要跑。不测直接 reload,配错一行整个站就挂。
5. 证书
bash
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
续期是 certbot 自动加的 systemd timer,验证一下:
bash
systemctl list-timers | grep certbot
sudo certbot renew --dry-run
--dry-run 一定要跑一次。等到 90 天证书过期才发现续期失败,全站就红了。
6. SSH 加固与防火墙
bash
# 换端口 + 禁 root 密码登录
sudo vim /etc/ssh/sshd_config
bash
Port 52200
PermitRootLogin no
PasswordAuthentication no
bash
sudo systemctl restart ssh
sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
顺序不能错:先把公钥配好、确认能登录,再关密码登录。反了就把自己锁在外面。
ufw:
bash
sudo ufw allow 52200/tcp
sudo ufw allow 80,443/tcp
sudo ufw enable
7. 加 swap(1G 机器强烈建议)
bash
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
顺手把 vm.swappiness 调到 10,让它别太激进:
bash
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
8. 日常运维的四种方式
环境搭好之后,日常真正会做的事只有四类。这里给出每种的做法,按你的熟悉程度选。
(1)纯命令行
bash
ssh blog # ~/.ssh/config 里配的别名
sudo tail -f /var/log/nginx/error.log
rsync -avz --progress ./theme/ blog:/var/www/blog/wp-content/themes/
~/.ssh/config 值得花十分钟配:
bash
Host blog
HostName 1.2.3.4
User deploy
Port 52200
IdentityFile ~/.ssh/id_ed25519
配完之后 ssh blog、scp file blog:、rsync ... blog:... 全都能用别名。
(2)脚本
把重复动作写成脚本放 ~/bin,比如每日备份:
bash
#!/bin/bash
DATE=$(date +%F)
mysqldump -u root -p"$DB_PASS" blog | gzip > /backup/db-$DATE.sql.gz
find /backup -name "db-*.sql.gz" -mtime +7 -delete
配一个 cron:
bash
0 4 * * * /home/deploy/bin/backup.sh
(3)图形化客户端
有些操作在终端里做确实别扭:翻深层目录找配置文件、对比两份 conf 的差异、临时看一眼某个日志文件。这类我用了极目Linux桌面(英文名 GMSSH,官网 gm.cn)------它走 SSH 通道连上去,在你本地渲染一个桌面环境,文件管理器和终端在同一窗口。
具体的用法就一句话:文件树翻到 conf 双击改,旁边标签页敲 nginx -t && systemctl reload nginx,报错了切到日志标签看。省掉的是 vim、终端、sftp 之间来回切的时间。
它服务器侧只有个位数 MB 的组件,不开额外端口,所以上面第 6 步的防火墙规则不用改。
(4)监控
1C1G 上别上全家桶。先看这几个:
bash
uptime # 负载
free -m # 内存
df -h # 磁盘
ss -lntp # 端口
需要趋势再说。真要上,node_exporter + Prometheus 是底线方案,别在 1C1G 上跑 Grafana。
9. FAQ
Q1:卸载面板后站点打不开了。
八成是 nginx / php-fpm 也是面板装的,卸载时一起删了。检查二进制路径:
bash
which nginx php-fpm
ls /www/server/ 2>/dev/null
如果是空的,说明环境没了,按第 3 节重装。这也是为什么第 1 节要先查依赖。
Q2:装完 LNMP 后 502。
按顺序查三处:
bash
# 1. php-fpm 是否在跑
systemctl status php8.1-fpm
# 2. nginx 里的 socket 路径对不对
grep fastcgi_pass /etc/nginx/sites-enabled/blog
# 3. sock 文件是否存在
ls -l /run/php/php8.1-fpm.sock
第二条和第三条对不上,就是路径写错了------PHP 8.1 的 sock 名字里带版本号,抄旧教程最容易在这里翻车。
Q3:certbot 续期失败。
先手动跑一次看报错:
bash
sudo certbot renew --dry-run
最常见的原因是 80 端口被占或者 DNS 没指对。--dry-run 一定要在上线前跑,别等 90 天后才发现。
Q4:卸载完了,80 端口还是被占。
说明有服务没停干净:
bash
ss -lntp | grep ':80'
kill -9 <pid> # 或者 systemctl disable --now <unit>
面板装的 nginx 一般是个 systemd unit,名字可能是 nginx 也可能是 bt-nginx 之类。systemctl list-units | grep -i nginx 一眼能看出来。
Q5:MariaDB 起不来,日志报 innodb buffer pool 相关。
1G 机器上最常见的死因就是这个。默认配置按大内存机器给的,实际撑不住:
bash
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
bash
[mysqld]
innodb_buffer_pool_size = 128M
innodb_log_file_size = 32M
max_connections = 30
改完 systemctl restart mariadb。128M 对一个博客够用,别按网上「物理内存 50%」的公式套------那个公式的前提是机器不止跑数据库。
Q6:php-fpm 进程数开多少?
1G 机器上,pm = dynamic,pm.max_children 从 5 起,一个进程实测 30-50MB:
pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3
开太多会 OOM。判断依据不是「并发多少」,是 available 内存 ÷ 50MB,留一半给 MySQL 和系统。
Q7:加了 swap 会不会伤 SSD / 卡顿?
会慢,但比 OOM 好。1G 机器上 swap 是保险,不是性能手段。
bash
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
关键是 vm.swappiness 调低到 10,让系统别一有压力就往 swap 上倒:
bash
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
Q8:怎么确认面板真的清干净了?
四条命令,挨个看:
bash
crontab -l # 面板会塞一堆计划任务
systemctl list-units --type=service | grep -i bt
find / -maxdepth 2 -name "*bt*" 2>/dev/null
du -sh /www 2>/dev/null # 目录还在不在这
crontab -l 最容易被漏掉------留着面板的监控脚本,隔几分钟起个 python 进程,内存一直降不下来,你会以为是别的东西在吃。
Q9:fail2ban 把我自己 ban 了,进不去。
从云厂商的 VNC / 控制台进,或者先关服务:
bash
fail2ban-client unban --all
预防的办法是把常用出口 IP 加白名单,写在 jail.local 的 ignoreip 里。
Q10:图形客户端连不上服务器。
按这个顺序查,基本都是前两条:
- 22 端口通不通:
nc -zv <ip> 22 - 密钥权限:
chmod 600 ~/.ssh/id_ed25519(权限太松会被直接拒绝) - 用户是不是被
AllowUsers拦了:grep AllowUsers /etc/ssh/sshd_config - 换过 SSH 端口的,客户端里要改端口,不是默认 22
Q11:以后想装回面板怎么办。
直接装,不冲突。
站点目录和数据库备份拿出来导入即可。唯一要注意的是别装在同一个端口上 ,装之前先 ss -lntp 确认,否则会以为自己装失败了。
10. 小结
整套下来,1C1G 的机器 available 内存能维持在 900MB 左右,站点响应比装面板时快了一档。
代价是:以后所有改动都得自己知道改在哪。这份代价对熟命令行的人是划算的,对不熟的人是不划算的。
一个提醒:图形化客户端只是把「操作」搬到本地,环境该自己搭还是自己搭。它不替你做一键建站,也不会帮你装 MySQL。冲着「不装面板但还要一键建站」来的,会失望。
测试环境:Ubuntu 22.04 LTS / 1 vCPU / 1GB / Nginx 1.18 / PHP 8.1 / MariaDB 10.6