Windows下使用docker部署.Net Core
前言
Docker 是一个开源的应用容器引擎,它十分火热,如今几乎成为了后端开发人员必须掌握的一项技能。即使你在生产环境中可能用不上它,就算把它当作一个辅助开发的工具来使用,也是非常方便的。
安装及配置
下载安装
官网下载:https://www.docker.com/get-started
配置镜像加速
国内网络必须配置镜像加速,不然镜像几乎无法下载。
"registry-mirrors": [
"https://registry.docker-cn.com",
"https://dockerproxy.com",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://ccr.ccs.tencentyun.com"
]
配置镜像存储路径
默认docker的运行文件是在C盘,C盘空间不够的话,可以设置到别的盘。
新版本的windows Docker Desktop默认使用wsl运行,文件位置都只能由WSL管理:
如果是老版本Hyper-V,可以通过界面设置。更多信息可参照:win10使用WSL 2运行Docker Desktop,运行文件从C盘迁移到其他目录 - xhznl - 博客园 (cnblogs.com)
docker基本概念、基础命令可参照:.Net Core in Docker极简入门(上篇) - xhznl - 博客园 (cnblogs.com)
.net core部署到docker
项目添加docker支持
右键项目-添加-Docker支持,目标OS选择Linux,项目自动创建Dockerfile文件。
文件内容主要是通过.net core cli命令来定义了一系列打包发布运行的过程。
#使用asp.net 6作为基础镜像,起一个别名为base FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base #设置工作目录为/app WORKDIR /app #暴露80和443端口 EXPOSE 80 EXPOSE 443 #使用dotnet 6作为基础镜像,起一个别名为build FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build #设置工作目录为/src WORKDIR /src #复制WebApp/WebApp.csproj到/src/WebApp/目录下 COPY ["WebApp/WebApp.csproj", "WebApp/"] #运行dotnet restore命令,还原依赖包 RUN dotnet restore "WebApp/WebApp.csproj" #复制WebApp目录下的所有文件到/src/WebApp/目录下 COPY . . #设置工作目录为/src/WebApp/目录下 WORKDIR "/src/WebApp" #运行dotnet build命令,编译项目 RUN dotnet build "WebApp.csproj" -c Release -o /app/build #使用build作为基础镜像,起一个别名为publish FROM build AS publish #运行dotnet publish命令,发布项目 RUN dotnet publish "WebApp.csproj" -c Release -o /app/publish /p:UseAppHost=false #使用base作为基础镜像,起一个别名为final FROM base AS final #设置工作目录为/app WORKDIR /app #复制publish目录下的所有文件到/app/目录下 COPY --from=publish /app/publish . #设置环境变量ASPNETCORE_URLS为http://+:80 ENTRYPOINT ["dotnet", "WebApp.dll"]
构建镜像
在项目根目录启动powershell或cmd窗口来执行docker命令
执行构建命令: docker build -t testpub -f ./WebApp/Dockerfile .
注意:参数-f是指定Dockerfile所在的目录;注意大小写。
使用docker images可以看到打包成功的镜像
启动容器
执行命令:docker run -d -p 5000:80 --name mytestpub1 testpub
返回容器id说明执行成功
查看运行的容器:docker ps
打开浏览器可以正常访问
至此,一个简单的asp.net core web应用就成功运行于docker之中。
也可以利用vs的功能完成前面所有的步骤:在创建完dockerfile文件之后,选择在vs上选择docker运行,vs会自动创建镜像和容器。
镜像仓库
我们也可以把自己的镜像推送到远程仓库,然后在其他机器上直接就能通过命令拉取了。国内阿里云之类的都有docker镜像仓库服务,也可以搭建私有仓库,本文就推送到docker的官方仓库docker hub。首先需要在docker官网https://www.docker.com/注册账号。
构建镜像
重新构建镜像:docker build -t xiaoqingyao/testpub -f ./WebApp/Dockerfile .
xiaoqingyao为docker用户名
上传镜像
首先登录Docker:docker login,输入用户名密码。
如果登录失败提示下图:可能会出现登录超时的情况,说明被强了,我自己翻了一下。还可以参照:(17条消息) 解决在windows下docker login超时的问题_dock 登录超时_琴瑟和鸣1的博客-CSDN博客
如果还不行就用别的仓库
登录成功
推送镜像:docker push xiaoqingyao/testpub
推送成功后可在官网看到镜像
这样,在其他机器的docker里也可以直接通过docker pull xiaoqingyao/testpub来拉取这个镜像使用。
Docker-Compose
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
简单来理解,Compose类似一个批量工具,可以执行一组命令,支持批量构建镜像,批量启动容器,批量删除容器等等功能。
Windows的Docker Desktop中已经包括了Compose,Linux下Compose则需要单独安装一下。
代码修改
以.netCore+EfCore演示
添加EfCore依赖
添加相关代码
public class SQLDbContext : DbContext { public SQLDbContext(DbContextOptions<SQLDbContext> options) : base(options) { } public DbSet<IndexMessage> IndexMessage { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //初始化种子数据 modelBuilder.Entity<IndexMessage>() .HasData(new IndexMessage { Id = 1, Message = "这是一个测试发布的网站", Title = "自动化部署" }); modelBuilder.Entity<IndexMessage>() .HasData(new IndexMessage { Id = 2, Message = "这是2个测试发布的网站", Title = "2自动化部署" }); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); } }
public class IndexMessage { [Key] public int Id { get; set; } public string Message { get; set; } public string Title { get; set; } }
public class HomeController : Controller { private readonly SQLDbContext _dbContext; public HomeController(SQLDbContext dbContext) { _dbContext = dbContext; } // GET: HomeController public ActionResult Index() { var models = _dbContext.IndexMessage.ToList(); return View(models); } }
builder.Services.AddDbContext<SQLDbContext>(opt => { opt.UseSqlServer(builder.Configuration.GetConnectionString("DemoContext")); }); //设置自动迁移 using (var scope = app.Services.CreateScope()) { var dbcontext = scope.ServiceProvider.GetRequiredService<SQLDbContext>(); dbcontext.Database.Migrate(); }
appsettings.json添加数据库连接字符串配置:
{ …… "ConnectionStrings": { //"DemoContext": "Server=docker-sqlserver;Database=DemoDB;User Id=sa;Password=Password@2020;TrustServerCertificate=True;" "DemoContext": "Server=.;Database=DemoDB;User Id=sa;Password=Abc123456;TrustServerCertificate=True;" } }
添加迁移:
本地运行测试,自动创建数据库,运行正常。
yml file
右键项目-添加-容器业务流程协调程序支持,添加后会生成docker-compose相关文件:
version: '3.4'
services:
webapp:
image: ${DOCKER_REGISTRY-}webapp
build:
context: .
dockerfile: WebApp/Dockerfile
ports:
- "5000:80"
networks:
- webapp-network
depends_on:
- sql-server-db
sql-server-db:
image: mcr.microsoft.com/mssql/server:2019-CU5-ubuntu-18.04
ports:
- "1433:1433"
environment:
ACCEPT_EULA: Y
SA_PASSWORD: Password123
networks:
- webapp-network
networks:
webapp-network:
driver: bridge
services下定义了2个服务webapp、sql-server-db,相当于2个容器。webapp是基于webapp/Dockerfile构建的镜像${DOCKER_REGISTRY-}webapp来启动,depends_on用于指定依赖的服务,这里的webapp服务依赖于sql-server-db服务。
networks用于指定网络,因为docker中容器之间默认是无法直接通信的,这里创建了一个bridge模式的网络webapp-network,webapp和sql-server-db都在webapp-net网络中,那么他们之间就可以通过服务名来通信。
所以在上面webapp的数据库连接字符串中就可以写:Server=sql-server-db。通常数据库的数据目录会挂载到主机上,防止容器发生意外导致数据丢失。
up&down
来到项目根目录,启动PowerShell或cmd执行docker命令。
如果你想摧毁这个环境只需要执行docker-compose down
即可
可能存在的问题1:提示证书问题
按照提示执行命令创建并信任证书即可,如果还不能解决参照:解决ASP.NET Core通过docker-compose up启动应用无法配置https的解决办法 - 旋风小伙 - 博客园 (cnblogs.com)
这个问题是个神坑,很多方法都没能解决,最终重建了一个不配置https的项目解决。
docker-compose+镜像仓库部署
可以把镜像提前推送到镜像仓库,这样只需要一个yml文件就可以在其他机器轻松部署。
1、重新构建镜像:docker build -t xiaoqingyao/testpublish -f ./Dockerfile .
ps:xiaoqingyao是我的docker用户名,Dockerfile注意大小写
2、登录docker:docker login
,输入自己的用户名密码。
3、执行docker push xiaoqingyao/testpublish 推送到仓库
这里推送时候又被墙了,推不上去了,使用前面推送的镜像吧:
本地文件夹创建一个docker-compose.yml,内容如下
version: '3.4'
services:
mytest:
image: xiaoqingyao/testpub
ports:
- "5000:80"
networks:
- webapp-network
depends_on:
- sql-server-db
sql-server-db:
image: mcr.microsoft.com/mssql/server
ports:
- "1433:1433"
environment:
ACCEPT_EULA: Y
SA_PASSWORD: Password@2020
networks:
- webapp-network
networks:
webapp-network:
driver: bridge
cmd到当前目录并执行 docker-compose up
运行成功
学习源:.Net Core in Docker极简入门(下篇) - xhznl - 博客园 (cnblogs.com)