The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何移除 Docker Desktop 並在 Windows 與 WSL 2 改安裝 Docker Engine

今天我的 Docker Desktop for Windows 又掛掉了,五年來的第三次,毫無原因,導致我所有容器、所有 Image 全部都被清空。這次真的氣到,不用了,決定把 Docker 全部都移往 WSL 2 執行,聽幾個可靠的朋友說,讓 Docker Engine 跑在原生的 WSL 2 底下,不但速度快,服務也穩定許多。所以這篇文章,我要來記錄一下完整的設定過程。

image

1. 完整移除 Docker Desktop for Windows

首先,你必須從 Windows 的控制台移除 Docker Desktop 程式。

然後,你要登入 WSL 2 移除以下兩個符號連結檔案 (Symbolic Link File):

rm -f ~/.docker/contexts ~/.docker/features.json

接著,從 WSL 2 刪除所有 cli-plugins 檔案:

sudo rm /usr/local/lib/docker/cli-plugins/docker-*

最後,在 Windows 重啟 WSL 服務!

wsl.exe --shutdown

然後確認 WSL 核心是最新版本:

wsl --version
wsl --update
wsl --version

2. 在 WSL 2 安裝 Docker / Docker Compose v2

# 下載安裝腳本
# https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script
curl -fsSL https://get.docker.com -o get-docker.sh

# 執行安裝命令,過程會提示你要安裝 Docker Desktop
# 但我們就是不爽才改裝到 WSL 這裡的,請不要理會這些訊息,等十秒就會自動開始安裝
sudo sh get-docker.sh

# 把你個人的帳號加入到 docker 群組
# Manage Docker as a non-root user
# https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user
sudo usermod -aG docker $USER

# 檢查已安裝版本
docker --version
docker compose version

3. 透過 WSL 2 的 systemd 服務啟動 Docker Engine

要在 WSL 2 啟動 Docker Engine 有兩種方式:

  1. 登入帳號時才啟動引擎

    把以下這段命令加入到 ~/.profile 檔案即可:

    if grep -q "\-WSL2" /proc/version > /dev/null 2>&1; then
        if service docker status 2>&1 | grep -q "is not running"; then
            wsl.exe --distribution "${WSL_DISTRO_NAME}" --user root \
                --exec /usr/sbin/service docker start > /dev/null 2>&1
        fi
    fi
    

    💡 如果你想透過 systemd 啟動 Docker Engine 的話,這段命令是不需要設定的!

  2. 透過 systemd 服務啟動 Docker Engine

    總之,就是隨著電腦一起啟動 WSL 2 中的背景服務。詳見: Systemd support is now available in WSL!

    我不太確定 systemd 目前是否是自動會啟用,但你依然可以檢查一下 /etc/wsl.conf 這個設定檔:

    [boot]
    systemd=true
    

    你可以透過以下命令查找是否有個 docker.service 服務:

    systemctl list-unit-files --type=service
    

    查看 docker.service 的狀態:

    systemctl status docker.service
    

4. 讓 dockerd 同時聽 Unix socket file 與 TCP 連線

我主要是希望跑在 WSL 2 的 Docker Engine 同時也可以讓 Windows 原生環境下也能直接使用,而且也想讓開在 Windows 的 Visual Studio Code 也能直接連到 Docker Engine 進行管理!

以下命令請在 WSL 2 環境中執行:

# 1. 讓 dockerd 同時聽 Unix 與 TCP
sudo tee /etc/docker/daemon.json <<'EOF'
{
  "hosts": [
    "unix:///var/run/docker.sock",
    "tcp://127.0.0.1:2375"
  ]
}
EOF

# 2. 新增或編輯 systemd 背景服務設定 (docker.service)
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/override.conf <<'EOF'
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
EOF

# 3. 套用變更
sudo systemctl daemon-reload
sudo systemctl restart docker

# 4. 驗證
# 看到 LISTEN 狀態代表成功
ss -lntp | grep 2375

💡 我們在 /etc/docker/daemon.json 檔案中加入 tcp://0.0.0.0:2375tcp://127.0.0.1:2375 之後,你就可以從 Windows 直接透過 localhost:2375 就可以連上 WSL 2 環境下的 Docker Engine!

5. 讓 Windows 命令提示字元下也能使用 docker 命令

我使用 Chocolatey 安裝 Docker CLIDocker Compose V2 命令列工具:

choco install docker-cli docker-compose -y

安裝好之後,還要設定一個 DOCKER_HOST 環境變數,你可以設定到控制台中,也可以直接用以下命令設定:

  • PowerShell

    $env:DOCKER_HOST='localhost:2375'
    
    
  • Command Prompt

    set DOCKER_HOST=localhost:2375
    

最後我們查詢一下 CLI 工具版本,也順便查詢 Docker Engine 版本:

docker compose version

docker version

💡 注意:如果 docker verison 有顯示連不上,出現以下錯誤訊息:

error during connect: Get "http://localhost:2375/v1.50/version": dial tcp [::1]:2375: connectex: No connection could be made because the target machine actively refused it.

那就有可能是你的 WSL 2 目前是停止狀態,啟動 WSL 2 之後 systemd 會一併把 docker.service 啟動,只是時間可能會花上 10 ~ 20 秒左右。

如果都可以成功連上的話,就可以測試跑跑看一個簡單容器:

docker run --rm -it hello-world

然後可以進階一點,直接把 SQL Server 2022 執行起來:

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=P@ssw0rd1234' -p 1433:1433 -d --name=sqlserver mcr.microsoft.com/mssql/server:2022-latest

接著你就可以用 sqlcmdSqlPackageSSMS 來連接容器中的 SQL Server:

# 建議不要用 localhost 連線,改用 127.0.0.1 才是比較可靠的方法,因為 localhost 有可能被解析成 IPv6 位址!
sqlcmd -H 127.0.0.1 -U sa -P P@ssw0rd1234 -Q "SELECT database_id FROM sys.databases"

或者是直接把 Portainer 裝起來,直接取代 Docker Desktop 的 UI 介面:

docker volume create portainer_data
docker run -d -p 8000:8000 -p 9000:9000 -p 9443:9443 --name portainer \
        --restart=always \
        -v /var/run/docker.sock:/var/run/docker.sock \
        -v portainer_data:/data \
        portainer/portainer-ce:latest

💡 透過 http://localhost:9000/ 就可以連上管理介面!

6. 讓 VS Code 的 Container Tools 也能管理 Docker Engine

怕有人不知道,所先聲明一下,微軟近期將他們做的 Docker 擴充套件,更名為 Container Tools

直接在 VS Code 使用者設定中,加入以下設定即可:

{
  "containers.environment": {
      "DOCKER_HOST": "tcp://localhost:2375"
  }
}

7. 直接從 WSL 啟動 VS Code Server

其實在多年前開始,WSLVS Code 早就已經無縫整合在一起,只要你 Windows 下的 VS Code 有安裝 Remote Development 擴充套件,你直接在 WSL 的 Terminal 下執行 code . 就可以將目前資料夾開在 Windows 本機環境的 VS Code 之中,過程中會自動下載 VS Code Server 在你的 WSL 2 環境中,然後可以直接「遠端開發」,非常厲害!

詳細文件請參考 Remote Development with Linux

下載 Remote Development 擴充套件也會連同安裝以下這幾個擴充套件,全部都是遠端開發的威力套件:

相關連結

留言評論