=====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 [[https://github.com/JulienAndonov/C--Web/blob/master/Web%20Server%20-%20HTTP%20Protocol/HttpServerDemo/Program.cs|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: * 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 ====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==== 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: # 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: 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: 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]