第五节:自定义制作Centos镜像 和 制作Asp.Net Core WebApi8.x 镜像并发布
一. 自定义Centos镜像
1. 要求
基于Centos7.0官方镜像制作一个自己的名为ypfcentos的镜像,版本为1.0,要求如下:
(1). 默认的登录路径 /ypfusr
(2). 可以使用vim
2. 步骤
(1). 下载一个centos7.0的官方镜像
【docker pull centos:7.0】 宿主机已经存在该镜像
(1). 在工作目录下通过指令新建一个文件夹‘ypfcentos’,用于存放自己改造的centos镜像的Dockerfile文件
【mkdir ypfcentos】
(2). 进入ypfcentos文件夹,新建一个ypfcentos_Dockerfile文件,复制下面内容。
【cd ypfcentos】
【vi ypfcentos_Dockerfile】
相关dockerfile代码如下
#1.定义依赖镜像(宿主机中没有话则去下载) FROM centos:7 #2.定义作者信息(可以不写) MAINTAINER ypf <ypf@qq.com> #3. 执行安装vim的命令(-y表示安装过程中不提示) RUN yum install -y vim #4. 定义默认的工作目录 WORKDIR /ypfusr #5 定义容器启动执行的命令 CMD /bin/bash

(3). 运行下面指令,进行镜像构建
【docker build -f ./ypfcentos_Dockerfile -t ypfcentos:1.0 . 】 其中 ./ 代表当前目录 等价于 【docker build -f ypfcentos_Dockerfile -t ypfcentos:1.0 . 】
或:【docker build -t ypfcentos:1.2 . 】 使用默认的Dockerfile命名,且在当前目录,则不需要通过-f指定路径了。(已测试)


(4). 将镜像发布成容器,并进入容器内部(交互式容器)
【docker run -it --name=ypfcentoscontainer1 ypfcentos:1.0 】

(5). 测试
【pwd】查看当前目录
【vim ypf.txt】测试vim指令是否可以使用

二. 制作WebApi8.x镜像并发布容器
1. 要求
基于webapi8.x版本,制作一个Asp.Net Core WebApi镜像,名为ypfwebapi,版本号为2.1 ,并发布成容器,名为ypfapi,要求如下:
(1). 容器内的工作目录为userapi
(2). 容器仅对外暴露端口8080
(3). 用户可以通过 http://xxxxx:8000/swagger/index.html 访问接口,获取数据
2 步骤
(1). 新建项目
新建一个Asp.Net Core WebApi项目,版本8.0 ,右键对其添加docker支持,会自动生成一个Dockerfile文件,如下:

PS:默认生成的Dockerfile文件不能直接使用,主要看看需要依赖哪些库,可以提前下载,查看一下最后的运行指令即可
默认的Dockerfile文件
# 请参阅 https://aka.ms/customizecontainer 以了解如何自定义调试容器,以及 Visual Studio 如何使用此 Dockerfile 生成映像以更快地进行调试。 # 此阶段用于在快速模式(默认为调试配置)下从 VS 运行时 FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base USER $APP_UID WORKDIR /app EXPOSE 8080 # 此阶段用于生成服务项目 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src COPY ["WebApi8.csproj", "."] RUN dotnet restore "./WebApi8.csproj" COPY . . WORKDIR "/src/." RUN dotnet build "./WebApi8.csproj" -c $BUILD_CONFIGURATION -o /app/build # 此阶段用于发布要复制到最终阶段的服务项目 FROM build AS publish ARG BUILD_CONFIGURATION=Release RUN dotnet publish "./WebApi8.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false # 此阶段在生产中使用,或在常规模式下从 VS 运行时使用(在不使用调试配置时为默认值) FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "WebApi8.dll"]
经分析,依赖于下面两个库,可以提前下载(不下载的话,docker build 构建的时候将自动下载)
【docker pull mcr.microsoft.com/dotnet/aspnet:8.0】
【docker pull mcr.microsoft.com/dotnet/sdk:8.0】
下载后如下图:

(2) 根据上述需求,制作自己的Dockerfile文件
#1.依赖两个基础镜像
FROM mcr.microsoft.com/dotnet/aspnet:8.0
FROM mcr.microsoft.com/dotnet/sdk:8.0
#2.制作人
MAINTAINER ypf <ypf@qq.com>
#3.指定程序运行的端口(也可以在项目中通过UseUrls指定, 或者发布容器的时候通过--env ASPNETCORE_URLS=xxx动态指定)
ENV ASPNETCORE_URLS=http://*:8080
#4.容器对外暴露的端口
EXPOSE 8080
#5.指定默认工作目录
WORKDIR /userapi
#6. 将当前目录(Dockerfile文件下)的所有文件拷贝到镜像的userapi工作目录下
COPY . /userapi/
#7.启动容器的时候执行shell命令:dotnet webapi1.dll,即运行该项目
ENTRYPOINT ["dotnet", "WebApi8.dll"]
剖析:
A. 必须至指定程序运行的端口【ENV ASPNETCORE_URLS=http://*:8080】,否则无法匹配。
B. 容器暴露的端口如上8080 一定要和程序运行的端口一致,上述Dockerfile文件是通过 ENV设置环境变量来设置程序运行端口的。 另外还有两种方式:程序中通过UseUrl来指定 或 构建容器的时候动态设置环境变量。(详见下面3补充)
C. 可以自定义Dockerfile文件名,比如:ypfdockerfile,但需要在构建容器的时候通过 -f 指定一下路径即可 。指令如下 【docker build -f dockerfile文件路径 -t 镜像名称:版本号 .】
(3) 发布项目,选择可移植

(4) 在centos系统,创建相应的目录,并拷贝发布包程序
【mkdir webapi】
【cd webapi】
【mkdir 8.0】
然后将发布包程序通过finalshell拷贝进来,默认发布包程序是不包含Dockerfile文件的,这里需要手动创建一个,然后把上面准备的内容copy进去
【mkdir Dockerfile】

(5). 进入8.0文件夹下,通过指令生成镜像
【docker build -t ypfwebapi:2.1 . 】,然后运行 【docker images】

(6). 通过下面指令,将镜像发布成容器
【docker run -id --name=ypfapi -p 8000:8080 ypfwebapi:2.1】 然后通过指令 【docker ps】查看镜像

(7). 测试
A. 通过指令 【docker exec -it ypfapi bash】, 进入容器,发现默认路径为userapi

B. 访问 http://xx. 205.120.80:8000/swagger/index.html ,如下图

(8). 总结
在该容器内,查看工作目录下的内容 【ls】,发现就是发布包中的内容哦,这时通过Dockerfile中的 【copy . /userapi/】实现的。

说白了:
这里webapi部署成容器就是把依赖的环境和发布包的内容整合到一起,最后通过Dockerfile中的 ENTRYPOINT ["dotnet", "webapi8.dll"] 运行该项目。
三. 补充说明
1. 关于程序端口的另外两种写法
A. Dockerfile文件中不指定程序运行端口,通过构建容器指令来指定程序运行端口。
dockerfile文件如下:
#1.依赖两个基础镜像 FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster #2.制作人 MAINTAINER ypf <ypf@qq.com> #3.容器对外暴露的端口 EXPOSE 9000 #4.指定默认工作目录 WORKDIR /userapi #5. 将当前目录(Dockerfile文件下)的所有文件拷贝到镜像的userapi工作目录下 COPY . /userapi/ #6.启动容器的时候执行shell命令:dotnet webapi1.dll,即运行该项目 ENTRYPOINT ["dotnet", "webapi1.dll"]
相关指令如下:
#构建镜像 docker build -t ypfwebapi3 . #发布容器 docker run --env ASPNETCORE_URLS=http://*:9000 -id --name=ypfwebapicontainer3 -p 8002:9000 ypfwebapi3
测试连接:http://119.45.174.249:8002/weatherforecast
B. Dockerfile文件中不指定程序运行端口,在代码里指定端口
程序代码:

dockerfile文件同上一样:
#1.依赖两个基础镜像 FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster #2.制作人 MAINTAINER ypf <ypf@qq.com> #3.容器对外暴露的端口 EXPOSE 9000 #4.指定默认工作目录 WORKDIR /userapi #5. 将当前目录(Dockerfile文件下)的所有文件拷贝到镜像的userapi工作目录下 COPY . /userapi/ #6.启动容器的时候执行shell命令:dotnet webapi1.dll,即运行该项目 ENTRYPOINT ["dotnet", "webapi1.dll"]
相关指令:
#构建镜像 docker build -t ypfwebapi4 . #发布容器 docker run -id --name=ypfwebapicontainer4 -p 8004:9000 ypfwebapi4
2. 尝试一下,一个项目能不能同时挂多个端口。
答案:不行,当设置多个程序运行端口(非容器端口!!)的时候,仅最后一个有效。

3 . COPY 和 ADD 二者基本等效
只能复制Dockerfile所在目录下的文件;复制的镜像内的路径如果不存在,会自动创建。

Linux中相关操作截图:

4. CMD 和 ENTRYPOINT 效果一致,下面四行指令等效
# 启动容器时候的指令等价于下面的4种写法: # ENTRYPOINT ["dotnet", "webapi1.dll"] # ENTRYPOINT dotnet webapi1.dll # CMD ["dotnet", "webapi1.dll"] # CMD dotnet webapi1.dll
5. -P 随机端口映射的问题
A. 使用上述的ypfwebapi1镜像,是-P随机指定端口
【docker run -id --name=test1 -P ypfwebapi1】

B. 使用一个新的Dockerfile文件,对外暴露3个端口,通过-P随机指定所有暴露端口。

docker build -t ypfwebapi5 .
docker run -id --name=ypfwebapicontainer5 -P ypfwebapi5

四. 制作WebApi镜像并发布容器--旧版
1. 要求
制作一个Asp.Net Core WebApi镜像,名为ypfwebapi1,并发布成容器,名为ypfwebapicontainer1,要求如下:
(1). 容器内的工作目录为userapi
(2). 容器仅对外暴露端口9000
(3). 用户可以通过 http://xxxxx:8000/weatherforecast 访问接口,获取数据
2. 步骤
(1). 新建一个Asp.Net Core WebApi项目,版本3.1 ,右键对其添加docker支持,会自动生成一个Dockerfile文件,如下:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base WORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build WORKDIR /src COPY ["webapi1/webapi1.csproj", "webapi1/"] RUN dotnet restore "webapi1/webapi1.csproj" COPY . . WORKDIR "/src/webapi1" RUN dotnet build "webapi1.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "webapi1.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "webapi1.dll"]
分析Dockerfile文件,我们得知,该项目需要依赖的两个基础镜像为,其它内容,我们自行来编辑
mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim
mcr.microsoft.com/dotnet/core/sdk:3.1-buster
(2). 根据要求,自定义的Dockerfile文件内容如下:
#1.依赖两个基础镜像 FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster #2.制作人 MAINTAINER ypf <ypf@qq.com> #3.指定程序运行的端口(也可以在项目中通过UseUrls指定, 或者发布容器的时候通过--env ASPNETCORE_URLS=xxx动态指定) ENV ASPNETCORE_URLS=http://*:9000 #4.容器对外暴露的端口 EXPOSE 9000 #5.指定默认工作目录 WORKDIR /userapi #6. 将当前目录(Dockerfile文件下)的所有文件拷贝到镜像的userapi工作目录下 COPY . /userapi/ #7.启动容器的时候执行shell命令:dotnet webapi1.dll,即运行该项目 ENTRYPOINT ["dotnet", "webapi1.dll"]
说明:
A. 可以自定义Dockerfile文件名,比如:ypfdockerfile,但需要在构建容器的时候通过 -f 指定一下路径即可 。指令如下 【docker build -f dockerfile文件路径 -t 镜像名称:版本号 .】
B. 容器暴露的端口如上9000 一定要和程序运行的端口一致,上述Dockerfile文件是通过 ENV设置环境变量来设置程序运行端口的。 另外还有两种方式:程序中通过UseUrl来指定 或 构建容器的时候动态设置环境变量。(详见下面3补充)
(3). 将项目进行发布,目标运行时选择:可移植,并把Dockerfile文件复制到发布包根目录下


(4). 登录linux服务器,运行下面指令,下载必备的程序镜像
docker pull mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim docker pull mcr.microsoft.com/dotnet/core/sdk:3.1-buster
PS: 这里也可以不下载,等构建镜像的时候如果检测到Linux宿主机上没有该镜像,也会自动下载,这里建议提前下载。
(5). 在Linux的工作目录下新建myprogram文件夹,用于存放需要程序的发布包,进入该目录,然后新建ypfwebapi1文件夹,用于存放该项目的发布包。
【mkdir myprogram】
【cd myprogram】
【mkdir ypfwebapi1】

(6). 通过WinSCP软件,将项目发布包复制到ypfwebapi1文件夹下

(7). 进入ypfwebapi1文件夹下,通过指令生成镜像
【docker build -t ypfwebapi1 . 】


(8). 通过下面指令,将镜像发布成容器
【docker run -id --name=ypfwebapicontainer1 -p 8000:9000 ypfwebapi1】

(9). 测试:
A. 通过指令【docker exec -it 8ff5c6e7a5d8 bash】进入,容器查看工作目录为userapi

B. 用PostMan进行get请求 http://119.45.174.249:8000/weatherforecast,获取返回值,测试通过。

(10). 总结:
在该容器内,查看工作目录下的内容 【ls】,发现就是发布包中的内容哦,这时通过Dockerfile中的 【copy . /userapi/】实现的。

说白了:
这里webapi部署成容器就是把依赖的环境和发布包的内容整合到一起,最后通过Dockerfile中的 ENTRYPOINT ["dotnet", "webapi1.dll"] 运行该项目。
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。

浙公网安备 33010602011771号