【问题标题】:Static Files in wwwroot not contained in Docker Imagewwwroot 中的静态文件不包含在 Docker 映像中
【发布时间】:2020-02-24 16:01:53
【问题描述】:

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

我想 dockerize 应用程序。 这里的 Dockerfile 有效。 然后我通过 Ubuntu 服务器上的 kubernetes 加载此图像。

这里没问题,容器正在运行并为请求提供服务。

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

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

经过大量搜索(在 StackOverflow 上也发现了一些有用的问题),我发现文件自动包含在构建过​​程中。无需在 csproj 文件中单独定义它们。但如果我这样做,它会导致“包含重复文件”之类的错误。

这里是 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();
    ...

静态文件(大部分)都以正确的大小写敏感方式访问。但正如我已经说过的,没有静态文件可以访问。

在视图中,我的应用包含如下 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

【问题讨论】:

  • 我从来没有见过~在路径中使用过,目的是什么?如果您想要正在运行的文件的相对路径,请改用.:“./framework/1.css”
  • 我明白了。因为当我在本地编译它时它可以工作,所以我不在乎。这可能解决不了问题吧?

标签: docker asp.net-core kubernetes .net-core wwwroot


【解决方案1】:

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

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

其实不用在csproj文件中定义“包含这个文件和这个目录”之类的东西。

实际上很重要的一点是,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

【讨论】:

  • 嘿,你怎么“说 wwwroot 目录没有编译到 dll 中”?我有这个确切的问题,我可以使用控制器,但 wwwroot 中的文件没有提供。
  • @Codendaal 我也有同样的问题,请告诉我你是否解决了它;(
猜你喜欢
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2023-03-28
  • 2019-01-03
相关资源
最近更新 更多