不使用 Docker Desktop 在 Windows(WSL)上安装 Docker

2025-05-24

不使用 Docker Desktop 在 Windows(WSL)上安装 Docker

更新于 2022 年 4 月 10 日,包含最新的 Alpine 使用说明、Debian/Ubuntu 软件包签名调整(不再使用 apt-key),以及在 Debian 中处理 iptables 的更佳指南。此外,还提供了有关 TCP 访问的更多建议。并进一步强调了/mnt/wsl/shared-docker套接字目录的可选性。

Windows Subsystem for Linux 2 搭载了真正的 Linux 内核,支持真正的 Linux 容器和 Docker。Docker 可以在 WSL 2 上运行,并且无需使用强大但笨重的 Docker Desktop(如果不想使用的话)。然而,由于 WSL 和 Docker 的复杂性,Docker 的启动和运行需要一些细心的维护。本文将尝试探索这一过程以及其中的各种选项。

与本文篇幅所暗示的相反,让 Docker 在 WSL 上运行起来相当简单。简而言之:

  • 不要使用诸如 systemd 之类的 init 系统来启动 Docker 守护进程,而是通过dockerd手动调用来启动它。
  • 如果希望在 WSL 实例之间共享 Docker 守护程序,请将其配置为使用存储在共享目录中的套接字/mnt/wsl
  • 如果需要不使用 sudo 的共享和特权访问,请将docker组配置为在所有 WSL 实例中具有相同的组 ID
  • 为了简单起见,不要启动基于 Windows 的 Docker 客户端,而是docker在 WSL 内部启动。

当然,下面还有更多细微差别和决策。滚动到底部查看配套 Github 仓库的详细信息。

您确定不想要 Docker Desktop 吗?

在继续之前,让我们先了解一下 Docker Desktop 的强大之处。如果您想让 Docker 在 Windows 和 WSL 2 上运行,安装 Docker Desktop可能是最佳选择。借助Docker Desktop 的 WSL 2 后端,Docker 可以相当优雅地与 Windows 集成,并且 Docker 客户端可以通过 Powershell 或 Linux 启动。了解 Docker Desktop 的底层原理也是一件既有趣又有益的事情。非常巧妙。

如果您来这里是为了寻找如何轻松运行 Docker,或者您想要开箱即用的 Windows 容器(仍然很少见),那么 Docker Desktop 就是您的好朋友,您现在就可以安装它

但是,如果你和我一样,觉得 Docker Desktop 增加的所有复杂性都是不必要的,你不需要 Windows 容器,或者你只是厌倦了系统托盘中那条“鲸鱼”耗时太长……那么,或许你应该dockerd在你选择的 WSL 发行版中运行 docker daemon(),这样就好了。你来对地方了。

请注意,Docker Desktop 仅对个人或小型公司免费。如果您将其用于工作,并且公司规模或收入超过一定水平,请考虑付费订阅。当然,如果您使用 Docker 时没有使用 Docker Desktop(如本文所述),则不适用此规定。点击此处,查看有关 Docker 订阅模式的更多详情

你尝试过 Podman 吗?

Podman

不过,在我们开始之前,先问一下:您知道Podman吗?Podman 无守护进程(无需后台服务)、现代(开箱即用的 cgroups v2)、支持无根 (rootless),并且可以作为 Docker 的直接替代品。无需担心套接字和端口,很多麻烦事就迎刃而解了。

我曾经写过关于如何在 WSL 2 上运行 Podman 的文章。欢迎尝试一下,或许你永远不会后悔。没错,VSCode 确实可以与 Podman 兼容。

然而……有时候,你只需要 Docker 就能工作。也许你使用的某些工具无法处理 Podman,或者你只是想测试一下 WSL 的性能。如果是这样,请继续阅读。

确保 WSL 是版本 2

请注意,这些步骤需要 WSL 2(而非 WSL 1)。WSL 2 使用支持 Linux 容器的实际 Linux 内核。WSL 1 在 Windows 内核上运行 Linux 方面非常出色,但当然缺少一些功能,例如容器。微软在文档中提供了更详细的比较

您肯定需要 WSL 2 来运行 Docker 服务。

该命令wsl --set-default-version 2有效吗?这会将默认版本设置为 WSL 2,如果您仍在使用第一个版本,则会失败。

微软提供了有关如何升级到 WSL 2 的分步说明

要运行 WSL 2,需要 Windows 1903 或更高版本,并运行 Build 18362 或更高版本。要查看您正在运行的版本,请winver在 Powershell 或 CMD 中运行,或者直接按下 Win 键和 R (⊞-r) 打开“运行”对话框,然后输入winver。希望您能看到类似“版本 21H2。操作系统版本 19044.1586”的内容。

安装 Linux 发行版

如果您尚未拥有所选发行版的 WSL 实例,下一步是从 Microsoft Store 中选择一个。如果您不喜欢 Windows Store,还有其他选择

对于 WSL 2 来说,自定义安装也是一个不错的选择。例如,安装并配置 Fedora或任何其他可以获取 tar 格式的 rootfs 的发行版,然后wsl --import rootfs.tar

本指南包含在DebianUbuntuAlpineFedora中启动 dockerd 的说明。如果您认为还有其他值得考虑的 WSL 发行版,请在评论中告诉我。

配置非root用户

安装您选择的发行版后,请启动它并设置非 root 用户(如果您尚未设置)。Debian 和 Ubuntu 会在首次启动时自动配置,如果您从商店安装 Alpine,Alpine 也应该如此。如果命令whoami返回“root”,则您需要添加一个非 root 用户。对于 Alpine 或 Fedora,请使用adduser myusername创建新用户。在 Alpine 上,这将提示您输入新密码。在 Fedora 上,您还需要passwd myusername并输入您想要使用的密码。(如果您的 Fedora 没有passwd,则需要先dnf install passwd cracklib-dicts)。

在 Microsoft Store 中下载的更高版本的 Alpine 中,虽然在安装过程中会创建一个非 root 用户,但该用户最初是没有密码的。您可以使用以下命令在任何发行版上进行仔细检查:



cat /etc/shadow | grep myusername | cut -d: -f2


Enter fullscreen mode Exit fullscreen mode

(如果您不是 root,则可能需要su先执行此操作)。

如果结果为“!”,则表示该用户未设置密码。如果结果是一个随机哈希字符串,则表示一切正常。如果需要设置密码,可以使用passwd myusername(当然,以上所有方法中,请使用您的用户名代替“myusername”)。

为非 root 用户配置管理员 (sudo) 访问权限

如果您使用的是 Windows 应用商店中的 Debian 或 Ubuntu,并在首次启动时设置了默认用户,那么 sudo 应该已经为默认用户配置好了。您可以跳过此步骤,继续下面的更新软件包和测试网络连接。

当以您设置的用户身份登录时(su myusername如果您仍然是 root 用户,请尝试),是否可以sudo -v不出现错误?

如果没有,请首先确保已安装 sudo。在 Alpine 上,sudo 为 ;apk add sudo在 Fedora 上, sudo 为dnf install sudo。如果由于网络连接失败,请参见下文。您可以按照那里的说明来更正 DNS,但当然,请删除这些命令中出现的sudo,因为您还没有安装,而且您仍然应该是 root 用户。

你的用户是“sudoer”吗?尝试以下操作,看看他们是否属于sudowheel组:



grep -E 'sudo|wheel' /etc/group


Enter fullscreen mode Exit fullscreen mode

在具有sudo组的发行版(例如 Ubuntu 和 Debian)上,您应该会看到类似的内容sudo:x:27:myusername;在具有wheel组的发行版(例如 Fedora 和 Alpine)上,您应该会看到类似的内容wheel:27:myusername

如果组中缺少您的用户名,请记下组名(sudowheel),并将相关用户添加到该组:

  • 高山:addgroup myusername wheel
  • Fedora:usermod -aG wheel myusername
  • 可能没有必要,但在 Ubuntu/Debian 上:usermod -aG sudo myusername

最后,以 root 身份确保管理员组(无论是sudo还是wheel)已启用 sudo:



grep -E '%sudo|%wheel' /etc/sudoers


Enter fullscreen mode Exit fullscreen mode

如果该行存在,但用 注释掉#,则运行visudo并确保该行内容如下(使用wheelsudo按照先前确定的方式):



%wheel ALL=(ALL) ALL


Enter fullscreen mode Exit fullscreen mode

然后保存。

完成这些步骤后,再次测试:



su myusername
sudo -v


Enter fullscreen mode Exit fullscreen mode

如果系统提示您输入密码,则一切正常。如果您收到类似“抱歉,用户 myusername 可能无法运行 sudo”的错误,则可能需要从头开始重新执行这些步骤。

设置默认用户

如果您从商店获取了 Linux 发行版,则可以跳过此步骤,因为默认用户已经设置好了。

但是,如果启动 WSL 时您仍然是 root 用户,则将新用户设置为默认用户。

假设您拥有 Windows 版本 18980 或更高版本:只需/etc/wsl.conf.

如果您还没有该文件或[user]其中的某个部分,那么类似这样的操作将会很有效:



printf "\n[user]\ndefault = myusername\n" | sudo tee -a /etc/wsl.conf


Enter fullscreen mode Exit fullscreen mode

但是,如果您使用的是 Windows 10 Build 18980 之前的版本,则需要编辑注册表来设置默认用户。执行此操作之前,我们需要两条信息:用户 ID 和 WSL 发行版名称。您可能已经知道这些信息。如果不知道,您可以使用以下命令获取用户 ID,id -u myusername并使用以下命令(在 Powershell 中)检查您的 WSL 发行版列表。wsl -l

然后,在 Powershell 中使用以下命令,但使用您的 WSL 发行版名称代替“Alpine”,并使用您的用户 ID 代替“1000”:



Get-ItemProperty Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\*\ DistributionName | Where-Object -Property DistributionName -eq Alpine  | Set-ItemProperty -Name DefaultUid -Value 1000


Enter fullscreen mode Exit fullscreen mode

无论使用哪种方法,请先退出 WSL 再重新登录进行测试。确认whoami用户名正确。成功。

更新/升级包并测试网络连接

让我们用以下方法之一让一切变得崭新而闪亮:

  • Debian/Ubuntu:sudo apt update && sudo apt upgrade
  • Fedora:sudo dnf upgrade
  • 高山:sudo apk upgrade -U

网络问题?

升级软件包也可以作为网络测试。由于各种原因, WSL 2可能会出现网络连接问题,根据我的经验,调整 DNS 设置通常可以解决这些问题。如果升级命令成功,您可以跳过此部分。但是,如果上述命令无法访问软件包服务器,则可能是您的网络、防火墙或反恶意软件存在问题。我建议执行以下操作:



echo -e "[network]\ngenerateResolvConf = false" | sudo tee -a /etc/wsl.conf
sudo unlink /etc/resolv.conf
echo nameserver 1.1.1.1 | sudo tee /etc/resolv.conf


Enter fullscreen mode Exit fullscreen mode

第一行告诉 WSL 停止自动配置该/etc/resolv.conf文件。然后我们删除/取消链接旧文件,并创建一个新文件。

使用这个新配置的 DNS 解析器(在本例中,它直接指向 Cloudflare 的 DNS 服务器),您可以再次尝试升级软件包。成功了吗?太棒了。

准备 Docker 安装

值得庆幸的是,目前已经有官方指南可以在各种 Linux 发行版上安装 Docker。我根据这些指南编写了以下说明,并根据实际测试经验进行了一些调整。

清除残留物

如果这不是全新安装,并且您可能之前已经尝试过 docker,那么请首先清除所有残留的 docker 安装:

  • Fedora:sudo dnf remove moby-engine docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
  • Debian/Ubuntu:sudo apt remove docker docker-engine docker.io containerd runc
  • Alpine(可能没有必要,但以防万一):sudo apk del docker-cli docker-ce docker-openrc docker-compose docker

安装依赖项

然后,安装先决条件:

  • Debian/Ubuntu:sudo apt install --no-install-recommends apt-transport-https ca-certificates curl gnupg2
  • Fedora:sudo dnf install dnf-plugins-core
  • Alpine:无需任何依赖项。依赖项稍后将自动安装。

Debian:切换到旧版 iptables

Docker利用 iptables 实现网络隔离。Debian使用了更现代的 nftables,但这意味着 Docker 无法自动调整 Linux 防火墙。因此,您可能希望将 Debian 配置为默认使用旧版 iptables:



update-alternatives --config iptables


Enter fullscreen mode Exit fullscreen mode

并选择iptables-legacy。

如果你更倾向于使用 nftables,并且想手动为 Docker 配置 nftables,那就去做吧。不过,我估计大多数人会想切换到旧版 iptables。

Debian/Ubuntu 软件包存储库配置

在 Debian 或 Ubuntu 上,首先临时设置一些特定于操作系统的变量:



. /etc/os-release


Enter fullscreen mode Exit fullscreen mode

然后,确保apt信任该 repo:



curl -fsSL https://download.docker.com/linux/${ID}/gpg | sudo tee /etc/apt/trusted.gpg.d/docker.asc


Enter fullscreen mode Exit fullscreen mode

ID将是“ubuntu”或“debian”,具体取决于 中的内容/etc/os-release

然后添加并更新 repo 信息,以便apt将来使用:



echo "deb [arch=amd64] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update


Enter fullscreen mode Exit fullscreen mode

Fedora 软件包存储库配置

在 Fedora 上,首先添加 Docker 的 repo:



sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo


Enter fullscreen mode Exit fullscreen mode

安装 Docker

现在我们可以安装官方的 Docker Engine 和客户端工具:

  • Debian/Ubuntu:sudo apt install docker-ce docker-ce-cli containerd.io
  • Fedora:sudo dnf install docker-ce docker-ce-cli containerd.io
  • Alpine(从 Edge 安装最新版本):sudo apk add docker --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community

将用户添加到docker

Docker 守护进程是 Docker 需要在后台运行的服务。服务 ( dockerd) 和客户端 ( docker) 通过套接字和/或网络端口进行通信。通过套接字进行通信需要特权访问权限。获取此访问权限有两种方法:

  • 以 root 身份运行docker(即sudo docker
  • 通过组成员身份,授予特定用户对 Docker 套接字的特权访问权限

换句话说,除非您sudo每次都想使用或 root 访问权限,否则请将您的用户添加到名为的 Docker 组docker

  • Fedora/Ubuntu/Debian:sudo usermod -aG docker $USER
  • 高山:sudo addgroup $USER docker

然后关闭该 WSL 窗口,并再次启动 WSL。docker运行命令groups列出组成员身份时,您应该会看到以下内容。

docker共享dockerd:为组选择一个通用的ID

如果您只打算使用一个 WSL 发行版,则下一步并非必需。但是,如果您希望在 WSL 发行版之间共享 Docker 套接字,则所有发行版都需要共享一个通用的组 ID docker。默认情况下,每个发行版可能都有不同的 ID,因此需要创建一个新的 ID。

首先,我们来选择一个。它可以是任何未被使用的组 ID。选择一个大于 1000小于 65534 的数字。要查看哪些已分配的组 ID 为 1000 或以上:



getent group | cut -d: -f3 | grep -E '^[0-9]{4}' | sort -g


Enter fullscreen mode Exit fullscreen mode

不知道该用哪个号码?我建议你用36257。(用电话键盘输入DOCKR就行……)这个号码可能还没被用过,不过还是查一下吧:



getent group | grep 36257 || echo "Yes, that ID is free"


Enter fullscreen mode Exit fullscreen mode

如果上述命令返回一行/etc/group(不包含docker),请选择另一个号码并重试。如果返回“是,该 ID 是免费的”,则您可以继续,并执行以下命令:



sudo sed -i -e 's/^\(docker:x\):[^:]\+/\1:36257/' /etc/group


Enter fullscreen mode Exit fullscreen mode

或者,如果groupmod可用(在 Fedora、Ubuntu 和 Debian 上有,但在 Alpine 上没有,除非你sudo apk add shadow),这样做更安全:



sudo groupmod -g 36257 docker


Enter fullscreen mode Exit fullscreen mode

一旦组 ID 更改,请关闭终端窗口并重新启动 WSL 发行版。

docker请注意,如果您想让其访​​问共享 Docker 套接字,则需要在您当前拥有的或将来安装的任何 WSL 发行版上运行涉及该组的上述步骤。

(可选)准备共享目录

与上一步一样,如果您只打算使用一个 WSL 发行版,则下一步并非必需。但是,如果您希望在 WSL 发行版之间共享 Docker 套接字,则需要一个所有人都可以访问的共享目录。

让我们首先为 docker 套接字创建一个共享目录,并设置权限以便 docker 组可以对其进行写入。



DOCKER_DIR=/mnt/wsl/shared-docker
mkdir -pm o=,ug=rwx "$DOCKER_DIR"
chgrp docker "$DOCKER_DIR"


Enter fullscreen mode Exit fullscreen mode

配置dockerd使用共享目录

同样,如果您选择不使用共享目录作为 Docker 套接字,则可以跳过此步骤。但是,您可能希望输入其他设置daemon.json,因此您可能需要熟悉此主题。

我建议使用配置文件/etc/docker/daemon.json来设置 dockerd 启动参数。如果该/etc/docker目录尚不存在,请使用 创建它,sudo mkdir /etc/docker/以便包含配置文件。然后,将以下内容放入 中/etc/docker/daemon.json,即可将 docker 主机设置为共享套接字:



{
  "hosts": ["unix:///mnt/wsl/shared-docker/docker.sock"]
}


Enter fullscreen mode Exit fullscreen mode

发射dockerd

大多数 Linux 发行版使用 systemd 或其他 init 系统,但 WSL 有自己的 init 系统。我们无需费力使用现有的 init 系统,而是dockerd直接启动:



sudo dockerd


Enter fullscreen mode Exit fullscreen mode

应该会出现几行信息、与 相关的警告等,最后cgroup blkio会显示类似 的内容。如果是这样,则表示您成功了。API listen on /mnt/wsl/shared-docker/docker.sock

打开另一个 wsl 终端。

当且仅当您选择使用/mnt/wsl/shared-docker如上所述的共享 docker 套接字时,首先设置DOCKER_HOST环境变量:



export DOCKER_HOST="unix:///mnt/wsl/shared-docker/docker.sock"


Enter fullscreen mode Exit fullscreen mode

然后,尝试一下 docker cli:



docker run --rm hello-world


Enter fullscreen mode Exit fullscreen mode

您应该会看到“Hello from Docker!”消息。

启动脚本dockerd

如果需要自动启动,可以将以下几行放在.bashrc或中.profile,也可以放在单独的 shell 脚本中。例如,您可能希望创建一个脚本,~/bin/docker-service以便docker-service仅在需要时手动运行。



DOCKER_DISTRO="Debian"
DOCKER_DIR=/mnt/wsl/shared-docker
DOCKER_SOCK="$DOCKER_DIR/docker.sock"
export DOCKER_HOST="unix://$DOCKER_SOCK"
if [ ! -S "$DOCKER_SOCK" ]; then
    mkdir -pm o=,ug=rwx "$DOCKER_DIR"
    chgrp docker "$DOCKER_DIR"
    /mnt/c/Windows/System32/wsl.exe -d $DOCKER_DISTRO sh -c "nohup sudo -b dockerd < /dev/null > $DOCKER_DIR/dockerd.log 2>&1"
fi


Enter fullscreen mode Exit fullscreen mode

如果您使用默认的 docker 套接字位置而/var/run/docker.sock不是上面详述的共享套接字目录/mnt/wsl/shared-docker,那么脚本可能如下所示:



DOCKER_DISTRO="Debian"
DOCKER_LOG_DIR=$HOME/docker_logs
mkdir -pm o=,ug=rwx "$DOCKER_LOG_DIR"
/mnt/c/Windows/System32/wsl.exe -d $DOCKER_DISTRO sh -c "nohup sudo -b dockerd < /dev/null > $DOCKER_LOG_DIR/dockerd.log 2>&1"


Enter fullscreen mode Exit fullscreen mode

当然,你可以选择任何你想要的位置来存放 docker 日志。它只需要位于一个有权限的地方,以便你的用户可以写入它。

请注意,DOCKER_DISTRO应将 设置为您想要运行的发行版dockerd。如果不确定名称,只需wsl -l -q从 Powershell 运行即可查看您的 WSL 发行版列表。选择正确的发行版并将其设置为DOCKER_DISTRO

上面的脚本执行以下操作:

  • 设置环境变量$DOCKER_HOST以指向共享套接字。这不是必需的,dockerd但它允许运行时docker无需-H unix:///mnt/wsl/shared-docker/docker.sock每次都指定。
  • 检查docker.sock文件是否已存在且为套接字。如果存在,则不执行任何操作。如果不存在,则脚本执行剩余步骤,如下所示。
  • 为套接字和dockerd日志创建共享的 docker 目录,并适当设置权限
  • dockerd 从指定的发行版运行。这很重要,因为它允许任何dockerd尚未运行的WSL 发行版启动。
  • 启动时dockerd,将其输出和错误传送到共享日志文件。
  • 启动后dockerd,它会在后台运行,因此您无需像之前那样专门打开一个终端窗口来处理该进程。该sudo -b标志提供了此功能,我们使用nohup它运行,使其独立于终端运行,并使用显式的空输入来nohup避免出现额外的警告。标准输出和错误都会写入日志文件,因此需要2>&1重定向。

无需密码即可启动dockerd

如果将上述脚本放置在.bashrc(大多数 Linux 发行版)或.profile(以 Ash/Dash 作为默认 shell 的 Alpine 等发行版)或其他 shell 初始化脚本中,则会产生一个不良的副作用:几乎每次启动新的终端窗口时,系统都可能会提示您输入密码。

要解决这个问题,您可以选择sudo授予 的无密码访问权限dockerd,只要用户是该docker组的成员即可。为此,请输入sudo visudo并添加以下行(如果您visudo使用vivim,则请务必按“ i”开始编辑,并在完成编辑后按 ESC 键):



%docker ALL=(ALL)  NOPASSWD: /usr/bin/dockerd


Enter fullscreen mode Exit fullscreen mode

保存并退出(:wq如果编辑器是vi,则按“ ”;如果是 ,则按 Ctrl-x nano),然后您可以测试它是否sudo dockerd提示输入密码。为了安心,您可以再检查一遍:类似 的操作sudo -k ls -a /root仍然需要密码,除非您最近输入过密码。

确保$DOCKER_HOST始终设置

如果之前使用脚本启动dockerd,那么$DOCKER_HOST将会被设置,并且将来的调用docker将不需要笨重的-H unix:///mnt/wsl/shared-docker/docker.sock

如果该脚本已存在于你的.bashrc或 中.profile,则无需执行以下步骤。但是,如果你以某种方式手动调用,并且你选择了共享的 docker 套接字目录,dockerd则可能需要在你的.bashrc或中使用以下内容:.profile



DOCKER_SOCK="/mnt/wsl/shared-docker/docker.sock"
test -S "$DOCKER_SOCK" && export DOCKER_HOST="unix://$DOCKER_SOCK"


Enter fullscreen mode Exit fullscreen mode

上述代码会检查是否存在 docker 套接字/mnt/wsl/shared-docker/docker.sock,如果存在,则$DOCKER_HOST相应地设置环境变量。如果您想要更通用的“如果这是 wsl,则主动设置套接字”,那么您可能更喜欢下面的代码,它只检查目录是否存在/mnt/wsl,如果存在,则设置 docker 套接字:



[ -d /mnt/wsl ] && export DOCKER_HOST="unix:///mnt/wsl/shared-docker/docker.sock"


Enter fullscreen mode Exit fullscreen mode

docker从 Windows运行

如果配置如上所述,我建议始终从 WSL 运行 docker。要运行容器吗?请从 WSL 窗口运行。(请参阅我关于使用 Windows 终端的文章,了解如何便捷地使用 WSL 和 Powershell。)

这不仅适用于终端。例如,VSCode 在 WSL 2 中支持 docker

但是,如果您想要在 Powershell 窗口中运行 docker 的便利性和实用性,我有几个建议。

一种是dockerd通过 TCP 端口公开,或者更好的方法是,在 WSL 中设置一个 SSH 服务器并以此方式连接。docker context这种方法可能会对你有帮助。这些方法将在后续文章中探讨,但我鼓励读者们去探索。提示:你试过scoop.sh吗?设置完成后,scoop install docker docker-compose它会提供一些你熟悉的工具,然后在 WSL 端提供一个 SSH 服务器,例如 Dropbear 或 OpenSSH……

我推荐一种简化的方法:一个 Powershell 函数,它调用 WSLdocker并传递任何参数。此函数可以放在你的 Powershell 配置文件中,通常位于~\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1



$DOCKER_DISTRO = "fedora"
function docker {
    wsl -d $DOCKER_DISTRO docker -H unix:///mnt/wsl/shared-docker/docker.sock @Args
}


Enter fullscreen mode Exit fullscreen mode

再次,wsl -l -q如果您不确定使用哪一个,请尝试查看 WSL 发行版列表。

确保 Docker 守护进程正在运行,然后启动一个新的 Powershell 窗口,并hello-world再次尝试该容器。成功了吗?

您也可以创建一个包含相应命令的批处理文件。例如,将其命名为docker.bat,然后将其放置在C:\Windows\system32或 中包含的其他位置%PATH%。以下内容可在这样的脚本中运行:



@echo off
set DOCKER_DISTRO=fedora
wsl -d %DOCKER_DISTRO% docker -H unix:///mnt/wsl/shared-docker/docker.sock %*


Enter fullscreen mode Exit fullscreen mode

您可以更进一步,确保dockerd每次启动 Powershell 时都在运行。假设dockerd上面详述的启动脚本保存在 WSL 中的一个文件中,并且$HOME/bin/docker-service是可执行文件(try chmod a+x $HOME/bin/docker-service),那么 Powershell 配置文件中的以下行将dockerd自动启动:



wsl -d $distro ~/bin/docker-service


Enter fullscreen mode Exit fullscreen mode

不确定你的 Powershell 配置文件在哪里?尝试$profile在 Powershell 窗口中输入。

如果您不想依赖特定的 WSL shell 脚本,您可以实现 Powershell 函数来启动 dockerd,例如:



function Docker-Service {
  Param ([string]$distro)
  $DOCKER_DIR = "/mnt/wsl/shared-docker"
  $DOCKER_SOCK = "$DOCKER_DIR/docker.sock"
  wsl -d "$distro" sh -c "[ -S '$DOCKER_SOCK' ]"
  if ($LASTEXITCODE) {
    wsl -d "$distro" sh -c "mkdir -pm o=,ug=rwx $DOCKER_DIR ; chgrp docker $DOCKER_DIR"
    wsl -d "$distro" sh -c "nohup sudo -b dockerd < /dev/null > $DOCKER_DIR/dockerd.log 2>&1"
  }
}


Enter fullscreen mode Exit fullscreen mode

此函数接受一个参数:发行版名称。

在上述所有内容中,原理都是相同的:您正在使用WSL 互操作性启动 Linux 可执行文件。

关于绑定挂载的说明:留在 Linux 文件系统上

使用 docker,可以将主机系统的目录或文件挂载到容器中。以下方法通常有效,但在从 Windows 启动 WSL docker 时不建议这样做:



echo "<h1>Hello, World</h1>" > index.html
docker run -p "8080:80" -v "$PWD:/usr/share/nginx/html:ro" nginx


Enter fullscreen mode Exit fullscreen mode

不要随意执行上述操作,从 Powershell 启动 WSL docker 时,有两条建议:

  1. 出于性能考虑,请仅在 Linux 文件系统内进行绑定挂载。要在 Powershell 中访问 Linux 目录,请尝试以下操作:cd (wsl wslpath -m ~/path/to/my/dir)
  2. 不要$PWD获取当前目录,尝试'$(wslpath -a .)'一下,是的,单引号有助于转义。

一个例子:



cd (wsl wslpath -m ~)
mkdir html
cd html
echo "<h1>Hello, World</h1>" > index.html
docker run -p "8080:80" -v '$(wslpath -a .):/usr/share/nginx/html:ro' nginx


Enter fullscreen mode Exit fullscreen mode

然后将浏览器指向http://localhost:8080,结果就完美了。(根据你的网络配置,你可能需要通过 http://[WSL IP Address]:8080 访问,可以使用ifconfig或 来获取ip addr

尝试wsl wslpath从 Powershell 或wslpathLinux 中查看选项。至少可以说,这是一个非常有用的工具。

示例脚本

完成本文中的步骤后,您现在应该拥有一个可以正常工作、可能自动启动dockerd、共享的 Docker 套接字以及方便配置的docker命令。

上面的一些代码示例已放在配套的 Github 仓库的脚本中。我总结了可用的文件如下:

  • docker-service.sh是一个 Unix shell 脚本,用于启动dockerd
  • docker-service.ps1dockerd包含一个可在 WSL 中启动的 Powershell 函数
  • docker.bat是一个 Windows 批处理文件,用于docker从 CMD启动 WSL
  • docker.ps1包含一个 Powershell 函数,用于docker从 Powershell 启动 WSL(如果放在你的配置文件中)

毫无疑问,可以通过一些方法进行调整,使其更加实用和可靠;欢迎在评论中发表意见。

有兴趣进一步了解 WSL 2 吗?

我在 WSL 上写的其他文章:

文章来源:https://dev.to/bowmanjd/install-docker-on-windows-wsl-without-docker-desktop-34m9
PREV
Why I Stopped Interviewing with Companies That Require a Coding Test
NEXT
清洁架构 为什么我不推荐 Robert C Martin 的清洁架构