- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
本文首先简单介绍了 Dockerfile 内容和常用命令; 。
然后是在 Windows 环境 Docker desktop 的安装和配置; 。
最后创建了 Web API 示例项目,并简单说明了从构建到推送至 Harbor 镜像仓库的步骤.
#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"]
// 格式
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
类似命令行中的 cd 命令,设定之后后续的命令相当于在工作目录中运行 。
# 格式
WORKDIR /usr/workdir
# 示例
WORKDIR /a # (这时工作目录为:/a)
WORKDIR b # (这时工作目录为:/a/b)
WORKDIR /c # (这时工作目录为:/c)
# 格式
EXPOSE 80
EXPOSE 443
此命令只是声明容器打算使用什么端口,它并不会实际改变容器的网络设置.
也可以不配置 EXPOSE 参数来指定暴露的端口,可以通过配置环境变量的方式指定容器端口,例如:ENV ASPNETCORE_URLS=http://+:81.
这个命令非常简单,就是用于设置环境变量而已,无论是接下来的指令,还是在容器中运行的程序,都可以使用这里定义的环境变量.
# 格式
ENV <key>=<value>
# 示例,这个环境变量通常用于指定应用程序监听的 URL
ENV ASPNETCORE_URLS=http://+:81
# 表示应用程序将接受来自任何 IP 地址(由 + 表示)的连接请求,并使用端口 81 进行通信
这个命令可以拷贝当前宿主机的文件,也可以拷贝当前文件夹中编译后的文件到当前镜像.
# 第一个参数指的是源文件路径,【.】表示当前文件夹
# 第二个参数指的是目标路径,【.】表示将宿主机当前文件夹中的全部文件进行拷贝
COPY . .
# 使用【--from=publish】表示,从 publish 的镜像中拷贝文件,这里的 publish 是引入镜像时指定的别名
# 【/app/publish】是 publish 镜像的文件路径
# 最后这个【.】是指要拷贝到当前镜像来的目录,.表示当前路径,一般也是配合WORKDIR使用
COPY --from=publish /app/publish .
构建镜像的时候需要安装其他软件或者编译文件的命令都可以通过 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
指定容器启动的要运行的命令,可以追加命令 。
# 格式
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2 # shell 内部命令
# 示例
ENTRYPOINT ["dotnet", "Test.WebApplication1.ImgTest6.0.dll"]
# 相当于在命令行执行 dotnet Test.WebApplication1.ImgTest6.0.dll 这个命令
注意:只允许有一个 ENTRYPOINT 命令,多指定时会覆盖前面的设置,而只执行最后的 ENTRYPOINT 指令.
用于创建一个数据卷(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 。
打开“控制面板”,进入“程序和功能”,勾选“Hyper-V”和“适用于 Linux 的 Windows 子系统”:
安装完成后,按照提示需要重启.
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
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 相关服务开启情况 。
官网下载 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
在 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】,然后如下图操作,没有申请过的话需要申请下:
具体的配置,可以参考对应系统的操作文档,来更新配置.
在编辑器里创建新的项目,如下图勾选配置:
项目创建以后,会自动生成一个 Dockerfile 文件,需要对此文件做相应修改,详见本文 1.1 Dockerfile 文件示例.
如下示例文件目录:
首先在项目文件夹,打开命令行工具,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
解决方法:解决方案文件(.sln)需要和项目文件(.csproj、Dockerfile)在同一目录下.
根据提示内容,确认无法判断问题原因,实际上项目中就不包含 Main 这个方法.
详情可参考:https://stackoverflow.com/questions/52991469/getting-program-does-not-contain-a-static-main-method-suitable-for-an-entry-p 。
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 即可.
最后此篇关于.Net6.0WebAPI项目生成镜像并上传到私有仓库Harbor的文章就讲到这里了,如果你想了解更多关于.Net6.0WebAPI项目生成镜像并上传到私有仓库Harbor的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
如果需要在类外访问静态(例如单例),可以选择公共(public)静态而不是私有(private)静态,而当不需要公开函数时首选私有(private)静态(否则未命名的命名空间就可以了)——在这种情况下
在互联网上进行了一些搜索,但找不到简单的答案。我的问题集是在 Android 框架中使用 Java,但我相信这也是标准的 Java 行为。我理解 final 和 private 的定义,它们都用于变量
我有这个代码: public final class Board { private final int[][] blocks; private final int N; pr
对我来说,过去作为 Objective-C 开发人员很简单。一个类需要公开的每个字段都是一个属性,每个私有(private)字段都是一个没有 getter 或 setter 的实例变量。但我经常看到人
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我有一个在 Docker 容器中运行的应用程序。它需要来自公司私有(private) NPM 注册表(Sinopia)的一些私有(private)模块,并且访问这些需要用户身份验证。 Dockerfi
我试图理解 C# 使用 getters 和 setters 自动声明变量与 java 声明之间的区别。 在java中我通常这样做: private int test; public int getTe
我在 Azure 中创建了 VNET。我放入了一个子集 Azure Private Link,它在 VNET 之外和另一台虚拟机中调用 Azure Function。 当我尝试通过专用 IP 调用专用
我在 Azure 中创建了 VNET。我放入了一个子集 Azure Private Link,它在 VNET 之外和另一台虚拟机中调用 Azure Function。 当我尝试通过专用 IP 调用专用
我目前正在使用 Objective-C(适用于 iPhone)构建游戏。 为此,出于性能/复杂性原因,我略微打破了 MVC,并为 View (渲染器)提供了对模型的直接引用。这是因为它应该以 60fp
我已经在 ubuntu 上成功配置了 2 个虚拟主机站点(基于名称的虚拟主机)。我的 apache 版本是 2.2.22。 这两个站点都在本地主机上工作。 /etc/hosts 条目 127.0.0.
考虑下面的类 public class A { private final Map cache; public HeavyObject getThing(); } 假设不能泄漏对缓存
我有一个类,它有一个方法,我希望它只能被它的子对象访问,而不能被这个包中的其他类访问。 Modifier | Class | Package | Subclass | World ———————
本文实例讲述了JavaScript中的公有、私有、特权和静态成员用法。分享给大家供大家参考。具体分析如下: 下面的内容是在《JavaScript.DOM高级程序设计》里面摘抄出来的,比较容易理解,
我有一个用例,我已将其简化为以下程序: public class A { private int x = 100; class B { private int y = ne
问题: 类声明如下: class Select { public: template static Iterator function(Iterator , Iterator , bo
我是一名初级 PHP 程序员。我还有很多东西要学。这就是我问这个问题的原因。在一个类中,您有一个公共(public)函数,您可以从该类外部调用它。有时你有一个私有(private)函数,你可以在私有(
问题是: 何时使用私有(private)函数,何时使用嵌套函数? (我在问 F# 但也许答案可能与其他功能语言相关) 一个小例子 namespace SomeName module BinaryRea
我发现工作表中仍然可以使用私有(private)函数。它们是隐藏的,但如果用户输入他们的名字,他们就会被调用。为什么?它应该以这种方式工作吗?有没有办法完全阻止用户定义的函数在 VBA 项目之外使用?
所以我最近开始尝试使用 Kotlin,我偶然发现了这个: If a top-level declaration is marked private, it is private to the pack
我是一名优秀的程序员,十分优秀!