ASP.NET Core 2.0 和 Docker 在 MacOS






4.92/5 (7投票s)
快速 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。请继续安装以下内容:
- 适用于 MAC 的 .NET SDK (撰写本文时使用的最新版本是 2.0.3)。
- 适用于 MAC 的 Visual Studio (Visual Studio 2017)
- 适用于 MAC 的 Docker (撰写本文时使用的最新版本是 17.06.2-ce)
.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
上述命令应该会得到类似如下结果:
创建您的第一个 ASP.NET Core 2.0 项目
现在,启动 Visual Studio 2017 并创建一个空的 ASP.NET Core 项目,如下图所示:
点击“下一步”。在下一个屏幕上,选择 .NET Core 2.0 作为目标框架,然后点击“下一步”。现在应该会显示以下屏幕:
为简化演示,将项目命名为“aspnetcoredemo
”,然后浏览到您想要创建项目的路径。点击“创建”让 Visual Studio 为您生成默认文件。您应该能看到类似下图的内容:
首次运行项目
点击“播放”按钮来构建和运行项目。当一切成功构建后,您的浏览器中应该会显示类似如下的内容:
就是这样!我们现在已经在 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”,如下图所示:
然后,复制下面的设置:
"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()
方法负责两件事:
- 如果 PostgreSQL 中不存在,则创建数据库。
- 将数据库模式迁移到最新版本。
添加迁移
我们将使用 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”的新文件夹,其中包含迁移文件,如下图所示:
上面生成的文件将用于在首次运行时创建数据库。
创建 Web API 控制器
现在是时候创建简单的 Web API 方法来处理简单的 GET
和 POST
请求了。添加一个新的 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
GET
GET/Id
就是这样!希望您觉得这篇文章有用。
参考文献
- .NET Core 在 Mac 上 - 使用 Web API、EF、PostgreSQL 构建 ASP.NET Core 应用并将其运行在 Docker 中
- 开始使用 Docker for Mac
- Docker 命令
- ASP.NET Core 简介
摘要
在本文中,我们学习了在 MAC 环境中设置 .NET Core 2 的基础知识,并学习了如何创建一个简单的 ASP.NET Core 2 应用程序,其中包含 Web API、EF、PostgreSQL,并将其运行在 Docker 中。
历史
- 2018 年 1 月 3 日:初始版本