折腾个人服务器这件事,我前后换过四套硬件、重装过十几次系统,硬盘挂过两回,最长的一台机器连续跑了两年多没重启。这篇就把个人服务器搭建的完整流程摊开讲:从想清楚自己要拿它干什么,到选硬件、装系统、做安全加固、打通外网访问、把服务跑起来,再到日常监控和备份恢复。内容面向的是真正准备自己动手的人——你可能是想把散落在各处的笔记、照片、代码仓库收到自己手里,也可能是想跑几个自建服务练手,或者单纯想搞明白"一台机器从裸机到能对外提供服务"中间到底有多少道工序。硬件部分我不会给你一份必须照抄的清单,而是给判断方法;命令部分都是可以直接复制去跑的,但我更想让你明白每条命令为什么要这么写,因为服务器这行的坑,八成不是因为不会敲命令,而是因为没想明白自己在干什么。
1. 先想清楚:个人服务器到底要解决什么问题
1.1 三类典型需求与对应的配置档位
很多人上来就问"我要买个什么机器",这个问题其实问反了。正确的顺序是先盘需求,再倒推配置,最后才落到具体硬件。我把这几年见过的个人服务器需求归成三类,你可以对号入座。
第一类是数据收拢型。核心诉求是把照片、文档、影音、笔记这些东西从各种托管服务里拿回来,自己存、自己管、自己备份。这类需求的特点是:读多写少、容量优先、对算力几乎没要求、对可靠性的要求极高。一台低功耗四核小主机加两块大容量机械盘就足够,钱应该花在硬盘和备份上,而不是 CPU 上。
第二类是服务托管型。你要跑一堆自建服务:代码托管、笔记同步、订阅管理、下载工具、监控面板、智能家居中枢。这类需求的特点是:内存吃紧、容器数量多、对 IO 有一定要求、需要能随时加服务。这类场景我更推荐 16GB 起步的内存和一块 NVMe 系统盘,CPU 反而不是瓶颈——绝大多数轻量服务在空闲时占用不到 1% 的算力,真正的瓶颈永远是内存和磁盘随机读写。
第三类是学习实验型。你想练虚拟化、练容器编排、练网络配置,机器本身是练手场。这类需求最看重的是"能随便折腾不心疼",所以我建议直接上二手企业级设备或者大内存的迷你主机,内存给到 32GB,因为虚拟机才是真正的内存黑洞。
注意:这三类需求经常混在一起,但一定要分出主次。我见过太多人一上来就按"全能"标准配机器,结果发现 80% 的预算花在了自己一年都用不上一次的功能上。先满足主需求,剩下的靠后期加。
1.2 预算与电费的隐性成本账
买机器的钱是一次性的,电费是持续的,这笔账很多人根本没算过。一台常年开机的小主机,电费是可以精确估算的,而且这个估算过程本身能帮你做出正确的硬件选择。
具体算法:功率取"日均功率"而不是"标称功率"。假设你的机器待机 10W、日常负载 15W、偶尔满载 30W,按一天里 20 小时待机、4 小时日常负载折算,日均功率大概在 12W 左右。一年 8760 小时,年耗电量 = 12W × 8760h ÷ 1000 = 105.1 kWh。按居民电价 0.6 元/kWh 算,一年电费约 63 元。这个数字看着不大,但如果你选了一台待机 45W 的老旧台式机改造方案,日均功率按 55W 算,年耗电 481.8 kWh,电费接近 290 元——五年下来多出来的电费够买一台新的低功耗小主机了。
所以我的判断标准很简单:整机待机功耗超过 25W 的方案,除非你有明确的算力需求(比如要跑本地推理、要跑大量虚拟机),否则直接排除。这不是环保情怀,是纯粹的账目问题。
再叠加一个很多人忽略的成本:时间成本。软路由、虚拟机、容器编排这些方案,配置复杂度差别很大,一旦出问题,排查时间可能是一整个周末。如果你只是为了存文件和跑几个服务,那就选最直白的那条路,把时间省下来干别的。
| 需求类型 | CPU 参考 | 内存 | 存储 | 待机功耗目标 | 大致预算区间 |
|---|---|---|---|---|---|
| 数据收拢型 | 低功耗四核 | 8GB | 系统盘 256GB SSD + 数据盘 2×4TB | ≤ 15W | 中等 |
| 服务托管型 | 低功耗四到八核 | 16GB | 系统盘 512GB NVMe + 数据盘 4TB | ≤ 20W | 中等偏上 |
| 学习实验型 | 八核以上 | 32GB | 系统盘 1TB NVMe + 数据盘按需 | ≤ 35W | 较高 |
2. 硬件与运行环境选型:把钱花在刀刃上
2.1 四条主流路线的横向对比
个人服务器这东西,市面上能走的路其实就那么四条,我把它们的真实体验摊开说。
第一条,低功耗迷你主机。这是目前个人场景下性价比最高的一条路。整机功耗能压到 10W 上下,体积小到可以塞进书架,噪音几乎为零,接口齐全,装系统跟装普通电脑一样简单。缺点是扩展性差,一般只有一个内存插槽或者两个、一个 M.2 加一个 2.5 寸位,想加硬盘只能靠外置。我的建议是:如果你能接受"数据盘外置或者走网络存储",这条路几乎没有对手。
第二条,老台式机改造。优点是便宜、扩展性好、配件随手可得,四个硬盘位随便插。缺点是功耗高、噪音大、体积大,而且老平台的 SATA 控制器和电源质量参差不齐,长期运行的可靠性要打问号。我第一台机器就是这条路,跑了半年,电费和风扇噪音让我彻底放弃。
第三条,ARM 开发板类方案。功耗极低、价格便宜,适合跑轻量服务。但生态是硬伤:很多容器镜像没有 ARM 版本,你需要自己编译或者找替代,数据库、转码类服务在 ARM 上的性能表现也未必理想。新手不建议从这里入门,容易把时间耗在"为什么这个镜像跑不起来"上。
第四条,二手企业级设备。算力和扩展性拉满,内存便宜到离谱,适合做虚拟化实验。代价是功耗和噪音,一台机架式设备的风扇声在卧室里是灾难级别的,必须放在不影响生活的位置。而且企业级设备的固件配置对新手不太友好,第一次开机可能要折腾半天。
我的实际建议是:新手从第一条路进,把"跑通"作为第一目标;玩明白之后再考虑第二条或第四条扩展。
2.2 存储、内存与网络的参数计算方法
选配置最怕拍脑袋,我给几个能直接算的方法。
内存怎么定。先列出你要跑的服务,每个服务的常驻内存占用估一个数,然后加上系统和容器的额外开销。经验值:轻量 Linux 系统本身占 300~500MB;每个容器化的轻量服务占 50~200MB;数据库类服务给 512MB 到 2GB;如果跑虚拟机,每台给 2GB 起步。把所有数字加起来,再乘 1.5 的余量系数。举例:系统 0.5G + 八个轻量服务按平均 150MB 算是 1.2G + 一个数据库 1G + 预留,合计约 2.7G,乘 1.5 得到 4G 出头。但实际选型时我不会只买 8G,因为文件系统的缓存机制会主动吃掉空闲内存来加速读写,内存越大,磁盘读写越少,这是纯收益。所以 16G 是当前个人服务器的甜点容量,除非你明确知道自己的负载很轻。
存储怎么分。系统盘和数据盘必须分开,这是硬性原则。系统盘用 SSD 或者 NVMe,容量 256GB 起——容器镜像、日志、数据库都会啃这块盘,塞满了系统会出各种诡异问题。数据盘单独一块,容量按你现有数据的 2 倍估,因为备份还要占一份。至于要不要做磁盘阵列:单盘加外部备份,比双盘镜像更值得做。镜像只能防单盘物理损坏,防不了误删、防不了文件系统损坏、防不了整机失窃;而外部备份这三样都能防。当然两个都做最好,但预算有限时,先做备份。
网络带宽怎么算。外网访问体验完全由家庭宽带的上行速率决定,跟下行没关系。假设你的上行是 30Mbps,换算成传输速度是 30 ÷ 8 = 3.75MB/s,理论上一分钟能传 225MB。一张 20MB 的原始照片大概 5 秒,一部 2GB 的电影要将近 10 分钟。所以如果你打算外网看视频,就得考虑转码或者降低码率,而不是指望加内存能解决。局域网内如果有 2.5G 网口,内网传输能到 280MB/s 左右,这对备份和大量文件搬运是实实在在的提升。
2.3 到手后的第一件事:硬件自检清单
新机器到手别急着装系统,先花半小时做自检,能省掉后面几天的玄学排查。
- 内存检测:跑一轮完整的内存测试,至少覆盖一遍全容量。内存问题导致的故障最难查,表现往往是随机重启、文件系统报错、编译时莫名失败。
- 硬盘检测:看健康状态和通电时间。二手盘尤其要看,通电时间超过三万小时的要谨慎,另外注意有没有重新分配扇区计数异常。
- 温度压测:跑十分钟满载,看温度曲线。低功耗小主机最常见的坑是散热设计不足,满载时固态硬盘过热降速,你会在高负载写入时突然发现速度掉到几十兆。
- 网络连通性:确认网口协商速率是千兆还是 2.5G,很多人插了 2.5G 网口却用着超五类线,实际跑千兆,白花钱。
- 断电恢复设置:进固件把"来电自动开机"打开。这个设置看起来不起眼,但停电恢复后你不在家、机器不自动起来,那是真的干着急。
提示:自检阶段就把机器的序列号、硬盘型号、购买日期记到一个文档里。后面硬盘出问题要报修、要查保修期的时候,你会感谢现在的自己。
3. 系统安装与基础安全加固
3.1 系统盘制作与首次开机配置
系统我建议直接用主流的服务器发行版,不要用桌面版改。桌面版预装了一堆用不上的服务,攻击面更大,而且图形界面在低配机器上是纯粹的负担。服务器版的安装流程这些年已经很成熟了:下载镜像,用写盘工具写入 U 盘,插上开机,跟着向导走。
写盘这一步有个细节值得说:写完一定要校验。有些写盘工具会在完成后做校验,别跳过。镜像写入不完整导致的安装失败,报错信息往往指向莫名其妙的地方,你会以为是硬件问题查半天。
首次开机配置有几件事必须一次做对:
- 分区方案:如果只有一块盘,至少分出
/、/home、/var三个独立分区,/var单独分出来是因为日志和容器数据都在这里,它涨起来不应该把根分区撑爆。给/var至少 30% 的空间。 - 主机名:起一个有意义的名字,别用默认的。后面你接监控、做备份、看日志,主机名是唯一的区分标识。
- 时区:设成本地时区,日志时间对不上会让你在排查跨服务问题时怀疑人生。
- 用户:创建一个普通用户并加入管理员组,不要图省事直接用超级用户操作所有事情。
安装完成后第一件事是更新系统。这一步不能省,安装镜像里的软件包通常落后几个月,其中可能包含已公开的安全问题。
# 更新软件包索引并升级已安装的包 sudo apt update && sudo apt full-upgrade -y # 清理不再需要的依赖 sudo apt autoremove -y3.2 SSH 密钥登录与端口策略
远程管理靠 SSH,这是整台机器对外暴露的第一个入口,也是最值得花时间加固的地方。
先说一个常见误区:改默认端口。很多人觉得把 22 端口改掉就安全了。实际上改端口只能减少自动化扫描带来的日志噪音,挡不住任何有针对性的探测——扫全端口是很基础的操作。真正的防线是这三条,按重要性排序:禁用密码登录、只允许密钥认证、限制可登录用户。
生成密钥对在本地机器上做,私钥永远不要离开你的电脑:
# 生成一对密钥,-C 后面是注释,方便你区分是哪台机器的密钥 ssh-keygen -t ed25519 -C "workstation-to-homeserver" -f ~/.ssh/homeserver_ed25519 # 把公钥推送到服务器 ssh-copy-id -i ~/.ssh/homeserver_ed25519.pub user@192.168.1.100推送成功后先别急着改配置,新开一个终端窗口测试密钥登录是否真的可用。这个习惯非常重要:改 SSH 配置前必须保证有一个已经登录成功的会话不关,新开窗口验证成功后再改,否则一旦配置写错,你就会被锁在门外,只能去接显示器和键盘。
确认密钥能登录之后,再改服务端配置:
sudo nano /etc/ssh/sshd_config需要改的几项:
PubkeyAuthentication yes PasswordAuthentication no PermitRootLogin no AllowUsers youruser MaxAuthTries 3 ClientAliveInterval 300 ClientAliveCountMax 2ClientAliveInterval这两行的作用是让闲置连接自动断开,防止你从公共网络连过之后忘了退出。改完先检查语法再重启服务:
sudo sshd -t && sudo systemctl restart sshsshd -t是配置语法检查,不通过就不会重启,这一步能救你很多次。
3.3 防火墙与自动更新
防火墙的策略应该是"默认拒绝入站、按需放行"。这条原则比任何具体规则都重要。
# 设置默认策略:入站拒绝,出站允许 sudo ufw default deny incoming sudo ufw default allow outgoing # 放行 SSH 和 Web 服务 sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp # 启用 sudo ufw enable sudo ufw status verbose这里有个顺序问题:先把 SSH 放行,再启用防火墙。反过来的话,启用瞬间你的连接就断了,而且因为连接已经建立,你可能还没意识到问题,等下次连接才发现进不去。
自动更新这块我建议至少开启安全更新的自动安装。个人服务器的运维频率远低于企业环境,你自己不可能每周去检查一遍补丁,让系统自动处理是更现实的选择:
sudo apt install unattended-upgrades -y sudo dpkg-reconfigure --priority=low unattended-upgrades配置里可以指定只自动安装安全更新,其余的手动处理,避免自动升级把某个服务搞挂。日志在/var/log/unattended-upgrades/,偶尔看一眼确认它在正常工作。
4. 网络打通:让外网安全地访问到家里
4.1 公网IP、动态域名与端口映射
服务在局域网里跑起来之后,下一个问题就是怎么在外面访问。这一步的复杂度完全取决于一件事:你家宽带有没有公网地址。
先判断。登录路由器看 WAN 口拿到的地址,如果落在 100.64.0.0/10 这一段,或者是 10、172.16、192.168 开头的私有地址,说明你处在运营商的大内网里,没有独立的公网入口。这种情况靠路由器设置是解决不了的,需要走 4.3 节的替代路线。
如果有公网地址,还要确认它是固定的还是动态的。绝大多数家庭宽带是动态的,每次重播号都可能变,所以需要动态域名解析:在域名服务商那里添加一条 A 记录,然后在家里跑一个小程序,定时检测当前公网地址,变化时自动更新记录。
# 一个极简的检测思路,把结果写进日志便于排查 curl -s https://api.example.com/ip # 换成任意返回纯文本 IP 的接口然后配置端口映射。在路由器里把外部的 443 端口映射到内网服务器的 443 端口。建议只映射必要的端口,不要开全端口映射,也不要映射管理端口。管理类服务(面板、数据库、SSH)一律只在局域网可达,需要远程用时走更安全的方式。
注意:把服务暴露到公网之前,先问自己一个问题——这个服务有没有做身份认证?很多自建服务的默认配置是"局域网免登录",一旦暴露出去就是完全敞开的状态。我踩过这个坑,一个内部工具类的服务放在公网两天,日志里就出现了大量陌生访问记录。
4.2 反向转发与 HTTPS 证书
服务多了之后,如果每个都映射一个端口,管理会变得非常混乱:你要记住一堆端口号,还得在每个服务里单独配证书。更合理的做法是用一个统一的入口服务,按域名把请求转发到不同的内部服务。
这就是反向转发的价值:对外只暴露 80 和 443 两个端口,所有服务共用一套证书,新增服务只需要加一段配置,不用动路由器。
我用得最多的组合是一个轻量 Web 服务器做入口,加上 ACME 协议自动申请和续期证书。配置大致是这样:
server { listen 443 ssl; server_name files.example.com; ssl_certificate /etc/letsencrypt/live/files.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/files.example.com/privkey.pem; client_max_body_size 20g; # 文件服务必须调大,默认值会让大文件上传失败 location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 300s; } }几个参数值得解释。client_max_body_size默认只有 1M,这是新手最常见的"为什么上传大文件报错"的元凶。proxy_read_timeout默认 60 秒,对于大文件下载、长时间请求的服务不够用,会莫名中断。X-Forwarded-*这几个头是传给后端服务的原始信息,很多服务的日志和访问控制依赖它们,漏配会导致后端看到的全是 127.0.0.1。
证书自动续期不用自己写定时任务,主流的证书工具自带续期定时器,装完就会生效。装完用一条命令做一次演练,确认续期流程真的能跑通:
sudo certbot renew --dry-run4.3 无公网IP场景的替代方案
没有公网入口的情况其实非常普遍,别灰心,可走的路有好几条。
第一条路,向运营商申请。有些地区支持申请公网地址,打客服电话说明用途即可,能不能办下来看当地情况。这条路成本最低,值得先试。
第二条路,用中转节点建立连接。家里和外部各跑一个客户端,通过中间节点把两边的连接接起来,外部访问时走中转。这条路的好处是不需要任何路由器配置,穿透性极强;代价是流量要经过中间节点,速度和延迟受中转质量影响,大文件传输体验会打折。适合管理类、轻量访问类场景。
第三条路,IPv6。现在大部分地区的宽带已经下发 IPv6 地址了,而且数量足够多,每个设备都能分到独立的地址,不需要做地址转换。如果家里和你的常用网络环境都有 IPv6,这条路是最优解:直连、速度快、不需要中转。
# 检查是否拿到了 IPv6 地址 ip -6 addr show scope global # 测试外网 IPv6 连通性 ping6 -c 4 2606:4700:4700::1111实操上要注意两点:一是路由器防火墙默认会拦截入站的 IPv6 连接,需要在防火墙里放行对应端口;二是 IPv6 地址也会变化,同样需要动态域名解析,只是记录类型从 A 换成 AAAA。另外,IPv6 环境下每台设备都是直接可达的,安全性更要靠服务本身的认证和防火墙策略,不要因为"地址难记"就认为它安全。
第四条路,只做内网访问。如果你主要是怕数据丢失而不是随时要用,那其实不需要外网访问。把服务只放在局域网,出门在外需要用时通过其他方式间接访问即可。这条路最简单也最安全,值得认真考虑——很多人的真实需求,一周也就用一两次。
5. 服务落地:从容器编排到数据备份
5.1 容器化部署的目录规划
我强烈建议所有服务都跑在容器里,原因很实际:依赖隔离、升级方便、迁移简单。裸装服务最怕的是版本冲突,A 服务要某个运行时的 1.0 版本,B 服务要 2.0 版本,最后互相打架,系统被污染得一塌糊涂。容器把这个问题彻底解决了。
容器化之前先把目录结构规划好,这个规划的寿命比任何具体服务都长:
/opt/apps/ ├── compose/ │ ├── files/ # 文件服务 │ │ └── docker-compose.yml │ ├── notes/ # 笔记服务 │ │ └── docker-compose.yml │ └── monitor/ # 监控 │ └── docker-compose.yml └── data/ ├── files/ ├── notes/ └── monitor/原则是配置和数据全部放在宿主机目录里,通过挂载进容器。绝对不要把数据存在容器内部——容器一删数据就没了,这是新手最容易犯的致命错误。另外,把不同服务的 compose 文件分目录存放,每个服务独立启停,互不干扰。
还有一个细节:给每个服务固定一个内部端口,宿主机上不给这些端口做映射,只让入口服务能访问。容器之间通过一个自定义网络通信,用服务名当主机名,这样入口服务转发时写http://files:8080就行,不依赖任何固定 IP。
# 创建自定义网络,供入口服务和各业务服务共用 docker network create app-net5.2 一个完整的 compose 示例
以一个文件服务为例,完整配置长这样:
services: files: image: your-file-service:latest container_name: files restart: unless-stopped environment: - TZ=Asia/Shanghai - PUID=1000 - PGID=1000 volumes: - /opt/apps/data/files/config:/config - /mnt/data/photos:/data/photos - /mnt/data/docs:/data/docs ports: - "127.0.0.1:8080:8080" networks: - app-net networks: app-net: external: true逐条说几个关键点。restart: unless-stopped表示除非你手动停止,否则容器挂了会自动拉起,断电恢复后服务会自动回来。PUID和PGID用来指定容器内进程的用户,配错会导致新生成的文件属主混乱,后面宿主机上操作时权限报错。端口映射写成127.0.0.1:8080:8080而不是8080:8080,意思是只监听本地回环,外网无法直连,只能通过入口服务转发进来——这一条是安全上的关键差别,很多人的服务莫名其妙被外网扫到,就是这个127.0.0.1没写。
启动和查看:
cd /opt/apps/compose/files docker compose up -d # 后台启动 docker compose logs -f --tail=100 # 看最近 100 行日志并跟踪 docker compose ps # 查看状态有一个坑必须提醒:镜像标签不要用 latest 长期跑。用 latest 意味着你哪天重启一下,可能就悄悄升了一个版本,然后配置不兼容、数据库要迁移,服务直接起不来。正确做法是首次部署验证通过后,把镜像锁定到具体的版本号,升级时再主动改,升级前先备份数据和配置。升级完发现问题,改回版本号重启就能回滚,这是容器化最大的价值之一。
5.3 备份策略:3-2-1 与恢复演练
备份这件事,最大的误区是"我配了备份,所以数据是安全的"。真正决定安全性的不是"有没有备份",而是"备份能不能恢复"。我见过配了自动备份但从来没验证过的,出事那天才发现备份文件一直是空的。
先讲策略。业界通用的 3-2-1 原则放在个人场景依然适用,只是可以简化:至少三份数据,两种不同介质,其中一份放在异地。落到具体操作上:
- 第一份:服务器上的原始数据。
- 第二份:同一台机器上的另一块硬盘,或者局域网内另一台设备。这份用来防误删——删错了能立刻找回来。
- 第三份:异地。可以是移动硬盘定期轮换带走,也可以是同步到外部存储。这份防的是火灾、失窃、整机故障这类小概率但后果严重的事件。
工具层面,系统级的全盘快照和文件级的增量同步要分开做。全盘快照用来应对"系统搞崩了想整体回滚",文件级同步用来应对"某个文件被改了想找昨天的版本"。前者我用文件系统的快照功能实现,后者用增量同步工具,配置一次,定时跑。
增量同步的关键参数是删除策略。如果不加删除选项,源端删掉的文件会永远留在备份里,备份体积无限膨胀;如果加了删除选项,一旦源端数据被误删,同步一跑备份也跟着没了。我的做法是:备份端保留带版本历史的快照,不直接镜像,这样误删之后还能从历史版本里捞回来。
最后是这一节最重要的一句话:每季度做一次恢复演练。随便挑一个文件,从备份里完整恢复一次,验证文件能打开、内容正确。这个动作花不了十分钟,但它能确保你在真正需要的时候,备份是能用的。演练记录也顺手记一下日期和结果,半年后你会想知道上次验证是什么时候。
6. 监控、排障与长期维护
6.1 资源监控与告警
服务跑起来之后,你需要知道它现在是什么状态,而不是等它挂了才发现。监控不一定要上一整套复杂系统,从简单到复杂有三层,按需选。
第一层,基础指标采集。用系统自带的工具看图就够了,关注四个指标:CPU 使用率、内存使用率、磁盘占用率、磁盘温度。前三者能提前发现资源耗尽的风险,磁盘温度能提前发现散热问题。
# 一行命令看内存和磁盘占用 free -h && df -h # 查看磁盘温度(需要智能监控工具支持) sudo smartctl -A /dev/sda | grep -i temperature # 看哪个容器最吃资源 docker stats --no-stream第二层,可视化面板。部署一套指标采集加时序存储加图表展示的组合,好处是能看到趋势。趋势比瞬时值有价值得多——内存占用过去一周从 40% 缓慢涨到 75%,这个趋势告诉你可能有内存泄漏;CPU 每天固定时间飙高,说明有个定时任务在跑。这些信息靠top是看不出来的。
第三层,告警。个人场景的告警不需要太复杂,两三个就够了:磁盘剩余空间低于 15% 报警、服务健康检查连续失败报警、机器失联报警。告警渠道用邮件或者手机通知都行。这里有个必须注意的点:告警要设阈值和静默期,否则一次网络抖动能给你推几十条消息,最后你会把告警关掉,那就彻底失去意义了。
提示:磁盘占用是个人服务器最常见的故障源。容器镜像、日志、数据库、下载缓存都会无声无息地吃空间。我给的做法是单独给
/var和容器数据目录设一个 80% 的警戒线,到了就查是谁在涨。
6.2 常见问题速查表
下面这张表是我这几年真实遇到并解决过的问题,按现象归类,方便你对照排查。
| 现象 | 最可能的原因 | 排查动作 | 解决方式 |
|---|---|---|---|
| 外网访问大文件上传失败 | 入口服务请求体大小限制 | 查入口服务配置里的体积上限 | 调大限制并重载配置 |
| 外网访问莫名中断 | 转发超时设置过短 | 看入口服务日志的 504 记录 | 调大读超时时间 |
| 服务重启后起不来 | 镜像标签漂移或配置不兼容 | 看容器日志最后 50 行 | 回退镜像版本,恢复配置备份 |
| 新写入的文件属主异常 | 容器内运行用户与宿主机不一致 | 查 compose 里的用户参数 | 改为与宿主机用户一致 |
| 磁盘突然满 | 日志或镜像缓存堆积 | 按目录看占用排行 | 限制日志大小,清理无用镜像 |
| 系统负载高但 CPU 空闲 | 磁盘 IO 阻塞 | 看 IO 等待占比 | 换盘或减少并发写入 |
| 内存持续上涨不回落 | 缓存占用或内存泄漏 | 分别看应用内存和缓存内存 | 前者重启并反馈,后者属正常 |
| 停电后无法远程 | 固件未开自动开机 | 现场确认 | 固件里开启来电自启 |
| 局域网速度只有百兆 | 网线或网口协商速率问题 | 看网口协商结果 | 换线或指定速率 |
排查有个通用思路:先分层再定位。先确认是"到不了机器"还是"到了机器但服务不对";能 ping 通但端口不通,是防火墙问题;端口通但返回 502,是入口服务到后端的转发问题;后端服务正常但数据不对,才是应用层问题。按这个顺序走,绝大多数问题几分钟内就能圈定范围。
6.3 我踩过的几个坑
第一个坑是盲目追求"全自动"。早期我给机器配了一堆自动脚本:自动更新、自动清理、自动重启。结果有一次自动清理把容器正在使用的镜像删了,服务直接挂掉。现在的做法是自动化的范围收窄到"只做安全更新",其余清理动作全部改成手动触发,并且先打印"将要删除什么"让我确认。
第二个坑是日志不设上限。一个服务出问题后疯狂刷日志,一晚上把分区写满了,连锁导致其他服务全部失败。现在我在容器层面就给所有服务设置日志轮转,单文件上限和保留数量都定死。这件事做起来只需要在 compose 里加几行配置,但能省掉一次半夜被叫起来的经历。
第三个坑是升级前不备份配置。有次一个小服务升级,新版本改了配置格式,我的旧配置被它自动"迁移"了一遍,结果某些选项丢了,虽然数据还在,但权限设置全部回退到默认。从那以后我的规矩是:升级任何服务前,先把它的配置目录整体复制一份带日期的副本,升级完对比一遍。这个习惯救过我不下三次。
第四个坑,也是最隐蔽的一个:用不靠谱的方案做时间同步。机器时间不准会导致证书校验失败、日志时间错乱、备份任务在错误的时间触发。表现是各种"看起来毫无关联"的报错。现在我在部署完系统后的第一件事就是把时间同步配好并验证,不需要复杂操作,装完等几分钟看时间是否对齐就行。
第五个坑是过度设计。我一度把家里的机器搞成了一个小型机房:多层虚拟化、复杂的网络分段、一堆自研脚本。结果是每次出问题都要花大量时间理清层次,而且这套东西只有我自己看得懂,一旦我几个月不碰,回来自己都认不出来。现在我奉行一个原则:能用一层解决就别加两层,能用一个配置文件解决就别写脚本。个人服务器的目标是长期稳定地为你服务,不是展示架构能力。
最后说一个实操上的小体会:把每一步关键操作都记下来。不用写得像文档,就是一个纯文本文件,记日期、改了什么、为什么改、怎么回滚。半年后你回想"上次那个端口映射是什么时候改的",这个文件就是唯一的答案。我现在这个文件已经写了三年,每次出问题第一件事就是翻它,命中率比我预想的高得多。