一台 2015 年的 MacBook Pro,到 2026 年已經不是什麼理想的日常工作電腦。
但這不代表它沒有計算價值。
如果硬體仍然正常、有 SSD、有記憶體、有 Gigabit Ethernet,而且大部分工作本來就可以容器化,那它其實更適合脫離桌面作業系統,變成一台長期在線的 Linux Server。
一、改裝目標與最後架構
這次我的目標很單純:
把一台 MacBook Pro 2015 完全清除 macOS,安裝 Debian 13,只留下 SSH、Docker、Tailscale,最後關上螢幕,當成一台 24 小時運作的 Docker Server。
實際完成後,架構是:
MacBook Pro 2015
│
├─ Debian 13
├─ OpenSSH
├─ Docker Engine
├─ Docker Compose
├─ Tailscale
│
├─ 2TB internal SSD
│
└─ USB Gigabit Ethernet
日常管理則完全不碰 MacBook:
Windows / 其他電腦
│
├─ LAN SSH
│
└─ Tailscale SSH
│
▼
Debian Server
│
Docker
這篇記錄整個實際安裝流程,包括幾個 2015 MacBook 特有的坑。
二、為什麼最後選 Debian,而不是 Ubuntu?
最初其實考慮的是 Ubuntu Server。
Ubuntu 的優點非常明顯:文件多、教學多、遇到問題容易查,而且 Docker 支援也很好。
但這台機器的目的不是當 Linux 工作站,而是:
開機 → SSH → Docker → 長時間不碰 OS
最後因此選 Debian 13。
Debian 在這個情境下的優勢不是「效能突然快很多」,而是系統層比較簡單。沒有 GUI,沒有不必要的桌面服務,也不需要安裝 GNOME、KDE、Xfce。
這台電腦的工作不是讓人操作,而是讓程式運作。對 Server 而言,這是一個重要差別。
三、硬體與安裝前準備
這次使用:
- MacBook Pro 2015
- Intel x86-64
- 內建 SSD:2TB
- 安裝媒體:32GB USB
- 網路:USB → Gigabit Ethernet
原本的 SSD 已經升級到 2TB,因此磁碟容量對 Docker、資料庫、Crawler、Agent 等服務都相當充裕。
安裝前先完成所有 macOS 資料備份。
因為這次不是 Dual Boot,而是準備直接清掉整顆 SSD。
四、製作 Debian 安裝 USB
下載 Debian 13 amd64 netinst ISO,再使用 Rufus 把 ISO 寫入 32GB USB。
Rufus 的基本設定:
- Boot selection:Debian ISO
- Partition scheme:GPT
- Target system:UEFI
寫入完成後,把 USB 插入 MacBook。關機,再按電源鍵後立刻長按:
Option ⌥
直到出現 Apple 的開機磁碟選擇畫面。選擇 EFI Boot,即可從 Debian USB 啟動。
五、開始安裝 Debian
Debian Installer 有文字與圖形版本。我直接選:
Graphical install
雖然最後不會安裝桌面 GUI,但安裝時使用 Graphical Installer 比較方便。
語言我選 English。Server 上使用英文環境的好處很實際:未來查 log、錯誤訊息與 Linux 文件時,不需要再做翻譯。
設定大致如下:
Language:English
Location:Taiwan
Keyboard:American English
六、MacBook 2015 的 Broadcom Wi-Fi firmware 問題
安裝器很快就跳出:
Some of your hardware needs non-free firmware files...
brcmfmac43602...
這是 MacBook 2015 內建的 Broadcom Wi-Fi。
但這台機器本來就準備作為 Server,因此我沒有打算依賴 Wi-Fi。機器上已經接了一張 USB Ethernet,所以 firmware 畫面直接選 No。
接著 Debian 成功偵測出兩個網路介面:
enx........ USB Ethernet
wlp3s0 Broadcom Wi-Fi
選擇 enx........ 後,DHCP 成功拿到 IP。這也證明 USB Ethernet 可以直接使用,不需要額外驅動。
對 Server 而言,我反而認為這是更好的架構:
Router
│
Ethernet
│
USB Ethernet
│
MacBook
比依賴十年前的 Broadcom Wi-Fi 可靠。
七、設定 Hostname、使用者與 root
Hostname 設為:
mbp-server
Domain name 留白。家用網路和 Tailscale 環境沒有必要硬設定 DNS domain。
之後 Linux shell 就會變成:
alan@mbp-server:~$
Debian Installer 接著會要求設定 root password。我選擇兩格全部留白。
這樣 root 不直接登入,而是建立一般使用者後用 sudo 取得管理權限。
接著建立:
Full name:Alan
Username:alan
Password:自行設定
之後執行 sudo apt update,就會使用 alan 的密碼取得權限。
八、清除 macOS:整顆 SSD 給 Debian
磁碟分割選:
Guided - use entire disk and set up LVM
不要選:
largest continuous free space
因為那通常意味著保留既有 macOS partition。
接著 Installer 顯示兩顆磁碟:
/dev/nvme0n1
2.0 TB internal SSD
/dev/sda
31 GB USB
這裡一定要確認。我選的是 /dev/nvme0n1,也就是 2TB 內建 SSD。31GB 那顆是 Debian 安裝 USB,不能選錯。
接著選:
All files in one partition
這對 Docker Server 非常合理。如果過早把 /home、/var、/srv 切成固定大小,未來很容易出現 /var/lib/docker 滿了,但其他 partition 還有大量空間的情況。
因此先讓整顆 SSD 共用空間。LVM 容量直接選 2.0 TB,最後確認:
Write changes to disk → Yes
這一步之後,原本的 macOS 就正式消失了。
九、Mirror 與最重要的套件選擇
Debian Mirror 設定:
Mirror country:Taiwan
Mirror:deb.debian.org
HTTP proxy:留白
Package usage survey:No
Debian Installer 接著會問要安裝哪些軟體。預設可能包含 Debian desktop environment、GNOME、Xfce、KDE 等選項。
桌面環境全部取消,最後只留下:
[X] SSH server
[X] standard system utilities
這一步決定了這台機器之後不會有桌面。沒有 Dock、桌布、Finder、瀏覽器、視窗或桌面環境。
開機後只會看到:
Debian GNU/Linux 13 mbp-server tty1
mbp-server login:
這就是我要的。
十、第一次開機與 Retina TTY
安裝完成後拔掉 Debian USB,重新開機並登入:
login: alan
password: ********
成功後會看到:
alan@mbp-server:~$
到這裡,MacBook 已經正式變成 Linux Server。
不過,一開機馬上會發現 MacBook Retina 配 Debian TTY,字小得離譜。可以執行:
sudo dpkg-reconfigure console-setup
設定例如:
Encoding:UTF-8
Font:Terminus
Font size:16x32
Server 日後主要透過 SSH 使用,所以這只是讓本機 emergency console 比較容易閱讀。
十一、確認 Ethernet,從 Windows SSH 登入
先確認網路介面:
ip -br a
可以看到類似:
lo UNKNOWN 127.0.0.1/8
enx........ UP 192.168.1.xxx/24
wlp3s0 DOWN
代表 USB Ethernet 正常,Wi-Fi 未使用。
測試外網與 DNS:
ping -c 4 1.1.1.1
ping -c 4 deb.debian.org
兩個都成功後,Server 網路完成。
同一個區網的 Windows 即使使用 Wi-Fi,也可以連到接 Ethernet 的 MacBook,只要兩台都在相同 LAN。
在 PowerShell 執行:
ssh alan@192.168.1.xxx
第一次會看到:
The authenticity of host ... can't be established.
確認連線對象與指紋無誤後輸入 yes,再輸入 Debian 的 alan 密碼。成功後就會看到 alan@mbp-server:~$。
從這個時間點開始,我幾乎就不需要再碰 MacBook 的鍵盤了。
接著先更新 Debian:
sudo apt update
sudo apt upgrade -y
本次系統顯示:
Upgrading: 0
Installing: 0
Removing: 0
Not Upgrading: 0
然後重新開機:
sudo reboot
SSH 會自然斷線。等機器重新啟動後再連回去即可。
十二、安裝與測試 Docker Engine
這次沒有使用 Debian 自帶的 docker.io,而是使用 Docker 官方 repository。
先安裝必要套件:
sudo apt install -y ca-certificates curl
建立 keyring:
sudo install -m 0755 -d /etc/apt/keyrings
加入 Docker GPG key:
sudo curl -fsSL https://download.docker.com/linux/debian/gpg \
-o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
建立 repository:
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: trixie
Components: stable
Architectures: amd64
Signed-By: /etc/apt/keyrings/docker.asc
EOF
更新並安裝 Docker:
sudo apt update
sudo apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
執行測試:
sudo docker run hello-world
看到以下訊息,表示 Docker daemon、Docker Hub 與 container runtime 都正常:
Hello from Docker!
This message shows that your installation appears to be working correctly.
為了讓一般帳號直接使用 Docker,可以把 alan 加入 docker group:
sudo usermod -aG docker alan
接著執行 exit,重新 SSH 登入,再測試:
docker ps
docker compose version
本次環境顯示:
Docker Compose version v5.5.0
代表 Docker Compose plugin 也正常。
十三、安裝 Tailscale,從外面 SSH 回家
LAN SSH 解決了家裡管理。但我要的是:人不在家,也能安全連回這台 Server。
這裡使用 Tailscale。安裝:
curl -fsSL https://tailscale.com/install.sh | sh
啟動:
sudo tailscale up
Terminal 會產生一個登入網址。用瀏覽器登入並授權這台 mbp-server。
完成後執行:
tailscale ip -4
會得到:
100.x.x.x
這是這台 MBP 的 Tailscale IP。
另一台 Windows 也加入同一個 Tailnet 後,可以:
ssh alan@100.x.x.x
這裡使用的仍然是 Debian alan 的密碼,不是 Tailscale 密碼。
因為 Tailscale 負責的是網路連線,真正執行 SSH authentication 的仍然是 Debian OpenSSH。因此:
ssh alan@192.168.1.xxx
ssh alan@100.x.x.x
其實都是登入同一台 mbp-server、同一個 alan、同一個密碼、同一把 SSH Host Key,只是走不同路徑。
不要把 SSH 密碼接在指令後面
一個很容易犯的錯是:
ssh alan@IP我的密碼
這是錯的。正確一定是:
ssh alan@IP
看到 alan@IP's password: 再輸入密碼。
Linux/SSH 在輸入密碼時不會顯示 * 或圓點,畫面看起來完全沒有反應,這是正常行為。
十四、讓 MacBook 闔蓋後繼續運作
Server 最大的問題來了:MacBook 是筆電,正常情況下關上 lid 就會 suspend。
但我要的是:
- 螢幕關掉
- MacBook 闔起來
- Docker 照跑
- SSH 照連
編輯:
sudo nano /etc/systemd/logind.conf
設定:
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
注意前面不能有 #,因為 #HandleLidSwitch=ignore 只是註解,並沒有真正生效。
儲存後:
sudo systemctl restart systemd-logind
確認:
grep -E '^HandleLidSwitch|^HandleLidSwitchExternalPower' \
/etc/systemd/logind.conf
應該看到:
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
再做第二層保險,把 sleep/suspend 完全關掉:
sudo systemctl mask \
sleep.target \
suspend.target \
hibernate.target \
hybrid-sleep.target
系統會建立:
sleep.target → /dev/null
suspend.target → /dev/null
hibernate.target → /dev/null
hybrid-sleep.target → /dev/null
代表這些 target 已被 mask。
十五、確認自動啟動並進行闔蓋測試
確認 Docker 與 Tailscale 開機自動啟動:
systemctl is-enabled docker
systemctl is-enabled tailscaled
兩個都應該回傳:
enabled
再確認 Docker status:
systemctl status docker --no-pager
正常應該是:
Active: active (running)
本次 Docker daemon 空載時記憶體大約只有數十 MB。這也是為什麼這種舊機器很適合做 headless Linux Server。
設定好之後,我直接把 MBP 螢幕蓋上。等了一兩分鐘,另一台 Windows 先測 LAN:
ssh alan@192.168.1.xxx
成功。再測 Tailscale:
ssh alan@100.x.x.x
也成功。
這才算真正證明:
MacBook Lid Closed
│
▼
Debian 仍運作
Docker 仍運作
Ethernet 仍運作
SSH 仍運作
Tailscale 仍運作
到這一步,這台 MacBook 才正式完成 Server 化。
十六、停電與服務恢復
MacBook 做家庭 Server 有一個意外的優點:它自己就有電池。
一般 mini PC
市電中斷 → 直接斷電
MacBook
市電中斷 → 自動切換內建電池 → Server 繼續運作
也就是自帶一個小型 UPS。如果只是短暫停電,甚至可能完全不會中斷服務。
如果停電時間長到電池耗盡,Debian 關機、Docker 停止。恢復供電之後,這台老 MacBook 未必會自動開機。
我的情況並不要求完全 unattended,所以最壞情況只需要有人:
掀開 MacBook → 按電源鍵
Debian 開機後,Docker、Tailscale、SSH 都會自動恢復。
如果每個 Docker service 又設定:
restart: unless-stopped
application container 也可以自行恢復。
十七、這台 Server 適合做什麼?
完成 Server 化後,它的用途其實比繼續當一台十年前的 macOS 筆電廣很多。
特別適合:
- Docker services
- Crawler、Playwright、Python worker
- Cron、Webhook、Scheduler
- LINE Bot、Telegram Bot
- API Server、Laravel、FastAPI、Node.js
- PostgreSQL、Redis、Nginx
- Cloudflare Tunnel、n8n、Gitea
- Uptime Kuma、Syncthing、Samba
- AI Agent orchestration、LLM API worker、CI/CD
不適合:
- 大型 Local LLM
- Stable Diffusion
- ComfyUI 大型 workload
- Video generation
- CUDA workload
原因很簡單:它沒有現代 NVIDIA GPU。
因此它最合理的角色不是 AI GPU machine,而是 Always-on Infrastructure Node。
我現在把它看成:
MacBook Pro 2015
│
▼
Debian Control / Service Node
│
├─ Docker
├─ Database
├─ Crawler
├─ API
├─ Agent
├─ Queue
├─ Scheduler
└─ Monitoring
GPU 工作仍然交給另外一台有 RTX GPU 的 Windows workstation。
這台 MBP 負責 Always-on、Low-power、Networking、Scheduling、Orchestration、Storage 與 Services。兩者其實是完全不同的工作。
十八、第一批準備搬進來的服務:Crawler
我目前沒有打算急著把 production Web Server 從雲端搬回家。
因為原本的 Lightsail 每個月成本只有大約 USD 24。為了省這筆費用,把已經穩定運作的 production system 從雲端移回一台 2015 年筆電,其實不是很好的交易。
比較合理的是:
Lightsail
→ Production
→ 公開 Web
→ Critical DB
MBP
→ Crawlers
→ Workers
→ AI agents
→ Batch jobs
→ Internal services
尤其爬蟲非常適合第一批搬回來。Crawler 通常:
- 不需要外部 inbound port
- 不要求 99.99% uptime
- CPU/RAM/bandwidth 有實際需求
- 可以容忍短暫中斷
這正好適合家庭 Server。
未來可以建立:
/srv/docker/
├── crawlers/
├── agents/
├── monitoring/
├── postgres/
├── redis/
└── tools/
/srv/data/
把 application 與 persistent data 分開管理。
十九、最後的結果
原本它是一台:
2015 MacBook Pro
老舊 macOS
日常價值持續下降
現在變成:
2015 MacBook Pro
│
▼
Debian 13
│
├── OpenSSH
├── Docker
├── Docker Compose
├── Tailscale
├── 2TB SSD
└── Gigabit Ethernet
平常螢幕完全關起來。沒有 GUI,沒有滑鼠,沒有桌面。我甚至不需要坐在它前面。
在家:
ssh alan@192.168.1.xxx
在外:
ssh alan@100.x.x.x
然後直接開始工作。
這可能才是很多十年前 Intel Mac 最合理的生命延長方式。
不是努力讓它繼續像一台 2026 年的筆電。
而是停止要求它做一台現代筆電,讓它改做一件舊 CPU 到現在仍然非常擅長的事情:
安靜地、持續地執行程式。