将Docker for Windows和WSL设置为完美工作

2020-07-15 02:26:56

通过几个调整,WSL(Windows Subsystem for Linux,也称为Bash for Windows)可以与Docker for Windows一起使用。

2020年更新:既然微软已经发布了2020年春季Windows更新,我们就可以在所有版本的Windows 10上访问WSL 2了。我已经录制了一段视频,展示了我如何将Docker Desktop与WSL 2以及我使用的其他工具一起使用。

我已经决定保持这篇文章不变,并且完全适用于WSL1,以防你想继续使用它。只要知道我已经转到使用WSL2,并且下面的步骤都不是使用WSL2所必需的。

本文要求您已经设置好WSL。如果您没有,我还有另一篇文章介绍了如何在Windows中设置一个令人惊叹的基于WSL的开发环境。您甚至可以运行图形应用程序,而且不需要虚拟机。

虽然Docker守护进程不能直接在WSL上运行,但您可以使用Docker CLI连接到通过Docker for Windows或您创建的任何其他VM运行的远程Docker守护进程(本文包括这两种方法)。

如果您想知道“为什么不直接在WSL中从Docker for Windows运行docker.exe和docker-compose.exe呢?”,这是因为在该环境中交互运行Docker或Docker Compose.exe时出现了错误。TL;DR是在交互模式下不能在前台运行任何东西,这使得它不能用于真正的Web开发。

但是,将Docker CLI配置到远程Docker for Windows主机后,这真是太棒了!使用这种方法,超大型Rails应用程序的响应时间约为100ms(如果必须编译10,000多行Javascript和SCSS,则响应时间约为5秒)。挂载卷也是如此!

对于Rails、Flask、Phoenix、Node和webpack驱动的应用程序,我几乎每天都使用这个设置。它在性能和可靠性方面都非常可靠。

Docker for Windows最近已更名为Docker Desktop,因此,如果您的设置看起来与屏幕截图略有不同,也不用担心。这是一回事。

它提到“谨慎使用”,因为每当您建立未加密的网络连接时,都值得一谈,但在这种情况下,它是完全安全的,因为我们永远不会通过公共网络连接到它。

这将允许您的本地WSL实例本地连接到在Docker for Windows中运行的Docker守护进程。流量甚至没有离开您的dev箱,因为守护进程仅绑定到localhost,因此即使是您的本地网络上的其他计算机也无法连接。换句话说,通过纯文本传输此数据非常安全。

您可能还想共享您计划让源代码驻留的任何驱动器。这一步不是必需的,但我将代码保存在内部辅助硬盘上,所以我也共享了我的“E”盘。如果这样做,请转到“共享驱动器”设置并启用它。

您需要设置自己的VM来运行Docker。Docker Tip#73详细介绍了如何做到这一点,甚至还包含了有关如何配置虚拟机的视频链接。

我们仍然需要在WSL中安装Docker和Docker Compose,因为它可以让我们访问这两个CLI应用程序。我们不会费心启动Docker守护进程。

以下说明适用于Ubuntu18.04,但是如果您碰巧使用了不同的WSL发行版,您可以从Docker的安装文档中按照Docker针对您的发行版的安装指南进行操作。

#更新APT包列表。sudo apt-get update-y#安装Docker的软件包依赖项。SUDO APT-GET INSTALL-y\APT-TRANSPORT-HTTPS\CA-CERTIFICATES\cURL\SOFTWARE-PROPERTIES-COMMON#下载并添加docker的官方公共PGP密钥。curl-fsSL https://download.docker.com/linux/ubuntu/gpg|sudo apt-key add-#验证指纹。SUDO APT-KEY指纹0EBFCD88#添加`stable`频道的Docker上游仓库。##如果您想生活在边缘,您可以将下面的";稳定&34;更改为";测试&34;或##34;夜间&34;。我强烈推荐坚持使用马厩!sudo add-apt-pository\";deb[Arc=amd64]https://download.docker.com/linux/ubuntu\$(lsb_release-cs)\STRATE";#更新APT包列表(用于新的APT存储库)。sudo apt-get update-y#安装最新版本的Docker CE。sudo apt-get install-y docker-ce#允许您的用户无需root访问即可访问Docker CLI。SUDO usermod-AG docker$user

此时,您必须关闭您的终端并打开一个新的终端,这样您就可以在没有sudo的情况下运行Docker。你最好现在就做!

我们打算在GitHub上使用PIP而不是预编译的二进制文件安装Docker Compose,因为它的运行速度要快一点(两者仍然是Python应用程序)。

#安装Python 3和PIP。sudo apt-get install-y python3 python3-pip#将Docker Compose安装到用户的主目录中。Pip3 install--user docker-compose。

您可以通过运行ECHO$PATH来检查它是否已经设置。根据您使用的WSL发行版的不同,您可能会看到/home/nick/.local/bin(用您的用户名替换nick),也可能看不到/home/nick/.local/bin。

如果它在那里,你就可以开始了,可以跳到这篇文章的下一节。

如果它不在那里,您会希望将其添加到$PATH中。您可以通过使用Nano~/.profile打开您的配置文件来做到这一点。然后,在文件中的任何位置的新行上,添加export path=";$path:$HOME/.local/bin";并保存文件。

最后,运行source~/.profile以激活新的$PATH,并通过运行ECHO$PATH确认它是否正常工作。你现在应该看到了。搞定了!

下一步是配置WSL,以便它知道如何连接到在Docker for Windows中运行的远程Docker守护进程(请记住,它正在侦听端口2375)。

如果您没有使用Docker for Windows,而是按照Docker Tip#73的指南创建您自己的VM,那么您可能已经这样做了,这意味着您可以跳过下面的命令。

这只是将导出行添加到您的.bashrc文件中,以便您每次打开终端时都可以使用它。source命令重新加载您的bash配置,因此您不必立即打开新的终端即可使其生效。

#你应该会得到一堆关于你的Docker守护进程的输出。#如果出现权限被拒绝错误,请关闭+打开您的终端,然后重试。Docker info#您应该拿回您的Docker撰写版本。Docker-Compose--版本。

我们需要做的最后一件事是进行设置,以便卷装载正常工作。这让我绊倒了一段时间,因为看看这个,…。

使用WSL时,Docker for Windows要求您以与以下格式匹配的格式提供卷路径:/c/Users/Nick/dev/myapp。

但是,WSL不是那样工作的。相反,它使用/mnt/c/users/nick/dev/myapp格式。老实说,我认为Docker应该更改他们使用/mnt/c的路径,因为它更清楚发生了什么,但这是另一次讨论的问题。

现在要让事情运转起来,你有两个选择。如果您运行的是Windows18.03(2018年春季)或更高版本,您可以将WSL配置为挂载到/而不是/mnt,这样就完成了。如果你跑的是17.09(2017年秋季),你需要做一些其他的事情。

sudo Nano/etc/wsl.conf#现在使它看起来像这样,完成后保存文件:[auto ount]root=/options=";METADATA";

我们需要设置root=/,因为这将使您的驱动器挂载在/c或/e,而不是/mnt/c或/mnt/e。

选项=#34;METADATA&34;行不是必需的,但它将修复WSL挂载上的文件夹和文件权限,因此WSL挂载中的所有内容不会一直都是777。我强烈建议你这样做!

进行这些更改后,请注销并重新登录到Windows以确保更改生效。Win+L是不够的。您需要做一个全面的登出/登入。

如果下次启动WSL终端时出现错误,不要惊慌失措。

这是一个18.03版本的错误,您可以很容易地修复它。点击CTRL+SHIFT+ECS打开任务管理器,进入“服务”选项卡,找到“LxssManager”服务并重新启动。

这似乎只有在您注销Windows而不是完全重新启动时才会发生,并且可能会在未来的18.03+补丁中修复。

一旦做完了,你就都准备好了。您将能够访问您的坐骑,他们将完美地与Docker和Docker组合,没有任何额外的调整。例如,您将能够在docker-compose.yml文件中使用.:/myapp,等等。

如果您使用的是ConEmu,那么您需要确保升级到最新的alpha版本(至少18.05.06+,您可以在设置的标题栏中看到)。它包含一个打了补丁的wslbridge ge.exe文件,以支持自定义WSL根挂载点。

默认的Ubuntu WSL终端默认支持此功能,所以一切都很好。我不知道其他终端是否支持这一功能。请在评论中让我知道。

您需要对共享的任何驱动器(如d或e等)重复这些命令。

通过运行:ls-la/c验证它是否正常工作。您应该会看到与运行ls-la/mnt/c完全相同的输出,因为/mnt/c已挂载到/c。

在这一点上,你是黄金。您可以在Docker合成文件中使用.:/myapp这样的卷挂载路径,一切都会正常工作。这太棒了,因为Linux和MacOS原生用户也会使用这种格式。

值得注意的是,无论何时运行docker-compose up,您都需要确保首先导航到/c/users/nick/dev/myapp位置,否则您的卷将无法工作。换句话说,永远不要直接访问/mnt/c。

从技术上讲,您可以使用符号链接而不是绑定挂载,但在过去,当涉及到使用符号链接和某些工具无法工作时,我感到很恼火,因为它们没有正确遵循它们。在这里安全总比后悔好。

但是,您可以在WSL中使用符号链接来访问BIND挂载。例如,我的dev文件夹一直位于/e/backup/vms/workstation/home/nick/dev中,当我想要访问我的开发文件时,无论如何我都不可能总是键入它。

因此,在WSL中,我使用ln-s/e/backup/vms/workstation/home/nick/dev~/dev创建了一个符号链接,现在我只需输入cd~/dev即可访问我的文件,一切都正常。

不幸的是,每次打开新终端时都必须运行sudo mount命令,因为WSL还不支持通过/etc/fstab挂载(编辑:在18.09+中支持挂载,但如果您使用的是18.09+,则应该遵循18.03+步骤)。

但是我们可以通过将其挂载到您的~/.bashrc文件中来解决该限制。这有点脏,但据我所知,我认为这是唯一的办法,所以如果你知道更好的办法,请告诉我。

您可以使用以下1行代码执行此操作:echo";sudo mount--bind/mnt/c/c";>;>;~/.bashrc&;&;source~/.bashrc,并确保对与Docker for Windows共享的任何其他驱动器重复该命令。顺便说一下,你不需要mkdir,因为我们已经做过了。

是的,我知道,这意味着每次你打开终端时都会提示你输入根密码,但我们也可以绕过这一点,因为Linux就是那样酷。

这应该会打开Nano(一种文本编辑器)的大门。转到文件的底部并添加下面一行:nick all=(Root)NOPASSWD:/bin/mount,但是用您的用户名替换“nick”。

这只允许您的用户执行sudo mount命令,而不必提供密码。您可以使用CTRL+O保存文件,使用CTRL+X确认并退出。

任务完成。通过使用Docker for Windows和WSL,您已经做好了赢得生活的一切准备。