[随笔记录]使用Mac mini作为家用服务器

写在开头

由于 受到库老头远程蛊惑施法 在观察了一些视频以及发现原先使用的Orange Pi 5 Plus有一些性能不足的问题,因此趁着国补采购了一个Mac mini M4丐版(16G+256G)。建议各位理性购买,确认自己有需求后再下手。

本文章将从开箱,服务迁移与部署,问题排障展开。

开箱

Mac mini的采购来源是Apple京东自营店,叠加上海地区国补和教育优惠,原价3749元,于4月20日在高铁上2999元拿下。原本提示需要调货,4月25日送达,结果4月21日下午就送达了。

由于是国家补贴,需要当面和快递员拆箱。快递员似乎从来没有见过Mac mini,于是要求我插上屏幕登录Apple ID。我进行反复解释说明,他最终致电询问他人,对着我的包装,三包凭证,保修卡反复拍照,接着交货完成。擦锭开机,接入有线网络,显示器,进行默认初始化设置进入桌面。

如果要把Mac mini作为服务器,显然不会经常插入显示器,因此我参考这个Bilibili视频完成了虚拟显示器与iPad随航的配置。接着在Unifi后台为Mac mini指定静态IP并绑定内网mDNS名称。

服务迁移与部署

首先简单列出一下我目前需要部署的服务(其余支持软件将在下文列出)

其余支持软件

  • 1Password - 密码管理器
  • MCSManager - Minecraft服务器管理器
  • Orbstack - Docker Desktop替代
  • Sublime Text - 文本编辑器
  • Navicat Premium - 数据库查看编辑器
  • MySQL - 数据库
  • App Cleaner & Uninstaller - 应用卸载器
  • Surge - 代理与网络工具
  • Homerow - 键盘控制工具
  • Lingon X - 登录项与计划任务管理
  • Bartender 5 - 屏幕顶栏管理
  • SwitchHosts - Host文件管理
  • Tailscale - 异地组网
  • cloudflared - Cloudflare隧道
  • RustDesk - 远程控制
  • BetterDisplay - 虚拟显示器
  • BetterTouchTool - 键盘快捷键
  • rclone - 文件向对象存储备份

本次部署时尝试的方法优先级:Docker ComposeDocker RunBinary - Application - Virtual Machine。我非常建议各位在自己的VPS或服务器上部署的时候也尝试类似的方案,个人认为这样有助于管理和下次迁移服务。

此外,强烈推荐在macOS上使用OrbStack来代替Docker Desktop,原因有很多。首先,OrbStack拥有比Docker Desktop更加小的占用(内存和储存)此外,OrbStack无须配置即可在macOS上使用net=hosts这个配置,并且在网络方面,自动接管容器内的流量走系统代理(docker pull等二进制操作依然需要增强模式)(关于不使用增强模式的原因将在排障部分讲解)并为每个容器分配一个自动分配HTTPS证书的*.orb.local的域名。

大部分服务都很快速的通过Docker Compose迁移上线,将原本在Orange Pi上通过.NET运行的Microsoft 365 E5 Renew X改为了Docker运行。

但是在部署MCSManager的时候遇到了阻碍,原因是因为官方没有对macOS进行适配,只能使用Linux或者Windows。官方建议使用Docker部署,但是我发现Docker容器内部的文件我难以管理,尤其是对于实例的文件管理更是难上加难。因此我退而求其次,选择由OrbStack提供的虚拟机功能实现。

OrbStack的虚拟机非常的神奇我称之为msl(macOS Sub-system Linux),他会自动透传Mac的用户文件夹,并且在运行效率很高,对于我轻量供朋友们使用的Minecraft服务器来说不造成性能损失。

在先前的Orange Pi上,我是用宝塔面板内置的备份功能,将部分文件进行本地+OneDrive双重备份来保证文件安全。在macOS上我经过调研后选择了rclone这款软件来实现类似的操作。为此我写了如下的脚本来处理备份问题,可以实现文件上传,保留N个最新的备份,排除文件,使用<script path> <source_path> <backup_dest_path> <retain_count> [exclude_file]。其中exclude_file是一个纯文本文件,里面保存着一行一个不需要被备份的文件/文件夹路径(相对于source_path)。需要将里面的onedrive:替换为自己的config名称。

#!/bin/bash

if [ "$#" -lt 3 ]; then
    echo "Usage: $0 <source_path> <backup_dest_path> <retain_count> [exclude_file]"
    exit 1
fi

SOURCE_PATH="$1"
DEST_PATH="$2"
RETAIN_COUNT="$3"
EXCLUDE_FILE="$4"

SOURCE_DIR_NAME=$(basename "$SOURCE_PATH")
BACKUP_FILE="/tmp/${SOURCE_DIR_NAME}_backup_$(date +%Y-%m-%d_%H-%M-%S).tar.gz"

EXCLUDE_OPTS=""
if [ -n "$EXCLUDE_FILE" ]; then
    if [ ! -f "$EXCLUDE_FILE" ]; then
        echo "Error: Exclude file '$EXCLUDE_FILE' not found!"
        exit 1
    fi
    while read -r line; do
        EXCLUDE_OPTS="$EXCLUDE_OPTS --exclude=$SOURCE_PATH/$line"
    done < "$EXCLUDE_FILE"
fi

echo "Creating backup of $SOURCE_PATH..."

tar -czvf "$BACKUP_FILE" $EXCLUDE_OPTS "$SOURCE_PATH"

echo "Uploading $BACKUP_FILE to $DEST_PATH..."
rclone copy "$BACKUP_FILE" "onedrive:$DEST_PATH"

echo "Cleaning up old backups, keeping only the latest $RETAIN_COUNT..."
rclone lsl "onedrive:$DEST_PATH" | sort -n | tail -n +$((RETAIN_COUNT+1)) | awk '{print $NF}' | while read file; do
    echo "Deleting old backup: $file"
    rclone delete "onedrive:$DEST_PATH/$file"
done

rm "$BACKUP_FILE"

echo "Backup process completed successfully."

接着我使用Lingon X来将其添加为计划任务,不使用crontab的原因是因为在macOS上已经被Launch DaemonLaunch Agent替换掉了,因此使用新的总归没错。

问题排障

RustDesk提示远程主机关闭了连接

这个问题我先说结论,无论是手动编译的二进制文件还是Docker都存在这个问题,其核心原因是因为启用了代理软件的增强模式,我已测试了mihomo partySurge均存在此问题,这也是使用OrbStack其中的一个重要原因,因为他会自动接管容器内的流量走系统代理。

此外,还会出现提示ip/pk not match,原因是你可能在尝试替换密钥对,但是没有替换成功,在替换的时候需要确保容器/二进制已经关机

在此处放上根据1.1.14版本构建的macOS arm64的编译文件:点击下载

Tailscale Derper提示证书不匹配

由于我使用DDNS,因此我的域名类似于*.ddns.domain.com,每一个服务占用一个独立的三级域名,我在Let's Encrypt申请的是\*.ddns.domain.com,因此当使用derper.ddns.domain.com会显示证书不匹配,解决方案如下

找到~/go/pkg/mod/tailscale.com@xxxxx/cmd/derper/cert.go找到func (m *manualCertManager) getCertificate这段内容,把第一个if报错逻辑段注释掉,重新使用go build -o /path/to/derper构建即可,我这里同样放一个构建好的macOS arm64二进制:点击下载

87 个赞

感谢分享:folded_hands:

2 个赞

感谢分享

2 个赞

感谢分享。我也是 macmini。只能刷刷网页了。看看视频。就没啥玩的了。

4 个赞

macos上面的docker似乎得预分配内存,导致docker会非常吃内存 :thinking:

我之前问了一位mac mini m1版本的朋友,他的mac就是当homelab跑docker
因为内存不足,swap疯狂使用,用了一年硬盘坏了,导致我也不是很放心用mac跑服务

不知道佬友的体验如何

2 个赞

目前在跑上述服务的时候内存占用情况如下,经过测试,还未开始使用swap空间

2 个赞

还补充一个抽象的问题,使用macOS自带的屏幕共享链接Mac mini的时候,无法操作原生的选项界面(如右键Dock栏图标点击退出),需要使用RustDesk工具才可以操作,不知道为什么

1 个赞

感谢大佬分享

1 个赞

请问Minecraft和Github Runner的容器占用了多少内存 :thinking:

感觉为了docker吃掉7.66GB有点多了

3 个赞

感谢分享

1 个赞

由于Minecraft在orbstack的虚拟机中运行,因此采用减法推算
7.63*1024-56.52(Alist)-305.9(M365)-133.4(Uptime Kuma)-339.8(Home Assistant)-6.148(DDNS)= Minecraft占用6.80GB

GitHub Runner为脚本直接运行,在监听(等待任务)时占用133M

4 个赞

感觉做服务器不如买别的mini主机,3k能拿下7840hs+32g+2t,装个pve用起来比Mac mini爽多了

4 个赞

插个眼 mark

之前确实有考虑过其他的mini主机,但是综合选择Mac mini的原因如下,供佬友参考

  1. 我其他的所有设备均为Apple,在多设备之间跨设备同步做的比较好
  2. 7840HS功耗为35-54W(来自AMD)还不计算外围功耗,而Mac mini即使在Minecraft世界生成时的功耗也仅有如下来自powermetrics的信息
CPU Power: 3181 mW
GPU Power: 142 mW
ANE Power: 0 mW
Combined Power (CPU + GPU + ANE): 3323 mW

待机状态下(Minecraft服务器无人在线),SOC功耗为582mW

  1. 其拥有完善的服务器套件支持,可为我其余Apple设备提供内容缓存
2 个赞

苹果全家桶的话确实没啥好说的,爽就完事了,我其实也考虑过买Mac mini当服务器,打动我的点也是功耗,最终劝退我的因素是内存,16g没法扩展太伤了

2 个赞

确实,目前重型的虚拟化还是跑在了一台闲鱼来的Dell EMC上

补充用途:用于借给同学/朋友进行模型推理,科学数据演算,视频或建模渲染

1 个赞

之前尝试用闲置的13寸的mbp2015做家庭服务器,外接了一个贝尔金扩展坞接硬盘,qb做种时电脑风扇呼呼地叫,体验很不好 :joy: 这款mac mini静音吗

1 个赞

虽然3K不到入手超静音超省电mini主机也很值了,但主要是做家庭服务器的操作,还是建议买类似N305+16G内存+自插要多大就多大的nvme硬盘的x86小主机,N305其实也蛮省电和低温的,放弱电箱没问题。X86的话装个debian12,8核心想怎么跑就怎么跑,顺便做个特殊网关家里上网的问题也解决了

1 个赞

我把他放在机柜里,我不太清楚,但是通过风扇转速监控几乎不转,关于存储方面我用的是NAS,因此还没有测试过外接

1 个赞

感谢分享,的确有一个在吃灰