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 build(可省略)

执行docker-compose up启动

 启动成功后浏览器访问成功:http://localhost:5000/

如果你想摧毁这个环境只需要执行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)

 

posted @ 2023-05-26 11:12  chenxizhaolu  阅读(3501)  评论(0编辑  收藏  举报