SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-27

WSL 還是 VPS?開發環境怎麼選

WSL 與 VPS 解決開發環境的不同需求:了解持續運作、公用 IP、systemd、檔案速度、備份,以及兩者間 SSH 連線的取捨。

開發應使用 WSL 還是 VPS?

開發時選擇 WSL 或 VPS,關鍵在於可用性。WSL(Windows Subsystem for Linux)會在虛擬機器中執行 Ubuntu,而該虛擬機器的生命週期與 Windows 工作階段相同。VPS(virtual private server)則會在公用 IP 位址上執行相同的 Ubuntu,即使您闔上筆電,該位址仍會保持可連線。多數開發人員最後會同時使用兩者,並將伺服器作為持續可連線的主機。

兩者都是 Ubuntu,因此作業系統不是主要差異。差異在於運作時間、從網際網路連線的能力、systemd 能保證的事項、檔案存取速度、網路行為,以及備份由誰管理。以下每個段落都說明一項差異,您可以在自己的電腦上實際觀察其影響。

為什麼關閉筆電後 WSL 會停止?

WSL 2 會在輕量型虛擬機器中執行真正的 Linux kernel。Windows 會依需求啟動這部虛擬機器。只有在某個發行版執行時,這部虛擬機器才會存在;而發行版只有在有程序使用時才會執行。請從 PowerShell 查看狀態:

wsl --version
wsl --list --running

關閉所有 WSL 終端機,等待一分鐘,再次執行 wsl --list --running。當它顯示沒有執行中的發行版時,你啟動的 shell 也已經結束,其中執行的所有內容也會一併停止。wsl --shutdown 會立即執行相同操作,可用來測試系統重新啟動後的行為。

睡眠與休眠也會停止這部虛擬機器。設定在 03:00 傾印資料庫的計時器,在闔上螢幕時不會觸發,因為負責執行它的 kernel 並未運作。系統不會記錄錯誤,因此看起來就像工作從未排程過。正是這項行為讓人改用另一台機器:建置佇列、聊天機器人、每晚執行的備份或 webhook 接收器,都需要一台持續開機的電腦。

WSL 支援 systemd 嗎?

支援。WSL 0.67.6 開始提供這項支援,但舊版安裝預設會停用。未啟用時,systemctl status ssh 會輸出:

System has not been booted with systemd as init system (PID 1). Can't operate.

先讀取設定檔,因為其中可能已經有設定。若沒有 [boot] 區段,請附加一個;若已有該區段,請在現有區段內加入這一行。

cat /etc/wsl.conf
sudo tee -a /etc/wsl.conf >/dev/null <<'EOF'
[boot]
systemd=true
EOF

在 PowerShell 中執行 wsl --shutdown,開啟新的 Ubuntu shell,然後使用 systemctl list-units --type=service --state=running 檢查。若顯示單元清單,表示 systemd 已是 PID 1,之後 journalctl -b 即可正常運作。

關鍵在於 enable 在不同機器上所代表的意義。 在 VPS 上,sudo systemctl enable --now caddy 表示服務會在開機時啟動,因此即使沒有人登入,重新開機或升級 kernel 後服務也會恢復執行。在 WSL 中,這表示服務會在發行版啟動時啟動,而發行版會在你開啟終端機時啟動。因此,服務只有在你工作期間才會執行,這與服務存在的目的相反。容器也有相同的限制,所以讓 Docker Compose 服務在開機時啟動取決於 WSL 是否執行開機流程,而 WSL 只有在你要求時才會執行該流程。

Webhook 能連到在 WSL 中執行的伺服器嗎?

沒有額外設定就不行,原因在於網路配置。WSL 2 的預設模式會將虛擬機器置於 NAT(網路位址轉譯)後方,並使用自己的虛擬網路介面。查看其位址:

ip -4 addr show eth0
ip route show default

這是私有位址,而且每次虛擬機器啟動時都會重新指派,因此會變動。Windows 本身仍可連到 localhost:3000,因為 WSL 會將 localhost 連線轉送到該發行版。網路上的其他電腦則無法連線,除非使用系統管理員 PowerShell 新增代理規則:

netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=172.24.108.3

這項規則指定單一位址,因此位址下次變更時就會失效。Mirrored networking 是較好的選項:該發行版會取得與 Windows 相同的網路介面和位址。截至 2026 年 8 月,此功能需要 Windows 11 22H2 或更新版本。將下列內容放入 %UserProfile%\.wslconfig,然後執行 wsl --shutdown

[wsl2]
networkingMode=mirrored

Mirrored mode 可解決本機網路問題,但不會提供公開位址。路由器會再次執行 NAT;多數家用網路連線沒有可由你控制的入站連接埠,許多 ISP 還會在上游再加一層 NAT。因此,GitHub 無法將事件 POST 到你的筆記型電腦,同事也無法開啟你的示範連結。Tunnel service 可以避開這個限制,但 tunnel client 會在筆記型電腦上執行,因此筆記型電腦仍必須保持運作。

VPS 從問題的另一端開始。它具備公開 IPv4 位址,通常也有公開 IPv6 位址,只有你開放的連接埠可以對外使用。將 A record 指向它,允許 80 和 443,便能從任何地方回應。這也是取得公開憑證的必要條件,因為 HTTP-01 challenge 會要求 Let's Encrypt 透過公開名稱的 80 埠擷取檔案。使用 Certbot 和 nginx 取得 Let's Encrypt 憑證 在伺服器上只需 5 分鐘,在 WSL 中則無法完成。若是本機工作,仍可透過將自己的 CA 加入 Ubuntu trust store,在 WSL 中取得瀏覽器信任的 HTTPS。

為什麼在 /mnt/c 上執行 git 很慢?

因為檔案不在 Linux 檔案系統上。WSL 提供兩個成本差異很大的儲存區域。您的家目錄位於虛擬磁碟內的 ext4 檔案系統,行為與一般 Linux 磁碟相同。/mnt/c 是 Windows 磁碟,由 Windows 端的元件透過 9P 通訊協定(Plan 9 檔案系統通訊協定)提供,因此每次 open 與 stat 都必須跨越這個邊界。

單一檔案不成問題。但在大型儲存庫中,git status 會執行數千次 stat 呼叫,而每次呼叫都必須承擔跨越邊界的成本。請自行測量,不要直接採信任何人的數據,包括本頁提供的數據:

cd /mnt/c/Users/you/code/myrepo && time git status
cp -r /mnt/c/Users/you/code/myrepo ~/myrepo
cd ~/myrepo && time git status

每個指令都執行兩次,並比較第二次的結果,確保測量時快取已暖機。Windows 即時防毒軟體會在 /mnt/c 端增加額外成本,因此同一個儲存庫在公司筆記型電腦上可能比在個人電腦上更慢。

在 WSL 中,解決方法是將工作副本放在 ~ 下,並使用編輯器的 WSL remote mode 開啟,讓編輯器伺服器在該發行版內執行,而不是跨越邊界存取檔案。Explorer 仍可在 \\wsl.localhost\Ubuntu\home\you 瀏覽這些檔案。VPS 沒有這個問題,因為它只有一個 Linux 檔案系統。您需要承擔的是編輯時的網路延遲,因此使用者通常會在 terminal multiplexer 或 remote editor session 中工作。在小型伺服器上,共用 CPU 資源是必須正視的限制;鄰居佔用資源造成的 steal time 會在 top 中顯示為 st 欄位。

WSL 明顯勝出的地方

  • 免費,而且已經安裝在電腦上。啟用 WSL、安裝 Ubuntu 後,1 分鐘內就能開始工作,不必付費,也沒有需要防禦的公開攻擊面。
  • 它可以像伺服器無法做到的方式隨時丟棄。wsl --export Ubuntu D:\wsl-backups\ubuntu.tar 會將整個發行版寫入單一檔案,wsl --import 可將其還原,或以第二個名稱建立複本。在這裡嘗試新的 Ubuntu 版本,只需要建立複本並準備回復;而 將 VPS 從 24.04 升級至 26.04 是單向變更,必須配合目前已在執行的服務安排時程。
  • GPU 工作可直接使用硬體。搭配目前版本的 Windows GPU 驅動程式後,發行版內即可使用該顯示卡,因此 CUDA 與 ROCm 工作負載能直接使用現有硬體。按小時租用同級 GPU 則需要實際支付費用。
  • 編輯迴圈更短。檔案與瀏覽器都在本機,因此在 localhost:5173 上啟動的開發伺服器,可以直接在你已登入的瀏覽器中開啟。

這些都是實際優勢,也是通常建議同時使用兩台機器,而不是只選一台的原因。

誰負責備份?

兩台機器都由你負責,而 WSL 的這一點常讓人意外。發行版是 Windows 使用者設定檔中的虛擬磁碟檔案(ext4.vhdx)。沒有任何服務供應商會替你建立快照。wsl --unregister Ubuntu 會直接刪除它,且無法復原;重新安裝 Windows 也會連同其他資料一起刪除。請依照你確實能持續執行的排程匯出:

wsl --export Ubuntu D:\wsl-backups\ubuntu-2026-08-18.tar

在 VPS 上,供應商快照可在主機故障時提供保護。但它無法防止你將 rm -rf 放在錯誤的目錄中;若快照與伺服器位於同一個帳戶,只要該帳戶的登入資訊遭竊,快照也可能一併消失。請將檔案層級備份傳送到主機外部,並在真正需要之前先測試還原。兩種情況下,責任都在你身上。實務上的差異是,伺服器可以在 03:00 自行執行備份,不必請任何人讓筆電保持開機。

橋接:從 WSL 透過 SSH 連線至 VPS

只有在連線尚未正確設定時,第二台機器才會讓人覺得麻煩。在 WSL 中完成以下設定即可。

請在該發行版內產生金鑰,不要在 Windows 端產生。如此一來,私密金鑰會留在具備 Unix 權限的 ext4 檔案系統中,而 ssh 可接受這些權限:

ssh-keygen -t ed25519 -C "dev@laptop"
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@203.0.113.10

Ed25519 金鑰短小且速度快,而 ssh-copy-id 會以正確的模式,將公開金鑰附加至伺服器上的 ~/.ssh/authorized_keysSSH 金鑰管理基礎說明日後如何輪替與撤銷金鑰。

~/.ssh/config 中為伺服器指定名稱:

Host dev
  HostName 203.0.113.10
  User deploy
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
  ForwardAgent yes
  ServerAliveInterval 30

現在 ssh dev 會建立連線。IdentitiesOnly yes 會停止用戶端提供其持有的所有金鑰。當 agent 載入多個金鑰時,這可避免產生 Too many authentication failuresServerAliveInterval 30 會讓 home 連線上的工作階段持續運作,不會無訊息地中斷。

ForwardAgent yes 是讓整個工作流程變得簡單的設定。只要筆記型電腦上的 agent 已載入金鑰,git clone git@github.com:you/app.git 就能在伺服器上運作,而不必讓私密金鑰出現在伺服器上。請從 VPS 執行 ssh -T git@github.com 進行測試,預期會回應 Hi you! You've successfully authenticated。只將 agent 轉送至信任的伺服器,因為在連線期間,該機器上的 root 可以使用你的 agent socket。在與他人共用的伺服器上,使用每個 repository 專用的 deploy key 會更安全。

WSL 不會在不同 shell 之間持續執行 agent,因此每個新終端機都會再次要求金鑰。keychain 可解決這個問題:

sudo apt update && sudo apt install -y keychain
echo 'eval "$(keychain --eval --quiet id_ed25519)"' >> ~/.bashrc

開啟新的 shell,然後執行 ssh-add -l。該指令應列出金鑰指紋。若顯示 Error connecting to agent,表示沒有讀取該行。請確認你的 shell 確實載入 ~/.bashrc

請在終端機多工器內於伺服器上執行工作,避免連線中斷時工作也被終止:

tmux new -s dev
# Ctrl-b then d to detach
tmux attach -t dev

即使關閉筆記型電腦,建置仍會繼續執行。這正是使用第二台機器的原因。同樣的模式也可用來在 VPS 的 tmux 中執行 Claude Code,之後再從其他裝置恢復該工作階段。

在放入任何內容之前,先強化這台主機。新 VPS 上線後的前 10 分鐘會依照不會導致自己無法登入的順序,說明如何建立非 root 使用者、設定僅限金鑰的 SSH、防火牆及自動安全更新。

哪台機器適合哪種工作?

工作內容會在螢幕上進行時,使用 WSL。這包括編輯、執行測試套件、在 localhost 上執行開發伺服器、使用 notebooks、進行 GPU 實驗,以及任何需要啟動後持續觀察的工作。

工作必須可供外部存取,或必須在工作階段結束後繼續執行時,使用 VPS。例如,客戶可以開啟的 staging URL、webhook endpoint、依照實際時間執行的 cron job、bot、供其他服務連線的小型資料庫,以及星期五下午啟動的匯入工作。

如果你仍在考慮第二台機器的用途,人們實際在 VPS 上執行的工作 比規格比較更實用;VPS 是什麼 則說明其底層的虛擬化機制。如果你的工具只能在 Windows 上執行,那是另一項決策,Linux 與 Windows Server 的比較 是適合參考的頁面。

只要養成一個習慣,就能避免兩台機器都變成只完成一半設定的機器:程式碼存放在 git 中,而兩台機器都是 repository 的用戶端。任何重要內容都不會只存在其中一台機器上。

FAQ

我可以從 WSL 使用正式網域代管網站嗎?

無法可靠地做到。WSL 2 位於電腦內部的 NAT 後方,而路由器還會再執行一次 NAT;多數家用網路也不提供可轉送的入站連接埠。通道服務可以公開本機連接埠,但通道用戶端執行於筆記型電腦上,因此筆記型電腦進入睡眠時,網站也會中斷。憑證會讓問題更複雜,因為 HTTP-01 challenge 要求 Let’s Encrypt 透過公用名稱的 port 80 擷取檔案。具備公用 IP 位址與 A record 的 VPS 可同時滿足這兩項條件,無須繞道處理。

systemctl enable 在 WSL 中可以運作嗎?

啟用 systemd 後即可運作,也就是在 /etc/wsl.conf[boot] 下設定 systemd=true,接著執行 wsl --shutdown。未啟用時,systemctl 會回覆 System has not been booted with systemd as init system (PID 1). Can't operate.。即使 systemd 正在執行,enable 也只會在發行版啟動時啟動服務,而發行版是在你開啟 shell 時才啟動。在伺服器上,相同的命令表示重新開機後,即使沒有任何人登入,服務也會恢復執行。

為什麼我的 WSL IP 位址一直變動?

在預設的 NAT 模式中,每次虛擬機器啟動時,都會從 WSL 虛擬介面取得新的私有位址。任何 netsh interface portproxy 規則或硬式編碼的位址都會在 wsl --shutdown 後失效。使用 ip -4 addr show eth0 檢查目前的位址。Windows 11 的 mirrored networking mode 會讓發行版使用與 Windows 相同的介面,藉此移除獨立位址:在 %UserProfile%\.wslconfig[wsl2] 下設定 networkingMode=mirrored

/mnt/c 真的比較慢,還是只是迷思?

確實比較慢,在自己的電腦上測試 1 分鐘即可證明。~ 下的檔案位於 ext4 虛擬磁碟。/mnt/c 下的檔案由 Windows 端元件透過 9P protocol 提供,因此每次 stat call 都會跨越邊界,而在大型樹狀目錄上執行 git status 時,會產生數千次這類呼叫。將 repository 複製到 ~,在每個位置各執行 time git status 2 次,然後比較 warm runs。將工作副本放在 ~ 下,並使用編輯器的 WSL remote mode。

有了 VPS 後,我還需要 WSL 嗎?

多數人會兩者都保留。WSL 免費且啟動迅速,因此仍適合用來編輯與測試;GPU 工作也應在這裡執行。伺服器則是持續運作的機器:它持有公用名稱,並執行必須在筆記型電腦關閉後仍持續的工作。將程式碼存放在 git 中,並將兩者都視為 repository 的用戶端,在兩者之間移動工作不會增加成本。

#wsl#ubuntu#development#vps#workflow