Docker 图片中未包含 wwwroot 中的静态文件

Static Files in wwwroot not contained in Docker Image

只是玩了一下。 我得到了一个 Visual Studio 解决方案,包含 3 个项目。 这三个都需要。 一个项目 ("one") 是应用程序的 UI。它当然包含 wwwroot 中的静态文件。

我想docker处理应用程序。 此处的 Dockerfile 有效。 然后我通过 kubernetes 在 Ubuntu 服务器上加载这个图像。

没问题,容器 运行 正在处理请求。

但它根本不提供静态文件。所有这些文件请求都会导致 404 HTTP 错误。该网站看起来像垃圾(但加载)。

于是我登录了容器,开始观察/app的内容。这里没有名为 "wwwroot" 的目录。也不是子目录。 我不确定,如果 wwwroot 目录属于这里?还是该目录包含在应用程序的dll中?

经过大量搜索(还在 Whosebug 上找到了一些有用的问题)后,我发现文件会自动包含到构建过程中。无需在 csproj 文件中单独定义它们。但是如果我这样做,它会导致像 "Duplicate files included" 或类似的错误。

这是 Dockerfile:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY one/one.csproj one/
COPY two/two.csproj two/
COPY three/three.csproj three/
COPY . ./

WORKDIR "/src/one"
RUN dotnet build -c Release -o /app
WORKDIR "/src/two"
RUN dotnet build -c Release -o /app
WORKDIR "/src/three"
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Release -o /app

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

是的,我正在使用 UseStaticFiles:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }
    // IMPORTANT: This session call MUST go before UseMvc()
    app.UseSession();
    app.UseStaticFiles();
    ...

并且静态文件(大部分)都在正确区分大小写的情况下进行访问。但是正如我已经说过的,可以访问 none 个静态文件。

在视图中,我的应用包含 CSS 个文件,如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="~/framework/1.css">
    <link rel="stylesheet" href="~/framework/2.css" media="screen,projection">
    ...

虽然 运行 在 docker 中,但它的结果是 HTML 输出:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="/framework/1.css">
    <link rel="stylesheet" href="/framework/2.css" media="screen,projection">
    ...

看到缺少的代字号 ~ ?

如何将静态文件包含到docker图像中?

谢谢! xola

好吧,现在我自己发现了。

错误出在 Dockerfile 本身。 我需要明确说明要构建哪个 csproj 文件以及要发布哪个文件。这是我学到的here.

实际上,不需要在csproj文件中定义类似"include this file, and this directory"的东西。

实际上很重要的一点是,wwwroot 目录没有编译到 dll 中。它存在于容器中的 /app 文件夹中(我在任何地方都找不到该信息,但我得到了提示 here)。

这也提供了将外部文件夹映射到容器的能力(这样您就可以编辑静态文件,而不必一遍又一遍地对其进行重新 dockerize——当然这不适用于生产环境)。

同样重要的是,对于生产环境和通常所有您不想进入图像的静态文件(如源 SCSS、un-obfuscated JS、临时文件、副本文件副本的备份等),应使用 .dockerignore 文件。

如果不这样做,静态文件可以直接通过浏览器访问,因为它们直接进入 wwwroot 目录。

这是我的工作 Dockerfile。

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY all.sln ./    # not sure if I need this
COPY one/one.csproj one/
COPY two/two.csproj two/
COPY three/three.csproj three/
COPY . ./

RUN dotnet build "/src/one/one.csproj" -c Release -o /app
RUN dotnet build "/src/two/two.csproj" -c Release -o /app
RUN dotnet build "/src/three/three.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "/src/one/one.csproj" -c Release -o /app

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

希望我的解释对以后遇到这个问题的其他人有所帮助。

谢谢! xola