docker_basic_dockerize

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.

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:

  • Workdir - The workdir on the container which will be used.
  • FROM - The external resources which will be used.
  • COPY & RUN - These are self explanatory I hope.

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

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

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]#

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 ~]#

You can have the following error:

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:

  • Delete the “obj” and “bin” folders from the directory
  • Add a command to the “Dockerfile” to not upload these to the container as follows:

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"]

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]
  • docker_basic_dockerize.txt
  • Last modified: 2020/05/03 11:49
  • by andonovj