Table of Contents

Overview

After we learned a little bit a docker and containers, let's use docker for what it was meant to :) I have created a simple HTTP server which listens on port: 1234

Source code you can see in my Git

Packaging application in image, we call dockerize and it is done pretty simle.

Steps

Firstly, you need a Dockerfile in the place of your project. Since my project is on C#.NET Core and assuming your application is called: HttpServerDemo.dll, I have used the following Dockerfile:

Dockerfile

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "HttpServerDemo.dll"]

Now, let's go through the steps:

You have to verify you have docker at least 17.05 or newer. My current one is 19.03:

[root@postgresqlpgpool netcoreapp3.1]# docker --version
Docker version 19.03.5, build 633a0ea

Build

The building is also done fairy simple.

[root@postgresqlpgpool HttpServerDemo]# docker build -t httpserverdemo .
Sending build context to Docker daemon  398.3kB
Step 1/10 : FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
 ---> 2fe8fe202baf
Step 2/10 : WORKDIR /app
 ---> Using cache
 ---> 931056fe84ac
Step 3/10 : COPY *.csproj ./
 ---> Using cache
 ---> 33c701ccd6cf
Step 4/10 : RUN dotnet restore
 ---> Using cache
 ---> 2acbc600037a
Step 5/10 : COPY . ./
 ---> 68177b9bdcf6
Step 6/10 : RUN dotnet publish -c Release -o out
 ---> Running in 34db589b7d0b
Microsoft (R) Build Engine version 16.4.0+e901037fe for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 127.94 ms for /app/HttpServerDemo.csproj.
  HttpServerDemo -> /app/bin/Release/netcoreapp3.1/HttpServerDemo.dll
  HttpServerDemo -> /app/out/
Removing intermediate container 34db589b7d0b
 ---> d81f005279bc
Step 7/10 : FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
 ---> 5b704ff3cb6b
Step 8/10 : WORKDIR /app
 ---> Using cache
 ---> e35d6ba6b507
Step 9/10 : COPY --from=build-env /app/out .
 ---> dc3b27c05e4d
Step 10/10 : ENTRYPOINT ["dotnet", "HttpServerDemo.dll"]
 ---> Running in ff14d57a08fc
Removing intermediate container ff14d57a08fc
 ---> 46b4167e5b2d
Successfully built 46b4167e5b2d
Successfully tagged httpserverdemo:latest
[root@postgresqlpgpool HttpServerDemo]#

You can list the images as follows:

[root@postgresqlpgpool netcoreapp3.1]# docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
httpserverdemo                         latest              4ab730ac8ab5        6 hours ago         207MB

Start

Once the image has been built, you can start the container using that image:

[root@postgresqlpgpool HttpServerDemo]# docker run -d httpserverdemo 80:1234
c23e4bb41a9f660f8b409addb58d398b98dce38e93da00682214141f5bc719c9
[root@postgresqlpgpool HttpServerDemo]#

Finally, you can check the container:

[root@postgresqlpgpool netcoreapp3.1]# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
9afb2dcbd6c2        httpserverdemo      "dotnet HttpServerDe…"   5 hours ago         Up 5 hours          0.0.0.0:80->1234/tcp   web
[root@postgresqlpgpool netcoreapp3.1]#

Upload in docker hub

Docker hub is the default registry for docker images. You can upload your image there if you want, bare in mind that it will be public.

Login

[root@postgresqlpgpool netcoreapp3.1]# docker login --username=andonovj
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[root@postgresqlpgpool netcoreapp3.1]# 

Package

[root@postgresqlpgpool netcoreapp3.1]# docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
httpserverdemo                         latest              4ab730ac8ab5        3 hours ago         207MB
[root@postgresqlpgpool netcoreapp3.1]# docker tag 4ab730ac8ab5 andonovj/httpserverdemo

Push

[root@postgresqlpgpool netcoreapp3.1]# docker push andonovj/httpserverdemo
The push refers to repository [docker.io/andonovj/httpserverdemo]
6f2df37fa757: Pushed
64bca5e22c97: Pushed
05682a6a4056: Pushed
fcd021389694: Pushed
2c52aed6692d: Pushed
c51868eee26f: Pushed
556c5fb0d91b: Pushed
latest: digest: sha256:5e0866ff45e12c8e350923fbe32d94bd76bd2d1576722d4d55ca786043bfcbe1 size: 1791
[root@postgresqlpgpool netcoreapp3.1]#

Now you can also download this simple web from your docker hub or list it as follows:

[root@postgresqlpgpool ~]# docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
andonovj/httpserverdemo                latest              4ab730ac8ab5        6 hours ago         207MB
[root@postgresqlpgpool ~]#

Troubleshooting

You can have the following error:

Searching wrong Nuget

Nuget Issue

  Restore completed in 41.36 ms for /app/HttpServerDemo.csproj.
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018: The "ResolvePackageAssets" task failed unexpectedly. [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018: NuGet.Packaging.Core.PackagingException: Unable to find fallback package folder 'C:\Program Files\dotnet\sdk\NuGetFallbackFolder'. [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at NuGet.Packaging.FallbackPackagePathResolver..ctor(String userPackageFolder, IEnumerable`1 fallbackPackageFolders) [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at Microsoft.NET.Build.Tasks.NuGetPackageResolver.CreateResolver(IEnumerable`1 packageFolders) [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at Microsoft.NET.Build.Tasks.NuGetPackageResolver.CreateResolver(LockFile lockFile) [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at Microsoft.NET.Build.Tasks.ResolvePackageAssets.CacheWriter..ctor(ResolvePackageAssets task) [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at Microsoft.NET.Build.Tasks.ResolvePackageAssets.CacheReader.CreateReaderFromDisk(ResolvePackageAssets task, Byte[] settingsHash) [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at Microsoft.NET.Build.Tasks.ResolvePackageAssets.CacheReader..ctor(ResolvePackageAssets task) [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at Microsoft.NET.Build.Tasks.ResolvePackageAssets.ReadItemGroups() [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at Microsoft.NET.Build.Tasks.ResolvePackageAssets.ExecuteCore() [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at Microsoft.NET.Build.Tasks.TaskBase.Execute() [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [/app/HttpServerDemo.csproj]
/usr/share/dotnet/sdk/3.1.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(234,5): error MSB4018:    at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [/app/HttpServerDemo.csproj]
The command '/bin/sh -c dotnet publish -c Release -o out' returned a non-zero code: 1

In that case, either:

Edit Dockerfile

# copy and build everything else
COPY . ./
RUN find -type d -name bin -prune -exec rm -rf {} \; && find -type d -name obj -prune -exec rm -rf {} \;     <- This line
ENTRYPOINT ["dotnet", "HttpServerDemo.dll"]

Wrong ASP.NET

Be careful about the dockerizing the application. I tried to build the application with ASP.NET 2.2 while the app was build with ASP.NET 3.1, so I had to update my Dockerfile as follows:

Updated Docker File

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env                     <- This line
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
#FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
FROM mcr.microsoft.com/dotnet/core/sdk:3.1
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "HttpServerDemo.dll"]

Otherwise, you will receive the following error:

Error for wrong ASP.NET version

It was not possible to find any compatible framework version
The specified framework 'Microsoft.NETCore.App', version '3.1.0' was not found.
  - Check application dependencies and target a framework version installed at:
      /usr/share/dotnet/
  - Installing .NET Core prerequisites might help resolve this problem:
      https://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409
  - The .NET Core framework and SDK can be installed from:
      https://aka.ms/dotnet-download
  - The following versions are installed:
      2.2.8 at [/usr/share/dotnet/shared/Microsoft.NETCore.App]