.NET的Dockerfile文件编写要点——以WOL项目为例

这篇具有很好参考价值的文章主要介绍了.NET的Dockerfile文件编写要点——以WOL项目为例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文以 WOL 的.NET 项目为例,介绍了 Dockerfile 的基础知识和编写要点,旨在帮助读者更好地理解和掌握如何为 .NET 应用创建和优化 Dockerfile。

1. 背景

前面我们已经勾选了 Docker 容器化支持,项目已经生成了一个默认的 Dockerfile。但在实际项目中,我们需要根据项目的实际需求和环境来定制化 Dockerfile,以便更好地利用 Docker 的优势。本文将以 WOL (Wake On LAN) 项目为例,详细介绍如何编写一个针对 .NET 应用的 Dockerfile 文件,并分享一些实用的编写技巧。

2. 从默认模板入手

2.1 默认模板

以下是 .NET8 中 Web API 项目的默认模板,在这个默认模板中,我们可以看到一个典型的多阶段构建过程。

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base  
USER app  
WORKDIR /app  
EXPOSE 8080  
EXPOSE 8081  

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build  
ARG BUILD_CONFIGURATION=Release  
WORKDIR /src  
COPY ["WebApplication3/WebApplication3.csproj", "WebApplication3/"]  
RUN dotnet restore "./WebApplication3/./WebApplication3.csproj"  
COPY . .  
WORKDIR "/src/WebApplication3"  
RUN dotnet build "./WebApplication3.csproj" -c $BUILD_CONFIGURATION -o /app/build  

FROM build AS publish  
ARG BUILD_CONFIGURATION=Release  
RUN dotnet publish "./WebApplication3.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false  

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

2.2 模板介绍

根据默认模板,我们先来复习一下 Dockerfile 的基本结构:

  1. FROM:指定基础镜像,并可以使用 AS 为这个阶段设置别名,如 FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
  2. USER:设置运行时的用户,如 USER app
  3. WORKDIR:设置工作目录,如 WORKDIR /app
  4. EXPOSE:暴露容器需要监听的端口,如 EXPOSE 8080EXPOSE 8081
  5. COPY:复制文件或目录,如 COPY ["WebApplication3/WebApplication3.csproj", "WebApplication3/"]
  6. RUN:执行命令,如 RUN dotnet restore "./WebApplication3/./WebApplication3.csproj"
  7. ARG:定义构建参数,如 ARG BUILD_CONFIGURATION=Release
  8. ENTRYPOINT:指定容器启动时执行的命令,如 ENTRYPOINT ["dotnet", "WebApplication3.dll"]

在默认模板中,我们还可以看到一个典型的多阶段构建过程。多阶段构建可以减小最终生成的镜像大小,提高构建速度。在上述示例中,我们使用了四个阶段,分别命名为 base、build、publish 和 final,用于不同的构建和运行阶段。

3. WOL 项目的 Dockerfile

一般来说使用默认的 Dockerfile 就可以了,但是有时候我们需要根据项目的特定需求和环境对 Dockerfile 进行调整和优化。

3.1 额外的依赖

项目可能需要一些额外的系统依赖或者工具。可以通过 RUN 指令和包管理器(如 apt-get、yum 等)来安装这些依赖。有时我们可以在编程中就能发现并意识到,但是更多的时候需要我们在容器化后对项目做好测试工作,确保所有功能都能正常运行。

比如在 WOL 项目的工具类中有写这样一个检查设备是否在线的函数:

internal static bool Ping(string iP)
{
    // 检查IP是否在线
    Ping ping = new Ping();
    PingReply pingReply = ping.Send(iP,100);
    return pingReply.Status == IPStatus.Success;
}

写起来倒是很简单,也很省事。但是如果不知道其运行原理的话,就会在容器化后遇到问题。这个函数使用了 System.Net.NetworkInformation.Ping 类来检查目标 IP 地址是否在线,但是其依然是使用了系统的 Ping 工具来处理。Docker 的 Base 镜像都是最简版本,为了轻便,都是不包含 Ping 工具的。

为了解决这个问题,我们就需要将缺失的依赖安装恢复,Debian 的 Ping 工具包为 Iputils-ping,在 final 阶段通过 apt 安装即可。

3.2 更改安装源

在上一节中,我们讨论了安装额外依赖的必要性。为了加速镜像构建过程中的软件包安装,我们可以考虑修改安装源。通常,我们会在物理机上更改镜像源以加速软件包的安装。同样的方法也适用于容器镜像的构建过程。如果不更改安装源,一个镜像的构建可能会花费数小时,这对于开发者来说是难以忍受的。

在使用 mcr.microsoft.com/dotnet/aspnet:8.0 镜像时,底层基于 Debian 系统。为了加速软件包的安装,我们可以更改安装源。在这个例子中,我们将安装源更改为清华大学的镜像源。以下是如何在 Dockerfile 中进行更改的示例:

sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/debian.sources && \
apt-get update

这段代码使用 sed 命令修改了 /etc/apt/sources.list.d/debian.sources 文件中的安装源,将其从 deb.debian.org 更改为了 mirrors.tuna.tsinghua.edu.cn。接下来,使用 apt-get update 命令更新软件包列表。

通过这样的设置,我们可以加速后续软件包的下载和安装过程,从而提高整体镜像构建速度。

3.3 清理垃圾

在执行 apt update 和安装软件包之后,我们需要注意清理系统中产生的缓存和临时文件。这些文件会增加镜像的大小,而在大多数情况下,它们在运行时并不需要。因此,我们可以在 Dockerfile 中添加相应的指令来清理这些垃圾文件,从而减小最终生成的镜像大小。

在使用 apt-get 安装软件包后,可以使用以下命令清理缓存:

apt-get clean
rm -rf /var/lib/apt/lists/*

这段代码首先使用 apt-get clean 命令清理软件包缓存,然后使用 rm -rf /var/lib/apt/lists/* 删除下载的软件包列表。这样一来,我们就可以在构建过程中有效地减小镜像大小。

3.4 权限问题

前面已节我们已经按照了系统的 ping 工具,这样我们就可以正常的使用 System.Net.NetworkInformation.Ping 类来检查目标 IP 地址是否在线。但是在 Linux 系统中,Ping 的实现依赖于 ICMP 协议,而在容器中执行 ICMP 请求通常需要特殊权限,直接容器化运行项目会发现下面的问题:

ping: socktype: SOCK_RAW                                                         
ping: socket: Operation not permitted                                            
ping: => missing cap_net_raw+p capability or setuid?

这是因为为了提高安全性,我们已经将应用的运行用户更改为了 app。为了解决这个问题,我们可以在 Dockerfile 中为更改 ping 命令的权限。

chmod u+s /bin/ping

3.5 编码问题

处理到这里,Dockerfile 的文件就基本解决完毕。但是在实际测试中我们会发现,API 接口中返回的中文会出现乱码的情况:

net 8.0 dockerfile,.net

我们可以看到,由配置文件返回的中文信息并没有出现乱码,而通过代码直接返回的中文出现了乱码的情况。这里是因为默认的代码文件编码是 GB18030 ,我们只需要将其改为 UTF-8 ,然后重新制备镜像即可解决这种硬编码导致的乱码问题。

net 8.0 dockerfile,.net

4. 要点总结

通过以上的问题重现和处理,我们最终的项目 Dockerfile 如下:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["WakeOnLan/WakeOnLan.csproj", "WakeOnLan/"]
RUN dotnet restore "WakeOnLan/WakeOnLan.csproj"
COPY . .
WORKDIR "/src/WakeOnLan"
RUN dotnet build "WakeOnLan.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "WakeOnLan.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=true

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/debian.sources \
    && apt-get update \
    && apt-get install -y --no-install-recommends iputils-ping \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* \
    && chmod u+s /bin/ping
WORKDIR /app
USER app
EXPOSE 8080
COPY --from=publish /app/publish .
ENTRYPOINT ["./WakeOnLan"]

最后总结在编写 Dockerfile 时需要注意的一些要点:

  1. 使用多阶段构建:多阶段构建可以减小最终生成的镜像大小,提高构建速度。在上述示例中,我们使用了三个阶段,分别用于编译、发布和运行应用程序。

  2. 使用官方镜像:尽量使用官方提供的基础镜像,以确保镜像的安全性和可靠性。

  3. 优化镜像层:尽量将不会经常变动的文件放在前面,以充分利用镜像层缓存,提高构建速度。

  4. 安装额外依赖:根据项目实际需求,安装额外的依赖和工具,确保所有功能正常运行。

  5. 更改安装源:更改镜像源以加速软件包的下载和安装过程,减少构建时间。

  6. 清理缓存和临时文件:清理缓存和临时文件,减小生成的镜像大小。

  7. 解决权限问题:确保容器化应用程序的安全性,遵循最小权限原则,避免使用 root 用户运行容器。设置运行时用户并调整文件和目录的权限。

  8. 充分测试:对容器化后的项目进行充分的测试工作,以确保所有功能都能正常运行。

通过关注这些要点,我们可以针对实际项目编写和调整 Dockerfile,以便更好地利用 Docker 的优势。同时,对容器化后的项目进行充分的测试工作也是至关重要的。文章来源地址https://www.toymoban.com/news/detail-835029.html

到了这里,关于.NET的Dockerfile文件编写要点——以WOL项目为例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • .net core 生成项目时.json配置文件没有复制到输出目录

    在程序运行时默认加载.exe文件同文件夹下的配置文件,而不是项目中的.json配置文件,所以需要把.json配置文件设置到自动生成目录,即下图所示:

    2023年04月13日
    浏览(42)
  • 【.NET 深呼吸】全代码编写WPF程序

    学习 Code 总有这样一个过程:入门时候比较依赖设计器、标记语言等辅助工具;等到玩熟练了就会发现纯代码写 UI 其实更高效。而且,纯代码编写也是最灵活的。Windows Forms 项目是肯定可以全代码编写的,哪怕你使用了设计器,它最后也是生成代码文件;而 WPF 就值得探索一

    2024年02月09日
    浏览(30)
  • 银河麒麟服务器v10 sp1 部署.Net6.0项目后无法访问静态文件

    上一篇:银河麒麟服务器v10 sp1 部署.Net6.0 http https_csdn_aspnet的博客-CSDN博客 由于本人项目直接从.NetCore3.1升级到.Net6.0的,请参考文章:NetCore3.1项目升级到Net6.0_vs2022 没有startup_csdn_aspnet的博客-CSDN博客 虽然部署项目后,swagger与接口可以正常访问,但是静态文件,如html、css、j

    2024年02月12日
    浏览(30)
  • .net 6 web api项目添加日志(Serilog)管理,将日志输出到控制台、文件、数据库

    1.在nuget安装下面几个包 Serilog Serilog.AspNetCore //用于日志输出到控制台 Serilog.Formatting.Compact //用于日志输出到mysql数据库 Serilog.Sinks.MySQL //用于日志输出到文件 Serilog.Sinks.RollingFile 2.在Program.cs文件配置日志参数,依赖注入 别忘了在appsettings.json添加数据库连接字符串 3. 使用日志

    2024年02月10日
    浏览(53)
  • windows部署python项目(以Flask为例)到docker,通过脚本一键生成dockerfile并构建镜像启动容器

    这里使用 pipreqs 进行依赖库的识别。使用 pipreqs 可以自动检索到当前项目下的所有组件及其版本,并生成 requirements.txt 文件。相比直接用pip freeze 命令,避免将整个python环境的依赖包写入。 在项目的当前目录中执行 pipreqs ./ --encoding=utf8 --force 这里使用的是一个基于flask项目,

    2023年04月08日
    浏览(41)
  • 在.net中通过自定义LoggerProvider将日志保存到数据库方法(以mysql为例)

      在.NET中, Microsoft.Extensions.Logging是一个灵活的日志库,它允许你将日志信息记录到各种不同的目标,包括数据库。在这个示例中,我将详细介绍如何使用Microsoft.Extensions.Logging将日志保存到MySQL数据库。我们将使用Entity Framework Core来与MySQL数据库进行交互。 首先,我们需要创

    2024年02月05日
    浏览(35)
  • 使用VisualStudio2022插件(Visual Studio Installer Projects 2022)打包 .Net 6 框架下的 WPF项目 为安装文件

    目录 更新说明(2024/01/22) 序言 一、还是安装Visual Studio Installer Projects 2022插件 二、创建Setup Project项目 2.1 在现有解决方案中添加Setup Project项目 2.2 (更新)添加需要打包的文件  2.2.1 准备添加输出项。 2.2.2 【核心】添加 WpfMain 项目输出。 2.2.3 添加 WpfPluginManager 项目输出。

    2024年02月03日
    浏览(84)
  • 服务端使用ASP.NET Core SignalR与Vue3(TypeScript与JavaScript)前端建立通信(以进度条为例)

    1. ASP.NET Core           ASP.NET Core 是一个跨平台、高性能及开源的框架,用于生成基于云且连接互联网的新式应用程式。 官方文档:ASP.NET documentation | Microsoft Learn  2.  ASP.NET Core SignalR         ASP.NET Core SignalR 是开源库,用于服务端与客户端建立实时通信,可以自动管理连接

    2024年02月06日
    浏览(36)
  • C# 利用.NET 升级助手将.NET Framework项目升级为.NET 6

    .NET6 正式版本已经发布有一阵子了,今天我就体验一下如何将.NET Framework的项目升级为.NET 6. 升级条件: Windows 操作系统 .NET 6 SDK Visual Studio 2022 17.0 或更高版本 ①首先是VS2022下载,直接上微软官方网站,下载地址: https://visualstudio.microsoft.com/zh-hans/downloads/ 下载后,在线安装就

    2024年02月12日
    浏览(36)
  • dockerfile报错:“/bin/sh -c yum -y install vim net-tools wget“ did not complete successfully: exit code

    docker build -t cento7:1.0 .    #执行以上docker file报错 尝试过更换yum源、检查网络等等,均无法解决。 最后将docker 重启了,但是生产环境需要谨慎重启docker 再次执行 发现问题解决。  可参考学习!

    2024年02月07日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包