〇、前言

本文首先简单介绍了 Dockerfile 内容和常用命令;

然后是在 Windows 环境 Docker desktop 的安装和配置;

最后创建了 Web API 示例项目,并简单说明了从构建到推送至 Harbor 镜像仓库的步骤。

一、关于 Dockerfile

1.1 Dockerfile 文件示例

#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app # EXPOSE 811
# EXPOSE 443
# EXPOSE 可以注释掉,以环境变量 ASPNETCORE_URLS 配置为准
ENV ASPNETCORE_URLS=http://+:811 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["Test.WebApplication1.ImgTest6.0.csproj", "."]
RUN dotnet restore "./Test.WebApplication1.ImgTest6.0.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "Test.WebApplication1.ImgTest6.0.csproj" -c Release -o /app/build FROM build AS publish
RUN dotnet publish "Test.WebApplication1.ImgTest6.0.csproj" -c Release -o /app/publish /p:UseAppHost=false # 设置时间为中国上海
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 设置环境为开发环境
ENV ASPNETCORE_ENVIRONMENT=Development FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Test.WebApplication1.ImgTest6.0.dll"]

1.2 常见命令

1.2.1 FROM 指定基础镜像或创建新的镜像阶段

// 格式
FROM <image>  # 没有 tag 或 digest 时,默认使用 latest 版本
FROM <image>:<tag>  # tag 标签
FROM <image>:<digest>  # digest 摘要(通常是一个SHA256哈希值)
// 例如
FROM nginx
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
FROM ubuntu:18.04@sha256:3c7f9d4a8b1f3e4e8b1f3e4e8b1f3e4e8b1f3e4e8b1f3e4e8b1f3e4e8b1f3e4

Dockerfile 文件首行命令一定是 FROM 指令。当同时需要多个进出镜像时,可重复使用。

FROM 还有另外一个用途,为镜像创建一个副本,标识一个镜像阶段。

例如下面示例中的第二行命令:

# 【构建阶段】
# 使用 dotnet build 命令编译项目,此阶段的目的是编译源代码,准备用于发布
RUN dotnet build "Test.WebApplication1.ImgTest6.0.csproj" -c Release -o /app/build
# 【准备发布】
# “publish”阶段是通过本命令创建的,这一阶段从“build”阶段继承了编译好的代码,然后准备发布
FROM build AS publish
# 【发布阶段】
# 使用 dotnet publish 命令将应用程序发布到 /app/publish 目录
# 发布操作包括优化应用程序以减少其大小、生成运行时依赖项等
RUN dotnet publish "Test.WebApplication1.ImgTest6.0.csproj" -c Release -o /app/publish /p:UseAppHost=false

1.2.2 WORKDIR 设定工作目录

类似命令行中的 cd 命令,设定之后后续的命令相当于在工作目录中运行

# 格式
WORKDIR /usr/workdir
# 示例
WORKDIR /a # (这时工作目录为:/a)
WORKDIR b # (这时工作目录为:/a/b)
WORKDIR /c # (这时工作目录为:/c)

1.2.3 EXPOSE 指定与外界交互的端口

# 格式
EXPOSE 80
EXPOSE 443

此命令只是声明容器打算使用什么端口,它并不会实际改变容器的网络设置。

也可以不配置 EXPOSE 参数来指定暴露的端口,可以通过配置环境变量的方式指定容器端口,例如:ENV ASPNETCORE_URLS=http://+:81

1.2.4 ENV 设置环境变量

这个命令非常简单,就是用于设置环境变量而已,无论是接下来的指令,还是在容器中运行的程序,都可以使用这里定义的环境变量。

# 格式
ENV <key>=<value>
# 示例,这个环境变量通常用于指定应用程序监听的 URL
ENV ASPNETCORE_URLS=http://+:81
# 表示应用程序将接受来自任何 IP 地址(由 + 表示)的连接请求,并使用端口 81 进行通信

1.2.5 COPY 拷贝文件

这个命令可以拷贝当前宿主机的文件,也可以拷贝当前文件夹中编译后的文件到当前镜像。

# 第一个参数指的是源文件路径,【.】表示当前文件夹
# 第二个参数指的是目标路径,【.】表示将宿主机当前文件夹中的全部文件进行拷贝
COPY . .
# 使用【--from=publish】表示,从 publish 的镜像中拷贝文件,这里的 publish 是引入镜像时指定的别名
# 【/app/publish】是 publish 镜像的文件路径
# 最后这个【.】是指要拷贝到当前镜像来的目录,.表示当前路径,一般也是配合WORKDIR使用
COPY --from=publish /app/publish .

1.2.6 RUN 构建镜像

构建镜像的时候需要安装其他软件或者编译文件的命令都可以通过 RUN 命令执行。

# 格式
RUN <command> # shell 执行
RUN ["executable", "param1", "param2"] # exec 执行

多条命令可以用 && 来连接,以发布 ASP.NET Core 项目为例,将代码拷贝到镜像之后,需要进行 restore、build、publish,就可以在这里使用,例如:

RUN dotnet restore "./Test.WebApplication1.ImgTest6.0.csproj" && dotnet build "./Test.WebApplication1.ImgTest6.0.csproj" -c Release -o /app/build && dotnet publish "./Test.WebApplication1.ImgTest6.0.csproj" -c Release -o /app/publish /p:UseAppHost=false

1.2.7 ENTRYPOINT 容器启动命令

指定容器启动的要运行的命令,可以追加命令

# 格式
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2 # shell 内部命令
# 示例
ENTRYPOINT ["dotnet", "Test.WebApplication1.ImgTest6.0.dll"]
# 相当于在命令行执行 dotnet Test.WebApplication1.ImgTest6.0.dll 这个命令

注意:只允许有一个 ENTRYPOINT 命令,多指定时会覆盖前面的设置,而只执行最后的 ENTRYPOINT 指令

1.2.8 VOLUME 指定持久化目录

用于创建一个数据卷(volume),它允许将容器内的目录或文件与宿主机进行共享,卷会一直存在,直到没有任何容器在使用它。

通过使用数据卷,可以在容器之间共享数据,或者在容器重启时保留数据。对卷的修改会立即生效,但不会对镜像产生影响。

# 格式
VOLUME ["/path/to/dir"]
# 示例
VOLUME ["/data"] # 创建了一个名为/data的数据卷
VOLUME ["/var/www", "/var/log/apache2"] # 同时创建两个数据卷

注意:VOLUME 指令只是声明了数据卷的位置,并不会实际创建它们。数据卷的创建是在容器运行时进行的,通常是通过 docker run 命令或 Docker Compose 等工具来完成。

参考: https://blog.csdn.net/WuLex/article/details/113730475    https://blog.csdn.net/guojiaqi_/article/details/135909376

二、构建镜像并推送到 Harbor

2.1 Docker 安装

2.1.1 环境准备

  • 启用相关 Windows 功能

打开“控制面板”,进入“程序和功能”,勾选“Hyper-V”和“适用于 Linux 的 Windows 子系统”:

安装完成后,按照提示需要重启。

  • 安装 wsl

WSL(Windows Subsystem for Linux)是 Windows 10 的一个子系统,它允许用户在 Windows 上运行 Linux 发行版。

通过 WSL,用户可以在 Windows 上安装和运行 Linux 命令行工具、应用程序和环境,而无需使用传统的虚拟机或双启动设置。

wsl --install

检查是否安装成功

如下图运行wsl --list --verbose或简化为wsl -l -v,列出所有已安装的WSL分发版及其版本号,以及如何进入 wsl 命令模式:

另外,如何实现 WSL 和 Windows 文件系统互相访问?

在 WSL 中,你可以通过/mnt/目录访问 Windows 文件系统。例如,要在 WSL 中访问 C 盘的某个文件,可以使用以下路径:

/mnt/c/path/to/your/file.txt

在Windows中,你可以通过\\wsl$\路径访问WSL文件系统。例如,要在Windows中访问WSL的某个文件,可以使用以下路径:

\\wsl$\your_linux_distro\home\your_username\path\to\your\file.txt

2.1.2 环境准备中遇到的问题

1/3)安装 wsl 过程中出现如下报错,输出全是 ????? 报错提示不明确

C:\WINDOWS\system32>wsl --install
正在安装: Ubuntu
已安装 Ubuntu。
正在启动 Ubuntu...
Installing, this may take a few minutes...
WslRegisterDistribution failed with error: 0x80370114
Error: 0x80370114 ??????????????????
Press any key to continue...
分发“Ubuntu”的安装过程失败,退出代码: 1。
Error code: Wsl/InstallDistro/WSL_E_INSTALL_PROCESS_FAILED

解决步骤如下:

在 win10 搜索框搜索“应用和浏览器控制”,进入该界面
点击“Exploit Protection设置”
切换到"程序设置"
下拉找到“C:\WINDOWS\System32\vmcompute.exe”,点击编辑
找到“控制流保护(CFG)”,取消下面的“替代系统设置”。
打开 windows 命令行 ,输入“net start vmcompute”

参考:https://blog.csdn.net/gyjjj12/article/details/115531298

2/3)上边最后一部重启 vmcompute 时提示系统错误 1058

C:\WINDOWS\system32>net start vmcompute
发生系统错误 1058。
无法启动服务,原因可能是已被禁用或与其相关联的设备没有启动。

解决方法:

  服务【Hyper-V 主机计算服务】被禁用了或没有运行,开启即可。

3/3)检查下 Hyper-V 相关服务开启情况

2.1.3 下载和安装

官网下载 Docker Desktop Installer.exe:https://www.docker.com/products/docker-desktop/

双击下载安装包(Docker Desktop Installer.exe)进行安装,如下图,第一项建议勾选:

然后点击 OK 按钮,完成安装。

另外,关于 WSL 2 和 Hyper-V:

WSL 2 相较于 Hyper-V 有更低的资源占用;
WSL 2 允许用户在不启动完整虚拟机的情况下运行容器,这简化了操作并减少了系统的复杂性;
对于仅需要运行 Docker 容器的用例,WSL 2 提供了足够且优化过的支持;
如果需要使用其他虚拟机或需要精细控制 Docker 资源分配,则可能需要依赖 Hyper-V;
当使用 WSL 2 作为后端时,Docker 镜像和容器无法在不同的 Windows 用户账户之间共享。

验证是否安装成功

直接打开或以管理员身份运行 Docker Desktop。

启动后 Docker 是 running 状态,如下图:

如下简单操作测试 Docker 是否安装成功:

# 查看版本
C:\WINDOWS\system32>docker -v
Docker version 27.1.1, build 6312585
# 尝试拉取测试镜像 hello-world
C:\WINDOWS\system32>docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:1408fec50309afee38f3535383f5b09419e6dc0925bc69891e79d84cc4cdcec6
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest
...
# 运行测试镜像 hello-world,成功输出:Hello from Docker!
C:\WINDOWS\system32>docker run hello-world Hello from Docker!
This message shows that your installation appears to be working correctly.
# 查看当前全部镜像
C:\WINDOWS\system32>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d2c94e258dcb 15 months ago 13.3kB

2.1.4 Docker 必要的配置

  • 国内镜像仓库配置

在 Docker-->Setting-->Docker Engine 模块的配置中,新增配置项"registry-mirrors":(推荐使用阿里云的镜像地址,后边有详解如何获取)

{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"registry-mirrors": [
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}

其中,"http://hub-mirror.c.163.com"为网易云镜像地址;"https://docker.mirrors.ustc.edu.cn"为中国科学大学镜像地址。

最后点击“apply & restart”会自动重启 Docker,使新配置项生效。也可以通过命令docker info来查看当前的全部配置项。

推荐使用个人阿里云镜像地址,需要单独申请,方法:登录地址【https://cr.console.aliyun.com】,然后如下图操作,没有申请过的话需要申请下:

  

具体的配置,可以参考对应系统的操作文档,来更新配置。

2.2 创建 Web API 项目

在编辑器里创建新的项目,如下图勾选配置:

项目创建以后,会自动生成一个 Dockerfile 文件,需要对此文件做相应修改,详见本文 1.1 Dockerfile 文件示例

如下示例文件目录:

2.3 镜像编译并推送到 Harbor 镜像库

首先在项目文件夹,打开命令行工具,Shift+鼠标右键,选择“在此处打开 Powershell 窗口”,打开后,输入 cmd,进入命令行模式。

第一步:镜像构建

通过 build 语句,构建项目:

docker build -t test-dotnet/testwebapplication1imgtest60:stage_v1.0 .

其中,test-dotnet 表示项目名称,test-dotnet/testwebapplication1imgtest60 表示镜像名称,冒号后边的 stage_v1.0 是给镜像打的标签。

第二步:打标签

将本地的镜像对应到私有 Harbor 仓库中的镜像:(harbor.xxxx.com 为仓库的域名,需要更换成自己的)

docker tag test-dotnet/testwebapplication1imgtest60:stage_v1.0 harbor.xxxx.com/test-dotnet/testwebapplication1imgtest60:stage_v1.0

随后一步:将本地镜像推送到远程仓库

// 先登录
docker login harbor.xxxx.com
// 登录成功后,再推送
docker push harbor.xxxx.com/test-dotnet/testwebapplication1imgtest60:stage_v1.0

最后再登录 Harbor 进行仓库,查看对应标签的镜像是否已经上传成功。

确认推送成功后,接口通过镜像地址来拉取。例如:

// 域名+项目名称+Tag,拉取指定版本
docker pull harbor.xxxx.com/test-dotnet/testwebapplication1imgtest60:stage_v1.0

2.4 镜像构建和推送过程中遇到的问题

2.4.1 Program does not contain a static 'Main' method suitable for an entry point

解决方法:解决方案文件(.sln)需要和项目文件(.csproj、Dockerfile)在同一目录下。

根据提示内容,确认无法判断问题原因,实际上项目中就不包含 Main 这个方法。

详情可参考:https://stackoverflow.com/questions/52991469/getting-program-does-not-contain-a-static-main-method-suitable-for-an-entry-p

2.4.2 Docker 运行异常导致的 Error 提示

ERROR: request returned Internal Server Error for API route and version http://%2F%2F.%2Fpipe%2FdockerDesktopLinuxEngine/_ping, check if the server supports the requested API version

重启下 Docker Desktop 即可。

.Net 6.0 Web API 项目生成镜像并上传到私有仓库 Harbor的更多相关文章

  1. 一个简单的QQ隐藏图生成算法 通过jQuery和C#分别实现对.NET Core Web Api的访问以及文件上传

    一个简单的QQ隐藏图生成算法   隐藏图不是什么新鲜的东西,具体表现在大部分社交软件中,预览图看到的是一张图,而点开后看到的又是另一张图.虽然很早就看到过这类图片,但是一直没有仔细研究过它的原理,今天 ...

  2. 用eclipse怎样将本地的项目打成jar包上传到maven仓库

    使用maven的项目中,有时需要把本地的项目打成jar包上传到mevan仓库. 操作如下: 前提:pom文件中配置好远程库的地址,否则会报错 1.将maven 中的settings文件配置好用户名和密 ...

  3. 通过jQuery和C#分别实现对.NET Core Web Api的访问以及文件上传

    准备工作: 建立.NET Core Web Api项目 新建一个用于Api请求的UserInfo类 public class UserInfo { public string name { get; ...

  4. 【docker】将Java jar文件生成镜像、上传镜像并生成镜像压缩文件

    概述 将Springboot的web服务打包成Jar包后,自动化脚本将jar打包成镜像.上传镜像.并生成镜像的压缩文件: Dockerfile FROM 10.254.9.21/library/ora ...

  5. 从0到1手把手教你ASP.NET Core Web API项目配置接口文档Swagger(二)

    传送门:从0到1手把手教你ASP.NET Core Web API项目配置接口文档Swagger(一) 一.设置Swagger页面为首页--开发环境 我们虽然可以在输入 /swagger 后顺利的访问 ...

  6. 从0到1手把手教你ASP.NET Core Web API项目配置接口文档Swagger(一)

    一.创建ASP.NET Core Web API项目(若项目已创建,则可跳过本节内容) 1.双击打开VS2022. 2.单击"创建新项目",如下图. 3.选择"ASP.N ...

  7. 用VSCode开发一个asp.net core2.0+angular5项目(5): Angular5+asp.net core 2.0 web api文件上传

    第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 第二部分: http://www.cnblogs.com/cgzl/p/8481825.html 第三 ...

  8. 在Docker容器中运行.Net Core web Api项目

    安装Docker环境 参考本人这篇<CentOS 7 下Docker的安装>文章进行安装以及环境配置,这里不做赘述. 通过.NetCore开发WebApi项目 1. 创建.Net Core ...

  9. Web API项目中使用Area对业务进行分类管理

    在之前开发的很多Web API项目中,为了方便以及快速开发,往往把整个Web API的控制器放在基目录的Controllers目录中,但随着业务越来越复杂,这样Controllers目录中的文件就增加 ...

  10. 【WEB API项目实战干货系列】- API登录与身份验证(三)

    上一篇: [WEB API项目实战干货系列]- 接口文档与在线测试(二) 这篇我们主要来介绍我们如何在API项目中完成API的登录及身份认证. 所以这篇会分为两部分, 登录API, API身份验证. ...

随机推荐

  1. NOIP模拟82

    T1 魔法 解题思路 发现选择情况无非就是两种,连续的一段或者间隔为 \(R+B\) 的倍数的一段. 直接对于原序列贪心,每次选择可以消除的部分并将其删掉. 对于合法的情况将操作倒序输出即可. cod ...

  2. C# 配置文件增加自定义节点

    话不多说直接开撸! 首先创建一个Config的文件夹然后新增一个后缀名为.config的文件 配置文件的代码如下: <?xml version="1.0" encoding= ...

  3. LeetCode 673. Number of Longest Increasing Subsequence 最长递增子序列的个数 (C++/Java)

    题目: Given an unsorted array of integers, find the number of longest increasing subsequence. Example ...

  4. SQL SERVER 2012的安装

    1.将光盘镜像用虚拟光驱加载(WIN10自带虚拟光驱) 2.双击setup.exe 3.选择"安装"-"全新 SQL Server 独立安装或向现有安装添加功能" ...

  5. TiDB 多集群告警监控-初章-监控融合、自动告警处理

    author:longzhuquan 背景 随着公司XC改造步伐的前进,越来越多的业务选择 TiDB,由于各个业务之间需要物理隔离,避免不了的 TiDB 集群数量越来越多.虽然每套 TiDB 集群均有 ...

  6. 《Android开发卷——设置圆形头像,Android截取圆形图片》

    在有一些程序开发中,有时候会用到圆形,截取一张图片的一部分圆形,作为头像或者其他. 本实例就是截图圆形,设置头像的.      首先讲解一些代码 <ImageView android:id=&q ...

  7. == 和 equals 的区别是什么

    == : 它的作用是判断两个对象的地址是不是相等.即,判断两个对象是不是同一个对象.(基本数据类型 == 比较的是值,引用数据类型 == 比较的是内存地址) equals() : 它的作用也是判断两个 ...

  8. 写的程序总是出 BUG,只好请佛祖前来镇楼啦

    前言 自己之前写着玩的,在这做个备份,感觉不错的取走即可. 南无阿弥陀佛 佛祖镇楼,BUG 消失,永不怠机. ///////////////////////////////////////////// ...

  9. Libgdx游戏开发(3)——通过柏林噪音算法地图随机地形

    原文: Libgdx游戏开发(3)--通过柏林噪音算法地图随机地形-Stars-One的杂货小窝 在B站刷到了随机地图生成的视频,随手学习下并做下记录 注: 本篇使用javafx应用作演示,算是了解这 ...

  10. 高德解析城市的分析,根据高德的经纬度获取城市cityCode

    高德解析城市的分析,根据高德的经纬度获取城市cityCode http://restapi.amap.com/v3/geocode/regeo?output=json&location=110 ...