Dockerfile that Builds both ASP.NET Core and C++ binaries
Asked Answered
H

1

8

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?

Handcart answered 25/8, 2021 at 0:39 Comment(0)
C
3

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

Creech answered 31/8, 2021 at 10:50 Comment(7)
The last link looks promising, I will try this later and come back to you. Thanks for your answer...Handcart
The link provided in "or use the ubuntu 20.04 based one" is dead?Handcart
oh sorry put the registry pull url in the text linkCreech
did you check again since?Creech
I have attempted to build this using Debian 10, which is what the asp net image is based on. I have not tried the results as this took sometime to build. I will come back to you…Handcart
The above - installing on Debian 10 then copying the binary to the final layer works.Handcart
That's great to hear ☺️Creech

© 2022 - 2024 — McMap. All rights reserved.