将.NetCore3.1程序部署到Docker上

Posted lishuangquan1987

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将.NetCore3.1程序部署到Docker上相关的知识,希望对你有一定的参考价值。

关于Docker的基本操作,请参考:Docker学习
本文使用的Linux系统是Centos8
使用的VS是VS2022
使用的数据库是mysql

为C#程序添加Dockerfile

右键单击启动项目,添加Docker支持:

选择Linux:

可以看到,自动添加了Dockerfile文件:

需要注意的是,自动生成的Dockerfile是需要将源码拷贝到Linux下进行打包构建镜像的。在构建镜像的时候,会编译源代码。自动生成的Dockerfile如下:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["Langtian.ServerAPI/Langtian.ServerAPI.csproj", "Langtian.ServerAPI/"]
COPY ["Langtian.ServerAPI.Model/Langtian.ServerAPI.Model.csproj", "Langtian.ServerAPI.Model/"]
COPY ["../../Langtian.DataBaseModel/Langtian.DatabaseModel/Langtian.DatabaseModel.csproj", "../../Langtian.DataBaseModel/Langtian.DatabaseModel/"]
COPY ["Langtian.ServerAPI.Dao/Langtian.ServerAPI.Dao.csproj", "Langtian.ServerAPI.Dao/"]
RUN dotnet restore "Langtian.ServerAPI/Langtian.ServerAPI.csproj"
COPY . .
WORKDIR "/src/Langtian.ServerAPI"
RUN dotnet build "Langtian.ServerAPI.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Langtian.ServerAPI.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Langtian.ServerAPI.dll"]

关于Dockerfile的指令意思,后面再写一篇文章单独介绍。
自动生成的Dockerfile文件分为多个镜像构建步骤。步骤如下:

  • 基础镜像->设置工作目录-开放端口
  • 设置工作目录->指定要复制的代码文件夹->还原Nuget包->复制所有指定的文件夹到镜像构建上下文->运行dotnet build编译项目,并设定输出到上下文的/app/build目录->运行dotnet publish发布项目文件到/app/pblish文件夹。
  • 从/app/publish文件夹,将全部文件复制到构建上下文。
  • 设置镜像启动的入口命令是 dotnet Langtian.ServerAPI.dll

由于我不想使用源代码构建,仅仅想发布后的文件拷贝到Linux上进行构建Docker镜像,所以Dockerfile修改如下:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 10000

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "Langtian.ServerAPI.dll"]

记得将Dockerfile设置为始终复制到输出目录:

发布C#程序到指定文件夹


选择发布后的文件夹:

选择部署模式和目标运行时:

选择好之后点击发布按钮:


发布成功之后,会看到文件夹中有了很多文件,其中包含Dockerfile:

将发布文件夹传递到Linux目录

本文使用FinalShell进行传递文件

使用Docker拉取Mysql镜像并运行

由于本程序依赖于Mysql,所以必须先运行Mysql。

拉取Mysql镜像

docker pull mysql:latest
latest: Pulling from library/mysql
ffbb094f4f9e: Pull complete 
df186527fc46: Pull complete 
fa362a6aa7bd: Pull complete 
5af7cb1a200e: Pull complete 
949da226cc6d: Pull complete 
bce007079ee9: Pull complete 
eab9f076e5a3: Pull complete 
8a57a7529e8d: Pull complete 
b1ccc6ed6fc7: Pull complete 
b4af75e64169: Pull complete 
23390142f76f: Pull complete 
Digest: sha256:ff9a288d1ecf4397967989b5d1ec269f7d9042a46fc8bc2c3ae35458c1a26727
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
[root@TONY ~]# 

查看下载的镜像:

创建容器并后台启动Mysql容器

docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:latest

指令解释:
run:创建并启动一个容器
-d:容器以后台的方式运行
-p:端口映射,前面一个是宿主主机端口,后面一个是docker容器的的端口
-e:Dockerfile中规定的环境变量,用于传递参数给应用程序。MYSQL_ROOT_PASSWORD是构建Mysql是指定的环境变量
最后一个就是镜像的名称。
一个镜像可以构建多个容器。

运行成功,会返回容器的ID

进入容器的Mysql命令行创建用户

由于root用户一般是不允许外部主机访问的,所以创建一个用户,用于外部主机(容器和容器之间的访问)访问Mysql
启动容器之后,可以查看运行的容器:

docker ps


进入容器的Mysql命令行:

docker exec -it dc26afdc79c9 bash

其中dc26afdc79c9为mysql容器的ID
进入命令行后,连接mysql:

mysql -uroot -p123456

Mysql创建用户

create user 'test'@'%' identified by 'Test@123';

'test'@'%' :指定用户名test可以所有IP访问
Test@123:密码
授予权限给用户:

grant all on *.* to 'test'@'%';

使用DBeaver连接容器中的Mysql测试

创建程序所需要的表…

至此Mysql在Docker容器中创建完成。

修改程序的数据库连接配置

上面我们已经把发布好的文件夹拷贝到/usr/docker-test/serverapi-linux目录下了
首先将当前目录切换到这个目录:

cd /usr/docker-test/serverapi-linux/

修改配置文件appsettings.json:

镜像构建

/usr/docker-test/serverapi-linux目录下,运行

docker build -t tony/mes-api:v1 .

-t:tag的意思。为镜像添加名称描述和版本。
注意:最后的.号不能够省略,表示Dockerfile在当前目录

终端输出如下所示:

[root@TONY serverapi-linux]# docker build -t tony/mes-api:v1 .
Sending build context to Docker daemon  22.96MB
Step 1/9 : FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
 ---> e41b25ecf8bf
Step 2/9 : WORKDIR /app
 ---> Running in 999fe0e888e6
Removing intermediate container 999fe0e888e6
 ---> 4e086f5a5f3d
Step 3/9 : EXPOSE 80
 ---> Running in 70f10b42dc56
Removing intermediate container 70f10b42dc56
 ---> 4ffbb0994640
Step 4/9 : EXPOSE 443
 ---> Running in 124a9021ac6e
Removing intermediate container 124a9021ac6e
 ---> 55dffdd77766
Step 5/9 : EXPOSE 10000
 ---> Running in 805b1407f45b
Removing intermediate container 805b1407f45b
 ---> 40947ed642d2
Step 6/9 : FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
 ---> 7ed1cf292591
Step 7/9 : WORKDIR /app
 ---> Using cache
 ---> 4b749088bd25
Step 8/9 : COPY . .
 ---> 6fee3d2c7bf8
Step 9/9 : ENTRYPOINT ["dotnet", "Langtian.ServerAPI.dll"]
 ---> Running in 2b722f14fcf6
Removing intermediate container 2b722f14fcf6
 ---> 85a682aa2c39
Successfully built 85a682aa2c39
Successfully tagged tony/mes-api:v1

查看构建的镜像:

[root@TONY serverapi-linux]# docker images
REPOSITORY                        TAG       IMAGE ID       CREATED         SIZE
tony/mes-api                      v1        7540b38c0667   5 minutes ago   208MB
<none>                            <none>    85ebc7de55eb   5 minutes ago   733MB
mcr.microsoft.com/dotnet/sdk      3.1       7ed1cf292591   6 days ago      710MB
mcr.microsoft.com/dotnet/aspnet   3.1       e41b25ecf8bf   6 days ago      208MB
mysql                             latest    bbf6571db497   7 days ago      516MB
[root@TONY serverapi-linux]# 

可以看到刚刚构建的tony/mes-api

使用镜像创建容器并运行

docker run -d -p 10000:10000  tony/mes-api:v1

查看容器是否在运行:

docker ps


使用网页访问一下服务:


本程序部署的结构图解如下:

以上是关于将.NetCore3.1程序部署到Docker上的主要内容,如果未能解决你的问题,请参考以下文章

到 Azure ACI 的基本容器化 ASP.NET 3.1 Core 应用部署失败

从.NET Core 3.1(Docker)迁移后,.NET 6 应用程序日志为 JSON 格式 [重复]

HTTP 错误 500.32 - 将自包含 .Net Core 3.1 应用程序部署到 Azure 后,ANCM 无法加载 dll

docker多个容器连接 将 Rails 程序部署到 Docker 容器中

使用docker将django应用程序部署到heroku时在哪里运行collectstatic?

Azure部署管道:将发行版添加到配置中