---
title: WSL|在 WSL2 中安装 Docker
date: 2022-07-20
is_modified: false
disqus: cynthiahackmd
images: https://imgur.com/nMa3Drb.png
categories:
- "資訊科技 › 開發與輔助工具"
tags:
- "Windows/DOS"
- "Linux/Unix"
- "WSL"
- "工具安裝與部署"
- "Docker"
---
{%hackmd @CynthiaChuang/Github-Page-Theme %}
<br>
前幾天寫了份 Docker 的文件要給客戶,交稿前請 QA 幫忙校稿跟測試...原本一切順利,但突發奇想用了 WSL2 來安裝...結果就 :cry:
<!--more-->
<p class="illustration">
<img src="https://imgur.com/nMa3Drb.png" alt="適用於 Linux 的 Windows 子系統">
適用於 Linux 的 Windows 子系統(圖片來源: <a href="https://linuxiac.com/windows-subsystem-for-linux-explained-wsl-wsl2/">Linuxiac</a>)
</p>
## 問題描述
故事是這樣的,如果按照我提供的 Docker 安裝步驟,理論上坑品不錯的話應該能一次過。但... QA 的職業技能就是踩坑阿...阿不!是跳坑才對,這不馬上就開始發動技能了:
<p class="illustration">
<img src="https://i.imgur.com/ANgeQmq.png" alt="Docker is not running">
</p>
這個好解決,用 `service docker start` 把 service 起起來就好了:
<p class="illustration">
<img src="https://i.imgur.com/4gxrHf9.png" alt="service docker start">
</p>
但緊接著 QA 又丟給了我張截圖 :shocked_face_with_exploding_head: :
<p class="illustration">
<img src="https://imgur.com/gKwlCVC.png" alt="Cannot connect to the Docker daemon at unix:///var/run/docker.sock">
</p>
請她再次確認看一下目前 docker daemon 狀態,結果依舊顯示 not running。再排除系統重啟、service 重啟...等一些常見狀況與排除方法後,我們將目光放在了 WSL 這個環境上了...
## 安裝 WSL2
之前在曾經試著 [Win10 上安裝和使用 WSL](https://hackmd.io/@CynthiaChuang/WSL-Install-and-Use-the-Ubuntu-subsystem-in-Win10),所以這邊就跳過一些介紹,直接開始來裝 Docker 啦!
恩...原本是這麼打算的啦,想說可以直接從 Docker 的安裝開始。但進入 Ubuntu 後,就看到這個:
<p class="illustration">
<img src="https://imgur.com/BVTMZXb.png" alt="Docker 在 WSL1 中不支援需升級成 WSL2">
</p>
恩...我還是先重新安裝 WSL2 吧。
### Step1|確認 Windows 版本
若要安裝 WSL2,Windows 必須滿足一定的版本需求,對於 Windows 10 需符合:
- **x64**: 版本 1903 或更新版本,使用組建(Build Number) 18362 或更新版本。
- **ARM64**: 版本 2004 或更新版本,使用組建 19041 或更新版本。
或者直接使用 Windows 11。
<br>
想要確認版本與組建號碼的話,按 `Win 鍵 + R` 並輸入 `winver`,就可以看到相關數字了:
<p class="illustration">
<img src="https://i.imgur.com/v93FIjJ.png" alt="確認版本與組建號碼">
</p>
### Step2|啟用 Windows 子系統 Linux 版和啟用虛擬機器功能
啟用 Windows 子系統 Linux 版,才能在 Windows 上裝任何 Linux 版本;而要升級到 WSL2 ,則必須多啟用虛擬機器平台功能。
在上次的步驟中,所用到的下列指令就是啟用 Windows 子系統 Linux 版:
```bash=
$ Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```
這次在官網上看到另外一種啟用指令,也跟啟用虛擬機器平台的指令一並貼出來:
```bash=
# 啟用 Windows 子系統 Linux 版
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
# 啟用虛擬機器平台
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```
<br>
另外也可以藉由 UI 來啟動。開啟 `控制台 → 程式集 → 開啟或關閉 Windows 功能`,勾選其中「Windows 子系統 Linux 版」與「虛擬機器平台」。
<p class="illustration">
<img src="https://i.imgur.com/3pyD5A3.png" alt="開啟或關閉 Windows 功能">
</p>
設定完後,得重新開機,才能套用設定。
<br>
是說,我在許多教學中發現都會**啟用 Hyper-V**,因為 WSL2 是使用 Hyper-V 架構來實現虛擬化的,但在官方的教學過程中好像並沒有啟動 Hyper-V 的步驟?
剛好在知乎上有人提出[相關的討論](https://www.zhihu.com/question/439585675),得到結論==是不需要開啟 Hyper-V,但要啟用虛擬機器平台功能,因為這個虛擬機器平台就是一個精簡版的 Hyper-V==。再根據[木頭龍的回答](https://www.zhihu.com/question/439585675/answer/2144365789)詳細來看,Hyper-V 可分成 2 部分:底層的虛擬機器平台及上層的虛擬機器管理軟體,這兩個功能在之前是**合併在一起的**,我想這有可能就是部分教學文章會說開啟 Hyper-V 的原因?
### Step3|下載 Linux 核心更新套件
接下來更新 WSL2 Linux 核心套件,這步驟比較簡單[下載最新套件](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi)後,點擊安裝就好。
<br>
不過,有一次我載完後忘記安裝就繼續往下做,等我要開起 Linux 時就得到了 `WslRegisterDistribution failed with error` :sweat_smile: ...
<p class="illustration">
<img src="https://i.imgur.com/VBu3Ual.png" alt="忘了更新套件">
</p>
### Step4|將 WSL2 設定為預設版本
開啟 PowerShell,將 WSL2 設為預設版本:
```bash=
$ wsl --set-default-version 2
```
<p class="illustration">
<img src="https://i.imgur.com/xPTqL2W.png" alt="成功將 WSL2 設為預設版本">
</p>
### Step5|安裝並啟動 Linux
這邊就不提了,跟[之前](https://hackmd.io/@CynthiaChuang/WSL-Install-and-Use-the-Ubuntu-subsystem-in-Win10)的下載與執行步驟一樣。如果只是要從 WSL1 升到 WSL2 應該是不用重裝才對,我單純只是為了網誌截圖才重裝的。
## 在 WSL 中安装 Docker
我找到了兩種方式,可以在 WSL 中安装 Docker:
### 方法1|安裝 Docker 搭配 Docker Desktop
在 WSL2 中安裝 Docker 最常見的方法是採用 Docker Desktop for Windows,這種方式是利用了 Docker 的 Client/Server 架構,由 Windows 這邊負責 docker.sock,WSL2 中則是只有 Client 端,並利用 Windows 的 Docker Server 端進行通訊。
#### ⎚ Step1|安裝 Docker
因為我使用的 Ubunut 20.04 的 發行版本,所以它實際上已經有內建 `docker.io` 可以不用安裝了。
<br>
直接輸入 `docker` 指令,就會看到提示訊息建議我們到 Docker Desktop 設定 **WSL instegration**。
<p class="illustration">
<img src="https://i.imgur.com/wLnXIoo.png" alt="建議我們到 Docker Desktop 設定 WSL instegration">
</p>
<br>
不過,因為我要復現 QA 的操作,所以我還是把預載的 `docker.io` 給移除,重新按照[文件]( https://docs.docker.com/engine/install/ubuntu/)裝新版的 Docker。安裝好後,則是會直接看到 QA 反應的狀況:
<p class="illustration">
<img src="https://imgur.com/gKwlCVC.png" alt="Cannot connect to the Docker daemon at unix:///var/run/docker.sock">
</p>
基本上兩個問題都得去 Docker Desktop 做額外設定。
#### ⎚ Step2|在 Docker Desktop 設定 WSL instegration
因為我的環境中已經裝有 Docker Desktop,所以就不截圖安裝步驟了,有需要的可以看看[文件](https://docs.docker.com/desktop/install/windows-install/)的說明。印象中還挺簡單,至少...我沒有踩到奇怪的坑 XDDD
<br>
首先,開啟 Docker Desktop 上的 setting,並且在 General 中開啟 `Expose daemon on tcp://localhost:2375 without TLS`。
<p class="illustration">
<img src="https://imgur.com/Z9khlXF.png" alt="開啟 Expose daemon on tcp://localhost:2375 without TLS">
</p>
接下來回到 WSL2 中設定環境變數,為了讓每次打開 bash 時,此變數都會生效,所以我把它寫到 `~/.bashrc` 並更新:
```bash=
# 單次設定
$ export DOCKER_HOST=tcp://127.0.0.1:2375
# 寫入 bashrc 中,之後每次啟動都會被設定
$ echo DOCKER_HOST=127.0.0.1:2375 >> ~/.bashrc
$ source ~/.bashrc
```
再次執行 `docker run`。理論上這一步應該就可以了,因為同事說他做到這步就 OK,但....
<p class="illustration">
<img src="https://imgur.com/M7Kubev.png" alt="Cannot connect to the Docker daemon at tcp://127.0.0.1:2375">
</p>
<br>
我不得要領,只能先按照[論壇上](https://stackoverflow.com/questions/48047810/cannot-connect-to-the-docker-daemon-on-bash-on-ubuntu-windows)的解法一一試過去:
1. 檢查 `Use the WSL 2 based engine`:這個我有開沒問題。
2. 關 Hyper-V 重新啟動,再次開啟 Hyper-V 並重啟:也失敗,因為我不確定他的版本,所以虛擬機器平台的啟動我也來一次,但一樣失敗。
就在我還懷疑我是不是 export 下錯位置,想說難道它其實不是 WSL2 的指令而是 Windows 的時候(雖然不太可能),我在[某層回覆](https://stackoverflow.com/a/70502511/9661744)看到了線曙光,他標題大大寫著 ==DO NOT USER OTHER METHODS IN LATEST DOCKER DESKTOP==,並在內文提及了 **WSL Integration**。
難不成跟 Docker Desktop 的版號還有關?雖然不曉得發文者的版號是多少,但我很確定我的是最新的,因為我才剛被它拐騙更新而已。
<p class="illustration">
<img src="https://imgur.com/Y4UuIl3.png" alt="Docker Desktop 的版號">
</p>
<br>
我照著提示 `Settings > Resources > WSL Integration` 來到一個全新世界(誤)!在這我開啟了跟 Ubuntu 20.04 的連線,並重啟 Docker Desktop。
<p class="illustration">
<img src="https://i.imgur.com/pZdTTH9.png" alt="WSL Integration">
</p>
然後回到 WSL2 再次測試 `docker run` 指令,然後我就看到令人感動的結果啦~!開心的我立刻登入 Stack Overflow 幫他推一個,這個答案包含我才兩個人推而已 XDDD
<p class="illustration">
<img src="https://i.imgur.com/4KdNtUd.png" alt="docker run 成功執行">
</p>
對了,如果是新的 Docker Desktop,那麼 `Expose daemon on tcp://localhost:2375 without TLS` 不用開、環境變數也不用設定。
### 方法2|使用便捷腳本安裝 Docker
這是我在 [〈Does WSL2 docker need windows docker desktop?〉](https://superuser.com/questions/1583786/does-wsl2-docker-need-windows-docker-desktop) 這個提問中看到的,原本是想了解為何需要依賴 Windows 的 Docker Desktop,結果沒想到發現另外一個解法。
在之前安裝 [Docker 的文件](https://docs.docker.com/engine/install/ubuntu/)中有提到,安裝 Docker 有 repository、 package 跟 convenience script 3 種方法,習慣上我是使用 repository 來安裝的。不過它這邊用 convenience script 來安裝:
```bash=
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
$ sudo service docker start
```
測試 `docker run` 可以順利進行耶!
<br>
回到一開始的問題**為何需要依賴 Windows 的 Docker Desktop**?[Survey 得到結論](https://ithelp.ithome.com.tw/articles/10235035)是因為==有了 Linux Core 所以 Windows Docker Desktop 可以不需要,但跟 Windows 的整合就會差一點==。
## 參考資料
1. (2022-06-28)。[舊版 WSL 的手動安裝步驟](https://docs.microsoft.com/zh-tw/windows/wsl/install-manual)。檢自 Microsoft Docs (2022-07-19)。
2. (2022-06-28)。[Install Windows Subsystem for Linux (WSL) on Windows 10](https://docs.microsoft.com/en-us/windows/wsl/install)。檢自 Microsoft Docs (2022-07-19)。
3. (2021-02)。[wsl 2 是否需要启用 Hyper-V?](https://www.zhihu.com/question/439585675)。檢自 知乎 (2022-07-19)。
4. Les Lee (2019-04-26)。[在wsl-中安裝-docker](https://medium.com/一個小小工程師的隨手筆記/wsl-與-windows-的完美雙結合-在wsl-中安裝-docker-e722e87ffa3b)。檢自 一個小小工程師的隨手筆記|Medium (2022-07-19)。
5. sam-liaw (2020)。[WSL 安裝 Docker](https://hackmd.io/@sam-liaw/ByiB16T0S)。檢自 HackMD (2022-07-19)。
6. shreyansp (2021-12-28)。[Cannot connect to the Docker daemon on bash on Ubuntu windows](https://stackoverflow.com/a/70502511/9661744)。檢自 Stack Overflow (2022-07-19)。
7. kdm.J (2020-09-08)。[Does WSL2 docker need windows docker desktop?](https://superuser.com/questions/1583786/does-wsl2-docker-need-windows-docker-desktop)。檢自 Super User (2022-07-19)。
8. 我思故我在 (2020-09-08)。[5天-搞清楚為何 WSL2 需不需要 Windows Docker Desktop](https://ithelp.ithome.com.tw/articles/10235035)。檢自 iT 邦幫忙 (2022-07-19)。
## 更新紀錄
:::spoiler 最後更新日期:2022-07-20
- 2022-07-20 發布
- 2022-07-20 完稿
- 2022-07-18 起稿
:::
<br><br>
> **本文作者**: 辛西亞.Cynthia
> **本文連結**: [辛西亞的技能樹](https://cynthiachuang.github.io/Install-Docker-in-WSL2/) / [hackmd 版本](https://hackmd.io/@CynthiaChuang/Install-Docker-in-WSL2)
> **版權聲明**: 部落格中所有文章,均採用 [姓名標示-非商業性-相同方式分享 4.0 國際](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en) (CC BY-NC-SA 4.0) 許可協議。轉載請標明作者、連結與出處!