Blog

家庭实验室起步:用旧电脑搭建第一台 Linux 服务器

家里那台 2018 年小主机——i5-8500、16G、512G SSD 再加一块 2T 机械盘——角落里吃灰两年。灰尘比跑分更显眼。我不想一夜之间把它变成「什么都能跑的神机」,只想先有一块能长期开着、能远程进去、坏了知道怎么重来的底座。后面 NAS、反代、游戏服,都得站在它上面。

云主机适合对外业务;家里这台更适合大容量和真实网络实验。试错成本主要是电费和睡眠,不是账单惊吓。下面按真实七天写,而不是「最佳实践清单」。

2 月 7 日:先算账,再拆机

常开设备,功耗比跑分重要。我拿功率计量了一下:空载约 28W,装完 Docker 后稳态大约 35–45W。按 40W 估,一天约 1 度电,一个月十几块,还能接受。同屋那台老台式机闲着就 90W 往上,长期不如换 N100 一类。

网络我决定走有线。无线当备份可以,当主力你会在 NFS 卡住的夜里后悔。内存 8G 能起步,Docker 一多我建议 16G。系统盘用 SSD,数据盘机械就行。BIOS 里把「来电自启」打开——断电恢复少跑一趟客厅。

机箱侧面贴了便签:lab-core,系统 Ubuntu,数据挂 /data,固定 IP 192.168.1.10。三个月后的自己会感谢这种笨办法。

2 月 8 日:装系统,只做能远程的底座

选 Ubuntu Server 24.04 LTS,图的是文档多、对 Docker 和 1Panel 友好。Debian 更保守,滚动发行版更折腾。第一台机,复杂度留给业务,不留给发行版。

安装时勾 OpenSSH,主机名直接写成 lab-core,时区 Asia/Shanghai。第二块盘格式化后用 UUID 写进 /etc/fstab,挂到 /data,别写可能漂移的 /dev/sdb1:

sudo timedatectl set-timezone Asia/Shanghai
lsblk -f
# UUID=xxxx-xxxx /data ext4 defaults,noatime 0 2

装完立刻做基线,别急着上 Immich:

sudo apt update && sudo apt upgrade -y
sudo apt install -y vim curl git htop tmux tree ufw fail2ban jq ca-certificates

SSH 改密钥、关掉密码。本地生成 ed25519,公钥拷上去:

sudo tee /etc/ssh/sshd_config.d/99-hardening.conf <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
X11Forwarding no
EOF
sudo sshd -t && sudo systemctl reload ssh

纪律写在便签第二行:旧会话留着,新开窗口确认能进,再关旧的。防火墙只开 SSH:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable

晚上装了 unattended-upgrades,按官方文档装 Docker Engine 和 Compose 插件,用户加进 docker 组后重新登录,跑了一次 hello-world。

2 月 9–10 日:目录和网络,故意放慢

我定了四个根:

  • /opt/stack:compose 项目
  • /data:大体积数据
  • /var/backups/lab:本地暂存
  • ~/notes:变更记录,尽量进 git

路由器做了 DHCP 静态绑定。家庭 DNS 里加了 lab-core.lan。系统和数据分离,重装时痛苦会小一个数量级。

这两天我没有装 Immich,没有开 Minecraft,没有试 Kubernetes。只验证:重启后密钥能登、ufw status 只有预期规则、docker ps 正常、fstab 用 UUID、IP 和盘符用途写进笔记。

有一晚故意拔电再插,来电自启成功,/data 挂上了。那一刻比任何容器起来都让我安心。邻居问为什么灯又亮了,我说在给实验室做停电演练。听起来正经,其实就是怕自己懒。

目录约定写进 git 的第一天,我还画了一张简陋的树状图:系统盘只放系统,数据盘只放数据,备份暂存绝不当主存储。后来 Immich 和游戏档都受益于这个无聊决定。

2 月 11 日:差点把自己锁外面

上午手贱:密钥其实还没 ssh-copy-id 成功,就关了密码认证。旧会话也关了。笔记本连不上。

接显示器键盘进本地,改回 PasswordAuthentication yes,公钥重新拷,再关密码。花了四十分钟,大半时间在找 HDMI 线。

记下来的教训只有一条:改 sshd 之前必须保留一个已认证会话;改完新开窗口验证。显示器当急救通道,不是耻辱。

2 月 12 日:第一个服务,目的只是验证循环

放了一个极简静态页 + Caddy 练手。目的不是上线产品,是走通「compose 起来 → 重启还在 → 日志在哪」。

mkdir -p /opt/stack/hello /data/hello
# compose 里把 ./html 挂到容器,restart: unless-stopped
docker compose up -d
docker compose logs -f --tail=50

中午故意 reboot。起来后页面还在,容器状态 Up。下午把数据改到写进 /data/hello,删容器重建,内容还在——匿名卷的坑终于没踩。

时区昨天忘了在容器里设 TZ,日志时间差八小时,今天补上。小问题,但对后面证书和告警时间很关键。

2 月 13 日:补笔记,列「可以服役」标准

笔记里补了:IP、MAC、数据盘 UUID、Docker 版本、备份暂存路径、来电自启已开。

怎样算可以服役?不是装了多少应用,而是这几条同时成立:

  1. 任意断电后再上电,SSH 密钥能登。
  2. 数据盘按 UUID 挂上,不靠盘符运气。
  3. Docker 组权限正常,compose 项目有固定目录。
  4. 变更有一页笔记:IP、用途、备份位置。

四条都勾上,我才敢跟朋友说「家里有台服务器」。在此之前它只是通电的旧电脑。标准刻意定得无聊,因为无聊才可重复。

无线当主力那晚 NFS 差点挂死——后来网线固定插着,无线只作笔记本漫游。这种细节不写进笔记,三个月后一定会再踩一次。

2 月 14 日:底座上岗,热闹留给后面

七天结束,机箱侧面便签没撕。服务列表仍然很短:hello 静态页、Docker、ufw、密钥 SSH。

它的意义是秩序:可进入、可更新、可隔离、可扩展。有了底座,再谈 WireGuard 和存储池才不慌。第一台实验室主机上岗,不需要热闹,需要能活过下一次重启。

今天情人节,朋友问我干嘛。我说在给旧电脑过上岗日。他们不懂,我懂就行。七天日记到此收束;真正的试验从下周第一台「会哭的服务」开始。

← Back to Blog