在现代软件开发中,容器化技术如Docker越来越受到开发者的青睐。它提供了一种便捷的方式来打包、分发和运行应用程序。然而,将应用程序迁移到Docker环境时,可能会遇到一些意想不到的问题。本文将分享一个使用Puppeteer和NodeJS在.NET应用程序中渲染报告时遇到的问题及其解决方法。
Puppeteer是一个NodeJS库,它允许运行并控制无头Chrome浏览器,即没有用户界面的Google Chrome实例。在本项目中,使用Puppeteer来渲染报告的PDF导出。在原生环境中,它运行得非常顺畅。但在Docker中,情况就有所不同了。
首先,让来看一下Docker配置。以下是Dockerfile的内容:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["MyApplication.API/MyApplication.API.csproj", "MyApplication.API/"]
COPY ["MyApplication.Common/MyApplication.Common.csproj", "MyApplication.Common/"]
COPY ["MyApplication.Data/MyApplication.Data.csproj", "MyApplication.Data/"]
COPY ["MyApplication.Logic/MyApplication.Logic.csproj", "MyApplication.Logic/"]
RUN dotnet restore "MyApplication.API/MyApplication.API.csproj"
COPY . .
WORKDIR "/src/MyApplication.API"
RUN dotnet build "MyApplication.API.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "MyApplication.API.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyApplication.API.dll", "--environment", "Docker"]
# Install node and npm
RUN apt-get update
RUN apt-get install nodejs=12.22.5~dfsg-2~11u1 -y
RUN apt-get install npm=7.5.2+ds-2 -y
ENV NODE_ENV=production
# Install node modules for reports
WORKDIR "/app/Reports/jsreport"
RUN npm install
# Set the directory back so dotnet is able to run the application
WORKDIR "/app"
这个Dockerfile首先加载了ASP.NET6的基础镜像,构建解决方案,发布它,安装所需的Node模块,并设置.NET程序作为容器的入口点。
使用以下命令构建镜像:
docker build -t myimage -f ./MyApplication.API/Dockerfile .
注意,为了使Dockerfile中的构建步骤工作,镜像必须在解决方案级别而不是项目级别创建,因为所有项目都需要构建。这就是为什么在构建镜像时使用解决方案目录的原因。
然后使用以下命令运行容器:
docker run -p 127.0.0.1:80:80/tcp myimage
到目前为止一切顺利!但是在调用报告之一时,出现了内部服务器错误。
由于这是在Docker下运行(而且这只是一个业余应用,使用的是老式的滚动文件日志),实际上需要先进入容器才能查看日志。首先获取容器的ID:
docker ps
一旦有了容器的ID:
docker exec -it CONTAINER_ID /bin/bash
打开错误日志揭示了以下信息:
Jering.Javascript.NodeJS.InvocationException: Failed to launch chrome!
/app/Reports/jsreport/node_modules/puppeteer/.local-chromium/linux-609904/chrome-linux/chrome:
error while loading shared libraries: libnss3.so: cannot open shared object file:
No such file or directory
# Install latest chrome dev package and fonts to support major charsets
# (Chinese, Japanese, Arabic, Hebrew, Thai and a few others)
# Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer
# installs, work.
RUN apt-get update \
&& apt-get install -y wget gnupg \
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >>
/etc/apt/sources.list.d/google.list' \
&& apt-get update \
&& apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei
fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*