Windows 容器开发环境搭建指南

容器技术本质上是 Linux-native 的,依赖 cgroups、namespaces、overlayfs 等内核特性,而 Windows 内核并不具备这些能力。因此所有在 Windows 上运行容器的方案,本质上都是在解决”如何在 Windows 上运行 Linux”这个问题。本文对比主流方案的优劣,并提供一套基于 WSL2 + Docker Engine 的稳定、免费、零授权风险的实践配置。

本文面向习惯命令行操作的 DevOps 工程师和开发者。如果你依赖 GUI 管理容器,Docker Desktop 或 Rancher Desktop 可能更适合你的使用习惯。


方案对比:Docker Desktop / Podman / Rancher Desktop

Docker Desktop —— 好用但有授权风险

Docker Desktop 内置 Linux VM、GUI、CLI、Compose,开箱即用,是过去几年的事实标准。但 2022 年 Docker 修改订阅条款后,员工数超过 250 人或年收入超过 1000 万美元的企业必须付费订阅。对于中大型公司,法务部门通常会直接封杀,存在合规风险。

收费的是 Docker Desktop 这个 GUI 应用,Docker Engine 本身仍是 Apache 2.0 开源免费,这个区别很重要。

Podman on Windows —— 理想丰满,现实骨感

Podman 的核心优势(Daemonless、Rootless、OCI 兼容、与 systemd 深度集成)在 Linux 上非常突出,但在 Windows 上需要通过 Podman Machine(QEMU/WSL2 VM)运行:

Windows 命令行

Podman CLI (Windows)

Podman Machine (QEMU/WSL2 VM)

Linux 内核

Container

这层 VM 抽象带来了一系列实际问题:Volume 挂载路径转换不稳定、Machine 启动偶尔卡死、rootless 在 VM 下端口绑定受限(<1024 失败)、Docker Compose 生态兼容性存在缺口。Podman 的主战场是 Linux,在 Windows 上使用需要接受这些 trade-off。

Rancher Desktop —— 看似全能,实则复杂

Rancher Desktop Apache 2.0 完全开源,SUSE 背书,支持 containerd/dockerd 切换。但实际使用中存在几个痛点:

  • 默认 CLI 是 nerdctl,虽语法基本兼容,但细节有差异
  • 镜像存储与 Docker 完全隔离,与其他工具链不互通
  • 同样运行 Linux VM(Lima),资源占用与 Docker Desktop 相当
  • 国内网络加速需要手动修改配置文件,没有简单 GUI 入口

对于习惯命令行的工程师,Rancher Desktop 的 GUI 价值有限,反而增加了一层复杂度。


推荐方案:WSL2 + Docker Engine

这是目前 Windows 上跑容器最干净、最稳定、零授权风险的方案。

架构原理

Windows Terminal / PowerShell

WSL2 (Linux 内核)

Docker Engine (dockerd)

Container

Docker Engine 直接运行在 WSL2 的 Linux 内核上,没有额外的 VM 抽象层,性能和稳定性接近原生 Linux。

方案对比总结

维度 Docker Desktop Podman Rancher Desktop WSL2 + Docker Engine
授权风险 大公司需付费 免费 免费 零风险
Windows 稳定性 一般
Docker 生态兼容 完整 需配置 需切换 完整
Compose 支持 原生 兼容层 兼容层 原生
资源占用
配置复杂度 中(一次性)
适合人群 通用 Linux 用户 GUI 需求者 DevOps / 命令行

完整配置步骤

Step 1:启用 WSL2

以管理员身份打开 PowerShell:

# 启用 WSL 和虚拟机平台
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

# 重启电脑后,设置 WSL 默认版本为 2
wsl --set-default-version 2

# 安装 Ubuntu(或 Kali,按需选择)
wsl --install -d Ubuntu-22.04

验证安装:

wsl --list --verbose
# NAME STATE VERSION
# Ubuntu-22.04 Running 2 ← 确认是 VERSION 2

Step 2:WSL2 资源限制(可选但推荐)

默认 WSL2 会吃掉大量内存,在 C:\Users\<你的用户名>\.wslconfig 创建配置文件:

[wsl2]
memory=4GB # 限制最大内存,根据你的机器调整
processors=4 # 限制 CPU 核心数
swap=2GB
localhostForwarding=true # 允许 Windows 通过 localhost 访问 WSL2 端口

修改后重启 WSL2:

wsl --shutdown
wsl

Step 3:在 WSL2 里安装 Docker Engine

进入 WSL2 终端:

# 卸载旧版本(如果有)
sudo apt remove docker docker-engine docker.io containerd runc 2>/dev/null

# 删掉损坏的 key 和源
sudo rm -f /etc/apt/keyrings/docker.gpg
sudo rm -f /etc/apt/sources.list.d/docker.list

# 安装依赖
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release

# 添加 Docker 官方 GPG 密钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 验证 key 是否正常
sudo gpg --dry-run --quiet --import --import-options import-show /etc/apt/keyrings/docker.gpg

# 添加 Docker 软件源
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 把当前用户加入 docker 组(避免每次 sudo)
sudo usermod -aG docker $USER
newgrp docker

# 启动 Docker
sudo service docker start

# 验证
docker run hello-world

让 Docker 随 WSL2 自动启动,在 ~/.bashrc~/.zshrc 末尾添加:

# Auto-start Docker daemon in WSL2
if [ "$(service docker status 2>&1 | grep -c 'not running')" -eq 1 ]; then
sudo service docker start > /dev/null 2>&1
fi

Step 4:配置代理(国内使用关键一步)

WSL2 有自己的网络栈,不会自动继承 Windows 的代理设置。

找到 Windows 宿主机的 IP(WSL2 网关):

# 方法一
cat /etc/resolv.conf | grep nameserver | awk '{print $2}'

# 方法二
ip route | grep default | awk '{print $3}'

# 通常输出类似 172.x.x.1

~/.bashrc~/.zshrc 里添加代理配置:

# WSL2 Proxy Configuration
WINDOWS_HOST=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
PROXY_PORT=7890 # 替换成你的代理端口

export http_proxy="http://${WINDOWS_HOST}:${PROXY_PORT}"
export https_proxy="http://${WINDOWS_HOST}:${PROXY_PORT}"
export no_proxy="localhost,127.0.0.1,::1"

# Git 代理
git config --global http.proxy "http://${WINDOWS_HOST}:${PROXY_PORT}"
git config --global https.proxy "http://${WINDOWS_HOST}:${PROXY_PORT}"

给 Docker Daemon 单独配置代理(docker pull 走 daemon,不走 shell 环境变量):

sudo mkdir -p /etc/systemd/system/docker.service.d

cat > /etc/systemd/system/docker.service.d/proxy.conf << 'EOF'
[Service]
Environment="HTTP_PROXY=http://<WSL2_GATEWAY_IP>:<PROXY_PORT>"
Environment="HTTPS_PROXY=http://<WSL2_GATEWAY_IP>:<PROXY_PORT>"
Environment="NO_PROXY=localhost,127.0.0.1"
EOF

# WSL2 里没有 systemd,用 service 重启
sudo service docker restart

<WSL2_GATEWAY_IP> 替换为上一步获取到的 WSL2 网关 IP,<PROXY_PORT> 替换为你的代理工具实际端口。

WSL2 里三套代理互不相干,都要单独配:

作用域 配置方式 用途
Shell export http_proxy=... curl / wget / git
apt /etc/apt/apt.conf.d/proxy.conf apt install
Docker daemon /etc/systemd/system/docker.service.d/proxy.conf docker pull

apt 代理配置示例:

cat > /etc/apt/apt.conf.d/proxy.conf << 'EOF'
Acquire::http::Proxy "http://<WSL2_GATEWAY_IP>:<PROXY_PORT>";
Acquire::https::Proxy "http://<WSL2_GATEWAY_IP>:<PROXY_PORT>";
EOF

Git 精准代理(只代理 GitHub,国内仓库不受影响):

git config --global http.https://github.com.proxy http://<WSL2_GATEWAY_IP>:<PROXY_PORT>

Step 5:配置镜像加速(代理 Fallback)

如果代理不稳定,配置镜像加速作为备用:

sudo tee /etc/docker/daemon.json > /dev/null <<EOF
{
"registry-mirrors": [
"https://docker.1panel.live",
"https://hub.rat.dev",
"https://dockerpull.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOF

sudo service docker restart
docker info | grep -A5 "Registry Mirrors"

Step 6:配置 VSCode Remote WSL

安装 VSCode 插件:

  • ms-vscode-remote.remote-wsl
  • ms-vscode-remote.vscode-remote-extensionpack

使用方式:

# 在 WSL2 终端里直接打开项目
cd ~/projects/my-app
code . # VSCode 自动以 Remote WSL 模式打开

VSCode 在 Remote WSL 模式下,终端、文件系统、Git、调试器全部运行在 Linux 环境里,体验和本地 Linux 开发一致。


可选:Portainer —— 需要 GUI 时的选择

如果偶尔需要可视化管理容器和镜像,可以部署 Portainer:

docker volume create portainer_data

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

浏览器打开 http://localhost:9000,即可获得完整的容器、镜像、Volume、网络管理界面。


最终工作流

配置完成后,日常使用:

# 打开 Windows Terminal,切换到 WSL2
# 或直接在 VSCode Remote WSL 终端里操作

# 拉镜像
docker pull postgres:16-alpine

# 跑服务
docker compose up -d

# 看日志
docker compose logs -f app

# 清理
docker system prune -af

体验和纯 Linux 环境操作没有本质区别。


写在最后

Windows 上做容器开发,核心矛盾是 Windows 环境与 Linux-native 技术栈之间的阻抗失配。各种工具本质上都是在填这个坑:

  • Docker Desktop:填得最好,但要钱
  • Podman / Rancher Desktop:免费,但填得不够平整
  • WSL2 + Docker Engine:绕过这个坑,直接在 Linux 里跑

对于习惯命令行的工程师,GUI 是可选项而非必选项。这套方案一次配置,长期受益,没有授权风险,没有额外的抽象层,就是在 Windows 上搭了一个干净的 Linux 容器环境。