首页 > 解决方案 > 构建 ASP.NET Core 和 C++ 二进制文件的 Dockerfile

问题描述

我需要构建一个 ASP.NET Core 应用程序,它调用一个 C++ 可执行文件来完成一些工作。我有 docker 文件来为 .NET Core 和 C++ 构建两个图像,它们工作得很好,但分别是 .NET Core 和 C++ 。

ASP.NET Core Dockerfile 如下所示:

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 4444
EXPOSE 5599
ENV ASPNETCORE_URLS=https://+:4444;https://+:5599

# Creates a non-root user with an explicit UID and adds permission to access the /app folder
# For more info, please refer to https://aka.ms/vscode-docker-dotnet-configure-containers
# RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
# USER appuser

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src

COPY ["Core/Blundergat.Common/Blundergat.Common.csproj", "Core/Blundergat.Common/"]
COPY ["Core/Blundergat.Core/Blundergat.Core.csproj", "Core/Blundergat.Core/"]
COPY ["Core/Blundergat.Domain/Blundergat.Domain.csproj", "Core/Blundergat.Domain/"]
COPY ["Io/Blundergat.Io/Blundergat.Io.csproj", "Io/Blundergat.Io/"]
COPY ["Meshing/Blundergat.Meshing.Generator/Blundergat.Meshing.Generator.csproj", "Meshing/Blundergat.Meshing.Generator/"]
COPY ["Meshing/Blundergat.Meshing.Decimator/Blundergat.Meshing.Decimator.csproj", "Meshing/Blundergat.Meshing.Decimator/"]
COPY ["Optimization/Blundergat.Fireworks/Blundergat.Fireworks.csproj", "Optimization/Blundergat.Fireworks/"]
COPY ["Registration/Blundergat.CoarseRegistration/Blundergat.CoarseRegistration.csproj", "Registration/Blundergat.CoarseRegistration/"]
COPY ["Registration/Blundergat.FineRegistration/Blundergat.FineRegistration.csproj", "Registration/Blundergat.FineRegistration/"]
COPY ["Services/Blundergat/Blundergat.csproj", "Services/Blundergat/"]
COPY ["Storage/Blundergat.Storage/Blundergat.Storage.csproj", "Storage/Blundergat.Storage/"]
COPY ["Transport/Blundergat.Grpc/Blundergat.Grpc.csproj", "Transport/Blundergat.Grpc/"]

RUN dotnet restore "Services/Blundergat/Blundergat.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "Services/Blundergat/Blundergat.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Services/Blundergat/Blundergat.csproj" -c Release -o /app/publish

FROM base AS final

WORKDIR /app

COPY --from=publish /app/publish .
COPY --from=ubuntu /src/bin/PoissonRecon .
#ENTRYPOINT ["dotnet", "Blundergat.dll"]
ENTRYPOINT /app/Blundergat start && /bin/bash

这很好用。

C++ Dockerfile 如下所示:

FROM ubuntu:16.04 AS ubuntu

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        vim g++ make

WORKDIR "/src/"

COPY ["Meshing/Blundergat.Meshing/jpeg", "jpeg/"]
COPY ["Meshing/Blundergat.Meshing/png", "png/"]
COPY ["Meshing/Blundergat.Meshing/zlib", "zlib/"]
COPY ["Meshing/Blundergat.Meshing/linux", "src/"]
COPY ["Meshing/Blundergat.Meshing/Makefile", "."]

# TODO REMOVE unwanted files. 

RUN make

这可以编译,并且可执行文件也可以正常运行。

因此,我尝试将两者结合如下:

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 4444
EXPOSE 5599
ENV ASPNETCORE_URLS=https://+:4444;https://+:5599

FROM ubuntu:16.04 AS ubuntu

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        vim g++ make

WORKDIR "/src/"

COPY ["Meshing/Blundergat.Meshing/jpeg", "jpeg/"]
COPY ["Meshing/Blundergat.Meshing/png", "png/"]
COPY ["Meshing/Blundergat.Meshing/zlib", "zlib/"]
COPY ["Meshing/Blundergat.Meshing/linux", "src/"]
COPY ["Meshing/Blundergat.Meshing/Makefile", "."]

#REMOVE unwanted files. 

RUN make

# Creates a non-root user with an explicit UID and adds permission to access the /app folder
# For more info, please refer to https://aka.ms/vscode-docker-dotnet-configure-containers
# RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
# USER appuser

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src

COPY ["Core/Blundergat.Common/Blundergat.Common.csproj", "Core/Blundergat.Common/"]
COPY ["Core/Blundergat.Core/Blundergat.Core.csproj", "Core/Blundergat.Core/"]
COPY ["Core/Blundergat.Domain/Blundergat.Domain.csproj", "Core/Blundergat.Domain/"]
COPY ["Io/Blundergat.Io/Blundergat.Io.csproj", "Io/Blundergat.Io/"]
COPY ["Meshing/Blundergat.Meshing.Generator/Blundergat.Meshing.Generator.csproj", "Meshing/Blundergat.Meshing.Generator/"]
COPY ["Meshing/Blundergat.Meshing.Decimator/Blundergat.Meshing.Decimator.csproj", "Meshing/Blundergat.Meshing.Decimator/"]
COPY ["Optimization/Blundergat.Fireworks/Blundergat.Fireworks.csproj", "Optimization/Blundergat.Fireworks/"]
COPY ["Registration/Blundergat.CoarseRegistration/Blundergat.CoarseRegistration.csproj", "Registration/Blundergat.CoarseRegistration/"]
COPY ["Registration/Blundergat.FineRegistration/Blundergat.FineRegistration.csproj", "Registration/Blundergat.FineRegistration/"]
COPY ["Services/Blundergat/Blundergat.csproj", "Services/Blundergat/"]
COPY ["Storage/Blundergat.Storage/Blundergat.Storage.csproj", "Storage/Blundergat.Storage/"]
COPY ["Transport/Blundergat.Grpc/Blundergat.Grpc.csproj", "Transport/Blundergat.Grpc/"]

RUN dotnet restore "Services/Blundergat/Blundergat.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "Services/Blundergat/Blundergat.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Services/Blundergat/Blundergat.csproj" -c Release -o /app/publish

FROM base AS final

WORKDIR /app

COPY --from=publish /app/publish .
COPY --from=ubuntu /src/bin/PoissonRecon .
#ENTRYPOINT ["dotnet", "Blundergat.dll"]
ENTRYPOINT /app/Blundergat start && /bin/bash

这可以很好地编译 C++ 和 .NET Core 的东西。

问题是基本ubuntu:16.04映像丢失了,因此当我尝试运行 C++ 可执行文件(使用该-lgomp g++/gcc选项编译)时,出现以下错误:

./PoissonRecon:加载共享库时出错:libgomp.so.1:无法打开共享对象文件:没有这样的文件或目录

这是因为该/usr/lib/文件夹仅包含 .NET 程序集的最低限度。

如何构建此 Docker 映像以便编译两者,但将所需的 C++ 库保留在/usr/lib/目录中?

标签: c++linuxdockerasp.net-coreubuntu-16.04

解决方案


它有点奇怪,因为libgomp1默认情况下似乎没有安装,ubuntu:16.04甚至在运行之后也没有安装,apt-get update && apt-get install -y --no-install-recommends所以 ubuntu 16.04 和需要该软件包的 Debian buster (10) 之间可能存在一些差异。

但是,您可以mcr.microsoft.com/dotnet/aspnet:5.0使用apt-get update && apt-get install -y libgomp1. 另一种选择是使用基于 ubuntu 20.04mcr.microsoft.com/dotnet/aspnet:5.0-focal

第三个也是更全面的选项是,因为您知道它适用于您当前的 ubuntu:16.04 映像,您可以按照此处 指定的方式在其上安装 aspnet 5.0

更新:

libgomp1在基于 Debian 的原始映像上安装缺少的软件包 ( ) 解决了该问题


推荐阅读