Building an Application in Docker while Offline

While on a train with no internet access, I was working on a containerized .NET application. I had some of the work done and had built and rebuilt the image many times. But now, when I tried to build a new version of the image I got -

Failed to resolve...
Failed to resolve…
ERROR: failed to solve: mcr.microsoft.com/dotnet/sdk:8.0: failed to resolve source metadata for mcr.microsoft.com/dotnet/sdk:8.0: 
failed to do request: Head "https://mcr.microsoft.com/v2/dotnet/sdk/manifests/8.0": 
dialing mcr.microsoft.com:443 container via direct connection because  has no HTTPS proxy: 
connecting to mcr.microsoft.com:443: 
dial tcp: lookup mcr.microsoft.com: no such host

Why!? I had built the application image before, and I had everything needed from SDK and runtime to build and run the application. Yeah, I was offline, but so what?

Docker definitely does not download the SDK image every time I run a build. So what was going on?

Well, it seems that even though all the layers of the image SDK and runtime images were cached locally, the build process still needed to check the metadata of the images named mcr.microsoft.com/dotnet/sdk:8.0 and mcr.microsoft.com/dotnet/aspnet:8.0, and then decide if all the layers were available and up to date.

This is the error I get when I run the build command -

 => ERROR [internal] load metadata for mcr.microsoft.com/dotnet/sdk:8.0     19.4s
 => ERROR [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:8.0  19.4s

When I looked at the image on my machine, I saw that SDK and runtime for .NET 8.0 were not there because they had not been explicitly pulled. Compare this to using Redis or SQL Server images, when you pull them they appear in the list of images on your machine.

Redis and SQL Server only
Redis and SQL Server only

That was the clue I needed. I should explicitly pull the images for the SDK and runtime.

The next time I was online I pulled the two images -

docker pull mcr.microsoft.com/dotnet/sdk:8.0
docker pull mcr.microsoft.com/dotnet/aspnet:8.0

These commands did not download any data for the images because I had all the layers already. But it added the two images to my list of available images.

SDK and Runtime
SDK and Runtime

And when offline again I could build the application without any problems.

The full Dockerfile is below. Note images needed on lines 2 and 17 -

 1# This stage is used to build the service project
 2FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
 3ARG BUILD_CONFIGURATION=Release
 4WORKDIR /src
 5COPY ["WebApiApp.csproj", "."]
 6RUN dotnet restore "./WebApiApp.csproj"
 7COPY . .
 8WORKDIR "/src/."
 9RUN dotnet build "./WebApiApp.csproj" -c $BUILD_CONFIGURATION -o /app/build
10
11# This stage is used to publish the service project to be copied to the final stage
12FROM build AS publish
13ARG BUILD_CONFIGURATION=Release
14RUN dotnet publish "./WebApiApp.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
15
16# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
17FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
18WORKDIR /app
19COPY --from=publish /app/publish .
20ENTRYPOINT ["dotnet", "WebApiApp.dll"]

That’s it, pull all the images that your Dockerfile uses to build the application, and you’ll have no problems when offline. But, keep in mind you should occasionally pull those images to make sure you have the latest versions.

comments powered by Disqus

Related