前言
小白直接上手 docker 构建我们的第一个项目,简单粗暴,后续各种概念边写边了解,各种概念性的内容就不展开,没了解过的点击 Docker 教程 进行初步了解。
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
1、安装docker
由于我们是windows环境,所以安装的是 Docker Desktop for Windows
系统要求:
- Windows 10 64位:专业版,企业版或教育版(Build 15063或更高版本)。
- 在BIOS中启用虚拟化(各个主板的BIOS的操作面板不同,可咨询主板商)。通常,默认情况下启用虚拟化。
- 具有CPU SLAT功能。
- 至少4GB的运行内存。
- 启用Hyper-V
这里需要重点注意,Windows 10 64位、在BIOS中启用虚拟化、启用Hyper-V这三个条件比较重要。
可以点击下面的连接进行详细安装指导
详细安装步骤:Docker Desktop for Windows 安装要求已经安装步骤:https://www.jc2182.com/docker/docker-windows-install.html
PS:不同的主板可以百度查询一下如:HP工作站如何在BIOS下开启关闭虚拟化技术:https://jingyan.baidu.com/article/ce436649184b393773afd309.html
2、创建docker项目
1.创建项目
安装完docker后,我们创建第一个docker项目。
新建一个ASP.NET Core Web(模型-视图-控制器)项目,命名为 AspNetCoreWeb (你也可以自己取一个名称),
选择 .NET Core 3.1(长期支持) ,勾选 启用Docker ,Docker OS 下拉选择 Linux ,如下展示:
到这里默认代码就创建完成了,不需要的可以跳过,需要查看数据库交互的可以继续往下看。
我们之前介绍过:10分钟系列:NetCore3.1+EFCore三步快速完成数据库交互。现在就基于这个进行数据库交互,下面介绍的就是这里面的做法。
2.引入NuGet包并创建上下文对象
这里只需要两个包,一个是EFCore的引用包,一个是数据库连接的引用包。
在NuGet分别引入下面两个包,
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
在项目里面创建一个 EntityDbContext 文件夹,然后在文件夹里面创建一个 DbContext_first 类,并继承 EFCore框架中的 DbContext,
在 EntityDbContext 文件夹下创建 Entity 文件夹,创建 StudentTable 实体映射。如下展示
PS:(注意,这里默认是数据库存在StudentTable表的,如果没有请先创建,EFCore支持实体映射表到数据库的,这里就不体现了,有需要了解的自行百度或私信小编)
上下文里面的内容如下(注意:在Docker里面连接的数据库需要是外网可以访问的):
using AspNetCoreWeb.EntityDbContext.Entity; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace AspNetCoreWeb.EntityDbContext { public class DbContext_first:DbContext { /// <summary> /// 在这里重写OnConfiguring的方法来配置数据库的连接字符串 /// </summary> /// <param name="optionsBuilder"></param> protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { //SQL Server/Azure SQL 数据库、SQLite、Azure Cosmos DB、MySQL、PostgreSQL数据库连接 //注意,这个链接是外网可以访问的,本地链接不可以,Docker里面读取不到 optionsBuilder.UseSqlServer("Data Source=47.101.72.203; Initial Catalog=Demo;User Id=sa;Password=Ai562723XueEr@"); } public DbSet<StudentTable> StudentTable { get; set; } //需要操作的数据库对应的表 } }
3.编写一个查询语句并返回数据
在自动生成的Home控制器里面添加如下查询代码
//查询 public JsonResult GetStudentList() { List<StudentTable> studeltList = new List<StudentTable>(); ResultInfo result = new ResultInfo(); try { using (var ctx = new DbContext_first()) { try { studeltList = ctx.StudentTable.ToList(); } catch (Exception ex) { result.code = -1; result.message = "数据库查询失败:"+ex.Message; return Json(result); } result.code = 0; result.message = "成功"; result.info = studeltList; } } catch (Exception ex) { result.code = -2; result.message = "数据库连接失败:" + ex.Message; } return Json(result); } public class ResultInfo { public int code { get; set; } public string message { get; set; } public object info { get; set; } }
4.配置相关数据
配置1:避免中文变成Unicode
在 Startup.cs 类的 ConfigureServices 方法添加返回的格式定义为JSON,否则默认返回的是被编译的Unicode,不是中文。
由于一些 JS 组件要求 JSON 格式是 PascalCase ,新版本 ASP.NET Core 3.0 中默认移除了 Newtonsoft.Json ,使用了微软自己实现的 System.Text.Json 来代替,可以修改继续使用 Newtonsoft.Json 来设置 PascalCase 格式属性名。
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddControllersWithViews().AddJsonOptions(options => { options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); }); }
配置2:避免数据库版本过低和Docker版本不一致
在Dockerfile的最后添加一行代码,添加内容如下:
RUN sed -i 's/TLSv1.2/TLSv1.0/g' /etc/ssl/openssl.cnf
下面是详细解释,可以不看。
我是用SqlServer2012进行操作,发现返回下面下面的35错误:
A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught
出现问题的 asp.net core 程序是跑在容器中的,容器镜像用的是 mcr.microsoft.com/dotnet/core/aspnet:3.0
运行容器内的 openssl 命令发现 openssl 的版本比较高
1.进入容器
docker exec -it [容器ID] bash
2.查看容器openssl版本
openssl version
OpenSSL 1.1.1d 10 Sep 2019
3.查看 openssl.cnf 配置文件
cat /etc/ssl/openssl.cnf
[system_default_sect] MinProtocol = TLSv1.1 CipherString = DEFAULT@SECLEVEL=2
发现允许的 ssl 最低版本是 TLSv1.2 ,而程序所使用的 SQL Server 数据库版本比较低不支持 TLSv1.2 ,修改为 TLSv1.0 后问题解决
4.修改方法:在 Dockerfile 中添加下面的指令
RUN sed -i 's/TLSv1.2/TLSv1.0/g' /etc/ssl/openssl.cnf
3、生成Docker镜像并在浏览器运行
运行 Docker Desktop,也就是刚刚安装的docker,然后出现面板,直接点下面的按钮跳过,进入主面板。
在项目里面点击Dockerfile右键,点击 生成 Docker 映像,等待打包生成,生成后点查看Docker Desktop,在Images里面就有一个镜像包。如下
点击镜像文件后面的RUN运行镜像,然后在弹出的狂内下拉打开,数据端口号8088,你也可以输入其他端口号,然后点击Run。
这个镜像文件就运行成功了,然后点击OPEN IN BROWSER(在浏览器打开)就可以看到效果了。
然后在浏览器手动输入http://localhost:8088/Home/GetStudentList访问我们刚刚在Home控制器写的查询方法进行数据库交互验证,如下成功交互。
参考文献
- HP工作站如何在BIOS下开启关闭虚拟化技术:https://jingyan.baidu.com/article/ce436649184b393773afd309.html
- Docker 教程 | 菜鸟教程:https://www.runoob.com/docker/docker-tutorial.html
- Docker——从入门到实践:https://www.kancloud.cn/docker_practice/docker_practice/469767
- Docker 教程:https://www.jc2182.com/docker/docker-windows-install.html
- Docker 百度百科:https://baike.baidu.com/item/Docker/13344470?fr=aladdin