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

ASP.NET Core 2.0 和 Docker 在 MacOS

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (7投票s)

2018 年 1 月 3 日

CPOL

8分钟阅读

viewsIcon

29173

downloadIcon

123

快速 walkthrough 在 MAC 上构建 ASP.NET Core 2.0 应用程序并在 Docker 容器中运行它

  

引言

去年,我写了一篇关于“.NET Core 在 Mac 上 - 使用 Web API、EF、PostgreSQL 构建 ASP.NET Core 应用并将其运行在 Docker 中”的文章。该文章使用的是 .NET Core 1.1 版本,如果您按照文章中提到的相同步骤使用 .NET Core/ASP.NET Core 2.0,那么这些步骤将不再有效。

一年多以来,.NET Core 1.x 到 2.0 版本发生了一些变化。在本文中,我们将通过构建一个简单的 Web API 应用程序并将其部署到 Docker 容器中,来探索 ASP.NET Core 2.0 和 Docker。

引用

注意:在继续阅读之前,请确保您对 ASP.NET Core 和 Docker 有基本的了解,因为我不会在本文中详细介绍每项技术。

必备组件

在动手之前,我们需要为我们在 MAC 环境中构建和运行应用程序更新/安装所需的工具和 SDK。请继续安装以下内容:

.NET Core 2.0 和 ASP.NET Core 2.0 的 Docker 镜像

安装完所有必备软件后,我们需要从 Docker Hub 拉取 .NET Core 和 ASP.NET Core 所需的 Docker 镜像。请打开终端并分别运行以下命令:

  • docker pull microsoft/dotnet:2.0.0-sdk
  • docker pull microsoft/aspnetcore:2.0.0
  • docker pull microsoft/aspnetcore-build:2.0.0

拉取 Docker 镜像后,可以通过运行以下命令进行验证:

$ docker images

上述命令应该会得到类似如下结果:

图 1:Docker 镜像

创建您的第一个 ASP.NET Core 2.0 项目

现在,启动 Visual Studio 2017 并创建一个空的 ASP.NET Core 项目,如下图所示:

图 2:新的 ASP.NET Core 2 空项目

点击“下一步”。在下一个屏幕上,选择 .NET Core 2.0 作为目标框架,然后点击“下一步”。现在应该会显示以下屏幕:

图 3:配置 ASP.NET Core 项目

为简化演示,将项目命名为“aspnetcoredemo”,然后浏览到您想要创建项目的路径。点击“创建”让 Visual Studio 为您生成默认文件。您应该能看到类似下图的内容:

图 4:生成的 文件

首次运行项目

点击“播放”按钮来构建和运行项目。当一切成功构建后,您的浏览器中应该会显示类似如下的内容:

就是这样!我们现在已经在 MAC 上运行了一个 ASP.NET Core 2.0 应用程序。

开始吧!

现在,为了让这个演示更有趣,我们将进一步创建一个简单的 Web API 来处理基本的 CRUD 操作,并使用 Postgres 作为我们的数据库。然后,我们将把应用程序和数据库运行在 Docker 容器中。

添加 Docker 文件

我们需要做的第一件事是在项目中创建一个 Docker 文件。Dockerfile 包含构建 Docker 镜像的指令。有关更多信息,请参阅 Dockerfile 参考

在 Dockerfile 中添加以下命令:

FROM microsoft/aspnetcore-build:2.0.0 AS build

WORKDIR /code

COPY . .

RUN dotnet restore

RUN dotnet publish --output /output --configuration Release

FROM microsoft/aspnetcore:2.0.0

COPY --from=build /output /app

WORKDIR /app  
ENTRYPOINT ["dotnet", "aspnetcoredemo.dll"]

集成 EF Core 和 PostgreSql

切换回 Visual Studio 并安装以下最新的 Nuget 包:

  • Npgsql.EntityFrameworkCore.PostgreSQL
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.EntityFrameworkCore.Design

上述包使我们能够使用 EntityFramework Core 作为我们的数据访问机制。我们将使用 EF Core 来同步和更新 PosgreSql 数据库,然后使用 Web API 来处理数据请求。

Entity Framework Core 现在支持多种数据库提供程序。在本演示中,我们将把 PostgreSQL 集成到我们的 .NET Core 应用程序中。安装 Postgres 最简单的方法是使用 Homebrew,它应该包含在 .NET Core SDK 的安装中。现在运行以下命令来下载和安装 PostreSQL:

$ brew install postgresql

如果安装顺利,数据库管理器就会安装好。现在,通过运行以下命令来启动 PostgreSQL 服务容器:

$ docker run -d --name localdb -e POSTGRES_PASSWORD=supersecret postgres

-d 选项使容器在后台运行并打印容器 ID。--name 为容器分配一个名称,在本例中,我们将容器命名为“localdb”。-e 允许我们设置环境变量,在本例中,我们使用 POSTGRES_PASSWORD 变量为我们的 Postgres 镜像设置了密码“supersecret”。

运行上述命令将公开 postgres 端口 5432,从而使标准容器可以被链接的容器访问。initdb 也将生成默认用户和数据库。

要验证我们的 PostgresSQL Docker 容器是否已启动并正在运行,请执行:

$ docker ps

要测试连接,您可以执行:

$ docker run -it --rm --link pg-db:postgres postgres psql -h postgres -U postgres 

创建应用程序

现在我们的数据库已经在 Docker 容器中准备就绪,是时候构建应用程序了。

设置数据库连接字符串

添加一个新的空 .json 文件,并将其命名为“appsettings”,如下图所示:

图 6:添加新文件

然后,复制下面的设置:

"DbContextSettings": {
    "ConnectionString": "User ID=postgres;Password=supersecret;
     Server=postgres;Port=5432;Database=POSTGRES_USER;
     Integrated Security=true;Pooling=true;"
}

上述 connectionstring 将允许我们连接到之前运行的 PostgreSql 服务容器。

创建模型

在本演示中,我们将使用 EF Code-First 方法,这意味着我们将先创建模型,然后运行迁移,让 EF 根据我们的模型生成数据库/模式。

在项目根目录下创建一个新的类,并将文件命名为“Student”。复制下面的代码:

namespace aspnetcoredemo  
{
    public class Student
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

定义 DbContext

EF Core Code-First 开发方法要求我们定义一个继承自 DbContext 类的数据访问上下文类。现在,在项目根目录下添加一个新的类。将文件命名为“StudentContext”,然后复制下面的代码:

using System;  
using Microsoft.EntityFrameworkCore;

namespace aspnetcoredemo  
{
    public class StudentContext: DbContext
    {
        public StudentContext
        (DbContextOptions<StudentContext> options)  
            : base(options)  
        { }

        public DbSet<Student> Students { get; set; }
    }
}

注册服务与依赖注入

接下来,我们需要将 DbContext 注册为服务,并启用 MVC 服务以启用 Web API。打开 startup.cs 并用以下代码替换现有代码:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Threading.Tasks;  
using Microsoft.AspNetCore.Builder;  
using Microsoft.AspNetCore.Hosting;  
using Microsoft.AspNetCore.Http;  
using Microsoft.EntityFrameworkCore;  
using Microsoft.Extensions.Configuration;  
using Microsoft.Extensions.DependencyInjection;

namespace aspnetcoredemo  
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName} .json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }
        // This method gets called by the runtime. 
        // Use this method to add services to the container.
        // For more information on how to configure your application, 
        // visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            var connectionString = 
                Configuration["DbContextSettings:ConnectionString"];
            services.AddDbContext<StudentContext>
                     (opts => opts.UseNpgsql(connectionString));
        }

        // This method gets called by the runtime. 
        // Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
        }
    }
}

让我们修改 Program.cs 以在启动时创建数据库。这是完整的代码:

using System;  
using Microsoft.AspNetCore;  
using Microsoft.AspNetCore.Hosting;  
using Microsoft.EntityFrameworkCore;  
using Microsoft.Extensions.DependencyInjection;  
using Microsoft.Extensions.Logging;

namespace aspnetcoredemo  
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();

            var host = BuildWebHost(args);

            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;

                try
                {
                    services.GetService<StudentContext>().Database.Migrate();
                }
                catch (Exception ex)
                {
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred seeding the DB.");
                }
            }

            host.Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

EF Core 不会自动执行迁移,这就是为什么我们需要上述配置才能使用 Code-First 迁移。Database.Migrate() 方法负责两件事:

  1. 如果 PostgreSQL 中不存在,则创建数据库。
  2. 将数据库模式迁移到最新版本。

添加迁移

我们将使用 EF Core 工具来脚手架迁移并更新数据库。我们将使用命令行 (dotnet CLI) 来运行迁移。撰写本文时,由于以下错误,我们无法从 Nuget 添加 Microsoft.EntityFrameworkCore.Tools.DotNet 包:

“包 'Microsoft.EntityFrameworkCore.Tools.DotNet 2.0.0' 具有不受项目支持的 'DotnetCliTool' 包类型”

作为一种解决方法,我们可以编辑项目文件 (.csproj) 并添加以下配置:

<ItemGroup>
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" 
     Version="2.0.0" />
</ItemGroup>

现在打开终端到项目根目录所在的位置,然后执行:

$ dotnet ef migrations add InitialMigration

ef migration add 是添加迁移的命令。如果迁移成功,您应该会看到一个名为“Migrations”的新文件夹,其中包含迁移文件,如下图所示:

图 7:迁移文件

上面生成的文件将用于在首次运行时创建数据库。

创建 Web API 控制器

现在是时候创建简单的 Web API 方法来处理简单的 GETPOST 请求了。添加一个新的 Web API 控制器类并复制以下代码:

using System.Collections.Generic;  
using System.Linq;  
using Microsoft.AspNetCore.Mvc;

namespace aspnetcoredemo.API  
{
    [Route("api/[controller]")]
    public class StudentsController : Controller
    {
        private readonly StudentContext _context; 

        public StudentsController(StudentContext context)
        {
            _context = context;
        }

        // GET: api/students  
        public IEnumerable<Student> Get()  
        {  
            return _context.Students.ToList();  
        }  

        // GET api/students/1  
        [HttpGet("{id}")]  
        public Student Get(int id)  
        {  
            return _context.Students.FirstOrDefault(x => x.Id == id);  
        }  

        // POST api/students  
        [HttpPost]  
        public IActionResult Post([FromBody]Student value)  
        {  
            _context.Students.Add(value);  
            _context.SaveChanges();  
            return StatusCode(201, value);  
        }  
    }
}

那里没什么花哨的,上面的代码只包含几个与 StudentContext 通信的基本方法。请注意,我们在 Controller 的构造函数中注入了 StudentContext 的实例,以便我们可以与数据库进行交互,并用它来查询数据。

在 Docker 中运行应用程序

此时,我们已准备好将应用程序部署到 Docker。首先,让我们通过运行以下命令来构建应用程序:

$ docker build -t dockerdemo .

上面的命令将在我们的 Docker 机器中生成一个新映像实例。您可以通过在命令行中运行 docker images 来查看映像列表。

现在,运行以下命令以确保我们的 PostgreSQL 数据库映像已启动并正在运行:

$ docker ps 

现在,让我们使用以下命令运行我们的 ASP.NET Core 2.0 应用程序并链接我们创建的数据库:

$ docker run -it -p 5000:80 --link localdb:postgres dockerdemo

测试 Web API 端点

以下是使用 Postman 测试端点的结果截图:

POST

图 8:输出

GET

图 9:输出

GET/Id

图 10:输出

就是这样!希望您觉得这篇文章有用。

参考文献

摘要

在本文中,我们学习了在 MAC 环境中设置 .NET Core 2 的基础知识,并学习了如何创建一个简单的 ASP.NET Core 2 应用程序,其中包含 Web API、EF、PostgreSQL,并将其运行在 Docker 中。

历史

  • 2018 年 1 月 3 日:初始版本
© . All rights reserved.