Reputation: 23833
I have the need to build both an ASP.NET Core application, which calls a C++ executable to get some work done. I have the docker file to build both images for .NET Core and C++ working great, but separately.
The ASP.NET Core Dockerfile looks like this:
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
This works great.
The C++ Dockerfile looks like this:
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
This compiles, and the executable runs fine, too.
So, I have tried to combine the two as follows:
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
This compiles the C++ and the .NET Core stuff fine.
The issue is that the base ubuntu:16.04
image is lost, so when I attempt to run the C++ executable (that was compiled with the -lgomp g++/gcc
option), I get the following error:
./PoissonRecon: error while loading shared libraries: libgomp.so.1: cannot open shared object file: No such file or directory
This is because the /usr/lib/
folder only contains the bare minimum for the .NET assemblies.
How can I build this Docker image so that I compile both, but keep the required C++ libraries in the /usr/lib/
directories?
Upvotes: 8
Views: 856
Reputation: 5394
Its a bit weird because libgomp1
doesn't seem to be installed by default on the ubuntu:16.04
and even after running apt-get update && apt-get install -y --no-install-recommends
so there might be some difference between ubuntu 16.04 and Debian buster (10) that requires that package.
You can however install it yourself on top of your preexisting image (mcr.microsoft.com/dotnet/aspnet:5.0
) with apt-get update && apt-get install -y libgomp1
. Another options is to use the ubuntu 20.04 based one (mcr.microsoft.com/dotnet/aspnet:5.0-focal
) or check this link for other versions and architectures, It's possible using this image would work for the same (yet unknown) reason it works on your regular Ubuntu server.
A third and more comprehensive option is, since you know it works with your current ubuntu:16.04 image, you can install aspnet 5.0 on it as specified here
UPDATE:
installing the missing package (libgomp1
) on the original Debian based image fixed the issue
Upvotes: 3