65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Microsoft Azure 将 ASP.NET Core Web 应用程序构建和部署为 Docker 容器 - 第一部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2019 年 4 月 24 日

CPOL

7分钟阅读

viewsIcon

14275

本文是系列文章的第一篇,我们将构建一个简单的 ASP.NET Core Web 应用程序,使用 Docker 对其进行容器化,并在本地主机上运行它。

您是否经常问自己……我构建了一个 ASP.NET Core Web 应用程序,**接下来该怎么办?我该如何使用 GitHub、Docker、CI/CD 和 Microsoft Azure 等工具和平台将我的应用程序提升到新的水平**?

如果**是**!您来对地方了!

引言

本文是系列文章的第一篇,我们将构建一个简单的 ASP.NET Core Web 应用程序,使用 Docker 对其进行容器化,并在本地主机上运行。然后,我们将所有内容推送到 GitHub 以供以后使用。

在接下来的文章中,我们将设置 Microsoft Azure DevOps 生成管道,以自动化生成 Docker 映像并将其推送到 Docker Hub 的过程。接下来,我们将使用 Azure DevOps 发布管道将我们的应用程序作为容器部署到 Azure Web App Service

所以,请继续关注我,还有很多内容需要介绍。**让我们开始吧**!

系列共三部分

设置 GitHub 存储库

第一步是在 GitHub 上设置一个存储库,您将在其中存放所有代码。这是必需的,*因为*稍后,当您每次向存储库执行 `push` 操作时,您都需要设置 Azure 来触发生成和发布。

因此,登录到您的 GitHub 帐户并创建一个存储库。

创建存储库后,就可以将其放到本地系统并开始进行编码了。但在执行此操作之前,请确保您的系统上已安装 Git。如果没有,请访问 Git 下载页面并进行设置。这很简单!

现在,在 GitHub 上,选择您刚刚创建的存储库。右侧应有一个“**Clone or download**”按钮,单击它,您将获得克隆存储库的 URL。

URL to clone the repository

打开终端或 PowerShell 会话,导航到要克隆存储库的目录,然后执行命令

$ git clone <repository-clone-url>

准备就绪后,就可以开始开发应用程序了。

创建 ASP.NET Core Web 应用程序

要创建应用程序,您必须安装 .NET Core(版本 >= 2.0)。访问 .NET Core 下载页面并安装与底层系统兼容的 SDK。

现在,如果您在 **Windows** 上,请打开 Visual Studio 并创建一个新的 ASP.NET Core Web 应用程序项目。

New ASP .Net Core Web Application Project

新的 ASP.NET Core Web 应用程序项目

在下一页上,选择 Web 应用程序(模型-视图-控制器)模板,并确保“**配置 HTTPS**”未选中。保持简单即可。单击 **OK**。

如果您在 **Linux** 或 **Mac OS** 上,请打开终端并导航到*克隆*目录。您可以使用以下命令创建 .NET Core MVC Web App

$ dotnet new mvc --name <your-project-name>

完成后,您就可以使用您喜欢的编辑器进行必要的更改了。

为了进一步学习或解决问题,我强烈建议您查看我关于“在 Linux 或 Mac OS 上入门 .NET Core”的 **YouTube** 视频播放列表。

此时,我将留给您,我亲爱的读者,来构思一个简单的应用程序创意并将其实现。或者,您可以按照我的应用程序的更改过程进行。

我正在构建一个简单的博客,用于显示最新文章列表。请随时克隆我的 GitHub 存储库,以获取最新的源代码和所有使用的资源。

向导航栏添加文章链接

ASP.NET Core Web 应用程序附带了一个精美的预定义模板。要更新导航栏,请打开 *Views/Shared/_Layout.cshtml*。在 body>nav 部分下方添加一个“Articles”链接。

...
<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" 
             data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a asp-area="" asp-controller="Home" asp-action="Index" 
             class="navbar-brand">Docker WebApp</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
                <li><a asp-area="" asp-controller="Home" asp-action="Articles">Articles</a></li>
            </ul>
        </div>
    </div>
</nav>
...

现在,当我们单击“Articles”链接时,将向 **Home** 控制器中的 **Articles** 操作发送一个 HTTP GET 请求,该操作尚未更新。

添加必需的模型

在 _Models_ **目录**下,添加一个 _ArticlesViewModel.cs_ **.cs** 文件,其中将包含必需的模型类。

using System;
using System.Collections.Generic;

namespace WebApp.Models
{
    public class ArticlesViewModel
    {
        public List<Article> Articles { get; set; }

        public ArticlesViewModel()
        {
            Articles = new List<Article>();
        }
    }

    public class Article
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Author { get; set; }
        public DateTime PublishedOn { get; set; }
        public string Content { get; set; }
    }
}

接下来,让我们使用 _ArticleRepository.cs_ 为博客添加一些静态数据。

using System;
using System.Collections.Generic;
using System.Linq;
using WebApp.Models;

namespace WebApp
{
    public class ArticleRepository
    {
        private List<Article> articles = new List<Article>
        {
            new Article
            {
                Id = 1,
                Title = "What is Lorem Ipsum?",
                Author= "Gaurav Gahlot",
                PublishedOn = new DateTime(2019, 01, 20),
                Content = "Lorem Ipsum is simply dummy text of the printing 
                           and typesetting industry."
            },
        }

        public List<Article> GetLatest()
        {
            return articles;
        }        
    }
}

更新 Home 控制器

**Home** 控制器需要一个操作来处理来自最新文章列表的请求。这是带有用于 `GET` 请求的 **Articles** 操作的新控制器。

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Net.Http;
using WebApp.Models;

namespace WebApp.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Articles()
        {
            var model = new ArticlesViewModel();
            model.Articles = new ArticleRepository().GetLatest();

            return View(model);
        }
    }
}

我们需要做的最后一件事是添加一个 View 来渲染我们的数据。因此,在 _Views/Home/_ **下添加一个 Articles View**,并包含以下代码以渲染最新文章。

@{
    ViewData["Title"] = "Articles";
}
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
    <div class="carousel-inner" role="listbox">
        <div class="item active">
            <img src="~/images/docker.png" alt="Docker" class="img-responsive" />
            <div class="carousel-caption" role="option">
                <p style="font-size:xx-large; color:darkslategrey">
                    If you see me swim, your application is up and running in Docker.
                </p>
            </div>
        </div>
    </div>
</div>

将代码推送到 GitHub

完成代码更改后,就可以将代码推送到 GitHub 了。打开终端并导航到*项目*目录。

您可以使用以下命令检查本地存储库的状态:

$ git status

您应该会看到所有文件和目录都已添加或更新。现在,要暂存存储库中的所有更改,请运行命令:

$ git add .

让我们用一个简短而有意义的消息提交更改:

$ git commit -m "your-commit-message"

最后,将所有已提交的更改推送到 GitHub 上的远程分支:

$ git push origin

**注意**:在最后提交所有更改**不是**一个好习惯。实际上,您应该经常提交可以按逻辑分组的所有更改。

至此,我假设您的应用程序运行良好,并且您已准备好使用 Docker 对应用程序进行*容器化*。

Dockerfile

根据 Docker 文档

Dockerfile 是一个文本文件,其中包含用户可以在命令行中调用以组装映像的所有命令。Docker 可以通过读取 Dockerfile 中的指令自动生成映像。

这是我的应用程序的 Dockerfile:

# STAGE01 - Build application and its dependencies
FROM microsoft/dotnet:2.1-sdk AS build-env
WORKDIR /app
COPY WebApp/*.csproj ./
COPY . ./
RUN dotnet restore 

# STAGE02 - Publish the application
FROM build-env AS publish
RUN dotnet publish -c Release -o /app

# STAGE03 - Create the final image
FROM microsoft/dotnet:2.1-aspnetcore-runtime
WORKDIR /app
LABEL Author="Gaurav Gahlot"
LABEL Maintainer="quickdevnotes"
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "WebApp.dll", "--server.urls", "http://*:80"]

请注意,我使用了多阶段生成,以确保最终映像尽可能小。

总的来说,多阶段生成就像我们在构建和发布项目时通常所做的那样。以下是各阶段的简要说明:

  • **STAGE01** - 在此阶段,我们还原应用程序构建所需的程序包和依赖项。请注意,.NET Core SDK 是我们的基础映像,用于生成项目。
  • **STAGE02** - 第一阶段成功后,我们将发布应用程序,并将生成的二进制文件存储在 _/app_ 目录中。
  • **STAGE03** - 在此阶段,我们使用 .NET Core Runtime 作为基础层,并将上一个阶段生成的 _/app_ 目录中的二进制文件复制过来。

这是最小化 Docker 映像大小的一项很棒的功能,您可以从文档中了解更多信息。

因为此 Dockerfile 特定于我的应用程序,所以您可能需要进行一些更改才能使其正常工作。

运行容器

现在是时候为您的应用程序构建 Docker 映像并启动一个容器了。打开终端并导航到保存 Dockerfile 的目录。然后,使用以下命令构建 Docker 映像:

$ docker build -t webapp .

这将构建一个 Docker 映像并将其保留在我们的本地系统上。为了测试我们的映像和应用程序,现在我们将使用以下命令运行一个容器:

$ docker run -d -p 5000:80 --rm --name webapp webapp
19c758fdb9bfb608c4b261c9f223d314fce91c6d71d33d972b79860c89dd9f15

上述命令将创建一个容器并输出容器 ID。您可以使用 `docker ps` 命令验证容器是否正在运行。

$ docker ps

CONTAINER ID        IMAGE               PORTS                  NAMES               MOUNTS
19c758fdb9bf        webapp              0.0.0.0:5000->80/tcp   webapp

现在,打开浏览器并转到 URL _https://:5000/_。如果一切正常,您应该会看到您的 Web 应用程序的主页。在我的情况下,它看起来像这样:

WebApp Home Page

测试您的应用程序,一旦确定它运行正常,就将 Dockerfile 提交并推送到您的 GitHub 存储库。

结论

在本篇中,我们使用 ASP.NET Core 开发了一个 Web 应用程序,并将其放入了 GitHub 存储库。我们还通过构建 Docker 映像并从中运行 Docker 容器来测试了我们的应用程序。

下一步是设置 Microsoft Azure DevOps 的生成管道。此管道将连接到我们的 GitHub 存储库。我们还将设置管道,以便每次向存储库的 master 分支推送更改时都会触发生成。该管道将创建一个 Docker 映像并将其推送到 Docker Hub。

历史

  • 2019年4月24日:初始版本
© . All rights reserved.