在Windows上开发Docker应用程序:使用WSL、Visual Studio Code和Docker Desktop

654 阅读15分钟

简介

Windows Subsystem for Linux 2(WSL 2或简称WSL)的出现简化了Windows上基于Linux的开发。WSL 2允许与Docker Desktop直接集成,并具有使用Visual Studio Code直接开发的插件。

在本教程中,你将使用Visual Studio Code、WSL和Docker Desktop在Windows上建立一个开发环境。你将在Docker中构建一个PythonFlask网络服务,以展示这些工具的开发功能。

前提条件

为了跟上本指南,你将需要:

  • 安装了Windows 10和WSL 2的个人电脑。你要确保WSL的安装正确,并且将Ubuntu 20.04安装到WSL中。你可以按照教程《如何在微软Windows 10上安装Windows Subsystem for Linux 2》来设置。

  • 安装了VSCode。你可以从其官方网站下载并安装VSCode。你不需要担心安装插件的问题。所需的插件将在本教程中讨论。

第1步 - 安装Docker桌面和连接到WSL

Docker是开发人员用来部署应用程序的常用开发工具。Docker Desktop的优点是也能运行并与你的WSL Linux环境集成。

通过从Docker网站下载Docker Desktop并点击Get Docker按钮开始下载来设置Docker。

Go to Docker's website and download Docker Desktop

一旦你下载了可执行文件,就运行它,让它进行修改。

Run the executable and let Docker make changes

在安装过程中,确保为WSL 2安装所需的Windows组件被选中。你是否需要一个桌面图标由你决定。

Make sure that "Install required Windows components for WSL 2" is checked

安装过程结束后,系统会提示你退出并重新登录,以使你的更改生效。点击关闭按钮,然后确保注销并重新登录,这样更改才会生效。

Once Docker is done installing you'll need to logout and log back in for changes to take effect

重新登录并从开始菜单中启动Docker Desktop。

Launch Docker Desktop from the start menu

**警告。**当你第一次启动Docker时,它会提示你有一个Docker教程。

Docker Tutorial Launched

如果你对Docker不熟悉,可能值得你花时间去做Docker教程,但这不是当前教程的必要条件。一旦你完成了该教程或跳过了它,继续。

Docker仪表板会出现。这里会出现任何正在运行的容器,以及Docker的设置和状态。如果你看到左下角的标志是绿色的,这意味着Docker正在运行。如果它是黄色的,那么Docker Desktop仍然在启动;给它一分钟左右的时间来完成。如果指示灯是红色的,那么Docker就无法启动。

The Docker dashboard will open. If the logo in the bottom left is green it means Docker is running

接下来你需要将Docker暴露给WSL,这样你就可以在Ubuntu环境中运行Docker。点击右上角的齿轮图标,打开设置。在那里,你将点击资源标签,然后点击WSL集成。你会看到你的Ubuntu环境在那里,但已经被关掉了,还有你可能已经安装的其他WSL环境。

Go to Settings, select Resources, and select WSL Integration. You'll see your WSL Ubuntu there, not selected

在你的Ubuntu环境中启用Docker,点击滑块将其打开,然后点击应用和重启。一旦重启完成,你的Ubuntu环境就可以访问Docker了。

Select your WSL Ubuntu and click Apply & Restart

现在你可以测试你的Docker与WSL的连接。在你启用Docker的操作系统上打开一个终端,在本例中是Ubuntu,然后运行Docker hello world命令。

docker run hello-world

你的Ubuntu环境应该下载和运行hello world容器并显示其输出。

Test Docker by running Docker run hello-world in your WSL Ubuntu

现在你已经将Docker连接到了WSL,你将学习如何在WSL中直接使用Visual Studio Code和远程开发扩展进行开发。

第2步 - 使用Visual Studio Code的远程扩展在WSL中开发

你可以将你的WSL Ubuntu环境与你的Visual Studio Code(以下简称VSCode)结合起来,以便能够直接在Linux环境下进行开发。

首先,打开VSCode。转到窗口左侧的扩展标签。搜索Remote - WSL,会出现Remote - WSL扩展。点击它,然后点击安装来安装它。

Open VSCode, go to Extensions and search for Remote. Install the Remote - WSL Extension

安装完成后,按CTRL + Shift + P ,打开VSCode命令对话框。输入Remote-WSL,你会看到有几个选项出现。你可以打开一个新的WSL环境,打开一个现有的文件夹,等等。选择Remote**-WSL:新的WSL窗口**。这将打开一个连接到Ubuntu WSL环境的新VSCode窗口。

Press CTRL + Shift + P to open the VSCode command dialog and type Remote. You'll see WSL there. Select Remote-WSL: New WSL Window

现在你在这个新窗口中,你可以按CTRL + Shift + ` ,或者通过点击导航栏中的终端->新终端来打开一个新的终端,你就会被放入WSL终端中。你所创建的任何文件也将被存储在WSL文件系统中。

If you open a new terminal you'll open your Ubuntu terminal and be able to develop using VSCode directly in the WSL

现在你已经建立了你的开发环境,你将使用Flask框架建立一个Python微服务,创建一个301重定向到你指定的环境变量的网站,并将其打包在一个Docker容器中。

第3步 - 设置你的开发环境

首先,你要设置一个开发环境,以便你可以使用Visual Studio Code开发你的代码。导航到左手边的侧边栏,点击最上面的图标,看起来像一张纸。你会被提示选择打开一个文件夹克隆一个资源库

File explorer dialog box open

从这里选择打开一个文件夹。默认位置将是你的主目录。选择这个选项并点击确定

Open home directory

Visual Studio Code可能会提示你,你是否信任这个文件夹的作者。这是一种安全措施,以确保没有自动执行的代码可以伤害你的电脑。在这种情况下,一切都很好,所以选择是,我信任作者

Author Trust Dialog box

现在你应该在左边的文件资源管理器面板上看到你的主目录。接下来,创建一个目录来存储你的项目。导航到带有加号的文件夹图标。当你把鼠标悬停在这个图标上时,应该会出现一个弹出窗口,上面写着 "新文件夹"。点击这个图标,创建一个新的文件夹,并命名为_my-app_。一个新的空目录应该出现在右边的资源管理器中。

New Folder Icon
现在你已经建立了你的开发者环境,准备在下一步建立你的Python微服务。

第4步 - 为你的项目创建一个Python虚拟环境

在你开始编码之前,你需要建立你的Python开发环境。在这一步中,你将在一个虚拟环境中安装和激活你的Python需求,以方便管理。

你可以在 Visual Studio Code 的终端中完成所有这些工作。按CTRL + Shift + ` 组合键来打开一个新的终端,或者点击顶部导航栏中终端部分下的新终端。一旦你这样做了,你应该看到一个新的终端出现在Visual Studio Code窗口的底部。

New terminal in Visual Studio Code

从这个终端导航到你为代码创建的目录,my-app

cd my-app

接下来,安装python3-venv Ubuntu软件包,这样你就可以创建Python虚拟环境。

sudo apt update && sudo apt install python3-venv

现在用Python创建你的虚拟环境。

python3 -m venv myapp

这将在你的当前目录下创建一个名为myapp 的目录。 在里面,它将安装一个本地版本的Python和一个本地版本的pip ,即Python的包管理器。 你可以用它来为你的项目安装和配置一个孤立的 Python 环境。

在安装你的项目所需的 Python 之前,激活虚拟环境。

source myapp/bin/activate

你的提示应该改变,以表明你现在是在一个 Python 虚拟环境中操作。 它看起来会像这样。 (myapp)user@host:~/my-app$.

在虚拟环境激活后,用pip 的本地实例安装flaskgunicorn

pip install flask gunicorn

**注意:**一旦你激活了你的虚拟环境 (当你的提示符前面有(myapp) 时),使用pip 而不是pip3 ,即使你使用的是 Python 3。 虚拟环境中的工具副本总是被命名为pip ,不管 Python 的版本如何。

现在你已经安装了软件包,你需要保存这个需求和它的依赖项。这是一个很好的做法,这样你就可以根据需要重新创建你的开发环境,并有助于在后面的步骤中把正确的包安装到你的Docker文件中。

使用pip ,将你的环境信息保存到requirements.txt 文件中。

pip freeze > requirements.txt

现在你有了一个用于开发的虚拟环境,让我们来构建微服务。

第5步 - 构建一个Python微服务来重定向流量

你需要做的第一件事是创建一个名为app.py 的Python文件和一个Dockerfile 来指定你的Docker要求。你可以通过终端用touch 命令创建文件,然后刷新资源管理器。

touch app.py

你也可以使用文件资源管理器来创建一个新的文件,方法是点击你的_my-app_文件夹,然后点击_新文件_图标,看起来像一张带加号的纸,然后输入文件的全名和扩展名。

Create your app.py

使用这两种方法都可以创建app.pyDockerfile

一旦你完成了这些,打开app.py 。你今天要写的微服务将只有一个端点,由@app.route("/") 装饰器定义。这个端点将使用Flask库中的redirect 方法来执行301重定向到一个环境变量中指定的网站。如果没有设置环境变量,该应用程序将默认重定向到DigitalOcean的网站。

通过点击打开app.py ,并添加以下几行代码。

添加一个import 语句来导入os 包,这将使微服务能够读取你以后定义的环境变量。

import os

接下来,从flask库中导入Flask类和重定向函数。你将使用这些来设置你的网络框架并将流量重定向到另一个网站。

from flask import Flask,redirect

接下来,创建一个Flask对象,可以在代码中进行操作。这是你的Web应用的实例,你将向其注册路由。

app = Flask(__name__)

/ 路由处创建一个单一的方法。你将使用你的Flask实例来装饰函数以指定路由。在该函数中,你将使用Flaskredirect 函数来执行301重定向到另一个网站,该网站将从一个环境变量中读取。如果环境变量没有找到,你的应用程序将默认重定向到DigitalOcean的主页。这是为了确保你的应用程序在忘记设置环境变量时不会崩溃。

@app.route('/')
def hello():
    # Attempt to read REDIRECT_TO from the environment. If nothing is set
    # perform a 301 redirect to DigitalOcean's website
    return redirect(os.environ.get("REDIRECT_TO", "https://www.digitalocean.com"), code=301)

最后,创建一个main 函数,在外部运行你的Flask应用,端口为80800.0.0.0 这个地址是用来指定你希望你的应用程序运行在设备的外部网络接口上,而不是本地环回设备,也就是localhost

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

完成的app.py ,可以在下面找到。

# Import the os package to read the environment variable
import os

# Import the Flask class and redirect function from the flask library
from flask import Flask,redirect


# Create a Flask object to be acted upon
app = Flask(__name__)

# Python decorator that specifies the web route that will execute the code below
@app.route('/')
def hello():
    # Attempt to read REDIRECT_TO from the environment. If nothing is set
    # perform a 301 redirect to DigitalOcean's website
    return redirect(os.environ.get("REDIRECT_TO", "https://www.digitalocean.com"), code=301)

# Main function that executes the Flask app
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

一旦你完成了,将文件保存为_app.py_。

现在你的应用程序已经写好了,让我们来测试它。

第6步 - 测试你的微服务

现在你的应用程序已经写好了,是时候测试它了。 在Visual Studio Code中打开的终端中,激活虚拟环境,运行命令:

python app.py

你应该看到Flask的输出看起来与此相似。

Output * Serving Flask app 'app' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead
 * Debug mode: off
 * Running on all addresses.
 * WARNING: This is a development server. Do not use it in a production deployment.
 * Running on https://256.333.112.1:8080/ (Press CTRL+C to quit)

这意味着你的Flask应用正在运行。打开一个浏览器并导航到localhost:8080 。当你这样做,你应该看到输出发生在你的终端,并被重定向到DigitalOcean的网站。这是因为你没有为你的Flask应用程序指定任何地方来重定向,所以它正在使用默认。

要停止你的Flask应用程序,请点击Visual Studio Code窗口,以确保它是活动的,然后按CTRL+C 。你会看到提示停止,你会再次看到你的终端。

接下来,运行以下命令,将你的重定向设置为其他内容。

REDIRECT_TO="https://digitalocean.com/community/tutorials"

使用该命令再次运行你的Flask应用

python app.py

再次进入你的浏览器并导航到localhost:8080 。然后你应该被引导到DigitalOcean的教程页面。

**注意:**如果你打算用同一个容器测试多个重定向,你可能想使用某种形式的隐身模式。大多数现代浏览器会缓存一个301重定向,所以如果你改变环境变量,你可能最终会在同一个网站上,看不到你的变化反映。使用隐身窗口或清除你的缓存将有助于解决这个问题。

这样一来,你的应用程序就完成了,并准备好被构建成一个Docker镜像。

第7步 - 在Docker中构建和运行你的微服务

在这最后一步,你将使用Docker和_Dockerfile_将你的Python应用打包成一个微服务。Dockerfile是一个构建命令的列表,Docker使用它来创建你的镜像。这些命令可以是安装包、复制文件等等。

打开你在上一步创建的Dockerfile ,以便你可以编辑它。在这个文件中,你要指定基础镜像,告诉Docker你想让代码在哪里运行,创建一个保存重定向目标的环境变量,把所有必要的文件复制到Docker镜像中,安装必要的Python包,最后添加容器运行时要执行的命令。

将以下代码添加到Dockerfile 来完成这些工作。

首先,你需要指定你要使用的基础镜像。python基础镜像将包含最新版本的Python。

FROM python 

接下来,设置你的工作目录。这是Docker运行命令的默认目录,如果你用ssh 连接,就会把你放到这个目录中。

WORKDIR /var/www/

REDIRECT_TO 环境变量设置为你想重定向到的默认位置。这里我把它设置为DigitalOcean的社区教程网站。这可以在你通过命令行运行图像时改变。

ENV REDIRECT_TO=https://digitalocean.com/community/tutorials

将你的app.pyrequirements.txt 复制到你的Docker容器中,使用完全合格的路径作为目标。

COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt

运行必要的命令,在你的Docker镜像中安装Python库需求。

RUN pip install -r /var/www/requirements.txt

最后,设置镜像的运行命令来运行你的应用程序。这是在任何人试图运行你的Docker容器时都会运行的命令。

CMD python3 app.py

完整的Dockerfile ,下面列出了。

# Choose your base image
FROM python 

# Set your working directory
WORKDIR /var/www/

# Set environment variable for redirect. Can be overwritten by Docker run command
ENV REDIRECT_TO=https://digitalocean.com/community/tutorials

# Copy the necessary files
COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt

# Install the necessary packages
RUN pip install -r /var/www/requirements.txt

# Run the app
CMD python3 app.py

当你完成后,保存该文件。

现在你可以在本地构建Docker镜像进行测试。运行下面的命令来构建你的镜像,并将其标记为_myapp_。-t 选项将标签应用到Docker镜像上。

docker build -t myapp .

最后,是时候测试你的Docker镜像了。在你上面的Docker文件中,你设置了一个环境变量REDIRECT_TO ,指向一个网站。这将覆盖你代码中的默认值,所以当你运行这个容器时,你在Dockerfile中指定的任何网站将是你的新位置。

注意:如果windows提示你授予Docker访问网络的权限,请点击允许

为了测试你的镜像,运行以下命令。

docker run -p 8080:8080 myapp

当你的镜像运行时,导航到一个浏览器,在导航栏中输入localhost:8080 ,你应该被重定向到Docker文件中列出的网站。

**警告。**有时WSL终端不能识别CTRL + C ,作为停止Docker镜像的一种方式。在这种情况下,你需要打开另一个终端,用命令搜索你正在运行的Docker镜像。

docker container ls

这将显示一个类似于此的输出。

OutputCONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS                                       NAMES
3f081712283e   myapp     "/bin/sh -c 'python3…"   About a minute ago   Up About a minute   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   reverent_saha

取容器的ID,在这个例子中是3f081712283e ,并使用docker kill 命令来停止它。

docker kill 3f081712283e

最后,让我们测试一下改变docker run 命令中重定向的环境变量。

输入以下命令,将环境变量改为DigitalOcean云控制台页面,cloud.digitalocean.com

docker run -p 8080:8080 -e REDIRECT_TO=https://cloud.digitalocean.com myapp

现在,如果你到浏览器中浏览localhost:8080 ,你将被重定向到命令行中指定的网站。

总结

你已经成功地在Windows上使用WSL、Visual Studio Code和Docker Desktop设置了一个开发者环境。你已经演示了如何在Windows上构建、测试和打包代码,使你在开发环境方面有更多的选择。