ASP. NET core uses System.Drawing.Common to deploy to Docker error issues

Source: Internet
Author: User
Tags dotnet stack trace docker run

After the release of ASP. NET Core 2.1, the System.Drawing.Common drawing is officially supported, which can be used to do some functions such as image verification code. However, the deployment of the site to the Docker container run will encounter a lot of problems, but also very annoying, this article records these issues, hoping to help people in need.

Create a Web site

Prerequisites: Install the latest version of VS2017 and net Core SDK 2.1.

To create a new Web site, choose the ASP. NET Core 2.1 Web application (Model View controller), I'm accustomed to writing dockerfile myself without checking Docker.

Specify site access Port 5000.

public static Iwebhostbuilder Createwebhostbuilder (string[] args) =            Webhost.createdefaultbuilder (args)                Port must be specified, otherwise the WIN10 command line run port is 5000, and the CentOS Docker run port is a                . Useurls ("http://*:5000")                . Usestartup<startup> ();

  

For debugging convenience, the privacy requirements and HTTPS requirements are first masked.

public void Configureservices (Iservicecollection services) {services. configure<cookiepolicyoptions> (Options + =//This lambda determines whether user cons                ENT for non-essential cookies are needed for a given request. Options.                checkconsentneeded = Context = true; Options.            Minimumsamesitepolicy = Samesitemode.none;            }); Services. Addmvc ().        Setcompatibilityversion (Compatibilityversion.version_2_1); }public void Configure (Iapplicationbuilder app, ihostingenvironment env) {if (env. Isdevelopment ()) {app.            Usedeveloperexceptionpage (); } else {app.                Useexceptionhandler ("/home/error"); App.            Usehsts (); }//app.            Usehttpsredirection (); App.            Usestaticfiles (); App.            Usecookiepolicy (); App.            USEMVC (routes = {    Routes.            MapRoute (name: "Default", Template: "{controller=home}/{action=index}/{id}");        }); }

  

Modify Appsettings.json output All debugging information, easy to find errors.

{"  Logging": {"    LogLevel": {"      Default": "Debug"}  },  "allowedhosts": "*"}

  

Debug run a bit, confirm the site is not a problem.

Change the index page of the home controller to a little bit more easily, and show a picture for yourself.

@{    viewdata["Title" = "Home page";} 

  

NuGet installs System.Drawing.Common.

Add a drawing function getimg to the home controller.

Public Iactionresult getimg ()        {            _logger. Loginformation ($ "{datetime.now:yyyy-mm-dd HH:mm:ss:fff}, start create image");            String msg = $ "{DateTime.Now:HH:mm:ss}, hello drawing from. NET Core";            Image image = New Bitmap (.);            Graphics graph = graphics.fromimage (image);            Graph. Clear (color.azure);            Pen pen = new Pen (brushes.black);            Graph. DrawLines (pen, new point[] {new Point (Ten), New Point (380)});            Graph. DrawString (msg, new Font (New FontFamily ("Microsoft Jas"), FontStyle.Bold), Brushes.blue, New PointF (ten, +));            Save the picture to the memory file stream            MemoryStream ms = new MemoryStream ();            Image. Save (MS, Imageformat.png);;            Byte[] buf = Ms. GetBuffer ();            _logger. Loginformation ($ "{Datetime.now:yyyy-mm-dd HH:mm:ss:fff}, Finish create image");            Return File (buf, "image/png");        }

  

Debugging and running it is no problem.

Deploying Web sites to Docker

Write Dockerfile, and note that the file properties "copy to Output directory" is set to "copy if newer".

From Microsoft/dotnet:2.1-aspnetcore-runtimeworkdir/appcopy. /appexpose 5000ENTRYPOINT ["dotnet", "NetCoreDraw.dll"]

  

Recompile the Web site and publish it as a folder to the default bin\release\publishoutput. In the Windows console go to the Publish directory, enter dotnet NetCoreDraw.dll run Web site, browser access http://localhost:5000/, confirm that no problem.

Writing DOCKER-COMPOSE.YML

Version: ' 3 ' services:  myweb:    container_name:myweb    image:mywebimage    Build:      context:./ Publishoutput      dockerfile:dockerfile    ports:      -"5000:5000"    Environment:      -Aspnetcore_ Environment=production      -Tz=asia/shanghai    restart:always

  

I use the CentOS 7.3 virtual machine To do the experiment, install the Docker environment, with Xshell access to the virtual machine, with xftp publishoutput folder, docker-compose.yml drag to the home.

Go to the home directory and run the container.

[[email protected] home]# docker-compose upcreating Network "Home_default" with the default driverbuilding Mywebstep 1/5: from microsoft/dotnet:2.1-aspnetcore-runtime2.1-aspnetcore-runtime:pulling to microsoft/ Dotnetbe8881be8156:pull completef854db899319:pull Complete4591fd524b8e:pull Complete65f224da8749:pull completeDigest:sha256:a43b729b84f918615d4cdce92a8bf59e3e4fb2773b8491a7cf4a0d728886eebaStatus:Downloaded newer Image for Microsoft/dotnet:2.1-aspnetcore-runtime---> Fcc3887985bbstep 2/5: workdir/appremoving Intermediate Container ABA36715ACFC---> 25bc5bb6871fstep 3/5: COPY. /app---> 9baaa790a82fstep 4/5: EXPOSE---> Running in 269408c67989removing Intermediate container 269408c6798 9---> Fbd444c44d20step 5/5: entrypoint ["dotnet", "NetCoreDraw.dll"]---> Running in 2a9ba559b137removing intermed Iate container 2a9ba559b137---> b1bb1dccd49asuccessfully built b1bb1dccd49asuccessfully tagged mywebimage: Latestwarning:image for serviceMyWeb was built because it does not already exist. To rebuild this image you must use ' docker-compose build ' or ' docker-compose up--build '. Creating myweb ... doneattaching to Mywebmyweb |       Warn:microsoft.aspnetcore.dataprotection.keymanagement.xmlkeymanager[35]myweb | No XML encryptor configured. Key {1f87d27e-c6b1-435f-bab6-aebacd6d6817} May is persisted to storage in unencrypted Form.myweb | Hosting Environment:productionmyweb | Content root path:/appmyweb | Now Listening On:http://[::]:5000myweb | Application started. Press CTRL + C to shut down.

  

In the browser to access my virtual machine site http://192.168.41.129:5000/, the picture does not appear.

The container debugging information can be seen in Xshell and an error has occurred.

MyWeb | 2018-07-29 09:50:04:753, start create Imagemyweb |       Info:microsoft.aspnetcore.mvc.internal.controlleractioninvoker[2]myweb | Executed Action NETCOREDRAW.CONTROLLERS.HOMECONTROLLER.GETIMG (netcoredraw) in 18.5988msmyweb |       Fail:microsoft.aspnetcore.diagnostics.exceptionhandlermiddleware[1]myweb | An unhandled exception have occurred while executing the Request.myweb | System.TypeInitializationException:The type initializer for ' Gdip ' threw an exception. ---> System.DllNotFoundException:Unable to load Shared library ' LIBDL ' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment Variable:liblibdl:cannot open Shar    Ed object File:no such file or Directorymyweb |    At Interop.Libdl.dlopen (String fileName, Int32 flag) myweb |    At System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary () myweb | At System.Drawing.SafeNativeMethods.Gdip.    Cctor () myweb | ---End of inner Exception stack Trace--- 

  

Unable to find library file LIBDL, there are similar problems and solutions on the Internet, which is to establish a file connection.

https://q.cnblogs.com/q/107946/

However, the location of the library files in the Aspnetcore container is not the same as the official release of CentOS and Ubuntu, so you have to go into the container to find it. When the container is running, it can open a terminal window and enter the container through the Xshell copy function.

Docker exec-it Myweb/bin/bash

Aspnetcore container does not support the locate command, I am not familiar with the Linux system file location, had to bite the bullet to see again, fortunately the catalogue is not many, and finally determined here.

[Email protected]:/# ls lib/x86_64-linux-gnu/libdl*

Lib/x86_64-linux-gnu/libdl-2.24.so lib/x86_64-linux-gnu/libdl.so.2

So modify the Dockerfile to

From Microsoft/dotnet:2.1-aspnetcore-runtimerun ln-s/lib/x86_64-linux-gnu/libdl-2.24.so/lib/x86_64-linux-gnu/ Libdl.soworkdir/appcopy. /appexpose 5000ENTRYPOINT ["dotnet", "NetCoreDraw.dll"]

  

Recompile, publish the Web site to the virtual machine, and rerun the compilation Run container.

[Email protected] home]# docker-compose up--build

Browse the site, still can't display the picture, but the error content changed.

MyWeb    | fail:microsoft.aspnetcore.diagnostics.exceptionhandlermiddleware[1]myweb    |       An unhandled exception have occurred while executing the Request.myweb    | System.TypeInitializationException:The type initializer for ' Gdip ' threw an exception. ---> System.DllNotFoundException:Unable to load DLL ' libgdiplus ': The specified module could not being Found.myweb    |< C5/>at System.Runtime.InteropServices.FunctionWrapper ' 1.get_delegate () myweb    |    At System.Drawing.SafeNativeMethods.Gdip.GdiplusStartup (intptr& token, startupinput& input, Startupoutput & Output) MyWeb    |    At System.Drawing.SafeNativeMethods.Gdip. Cctor () myweb    |    ---End of inner exception stack trace---

  

There is no libgdiplus this time, there is a solution on the Internet for this problem.

https://q.cnblogs.com/q/103863/

Because of the need to install something when the container runs, so to replace the domestic source, improve speed. Reference

Https://www.cnblogs.com/OMango/p/8519980.html

Change the dockerfile to this, pay attention to update the source to Apt-get update once, otherwise will error unable to locate package Libgdiplus.

From Microsoft/dotnet:2.1-aspnetcore-runtimerun ln-s/lib/x86_64-linux-gnu/libdl-2.24.so/lib/x86_64-linux-gnu/ Libdl.sorun echo "Deb Http://mirrors.aliyun.com/debian wheezy main contrib non-free deb-src http://mirrors.aliyun.com/ Debian wheezy main contrib non-free Deb Http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free deb-src http ://mirrors.aliyun.com/debian wheezy-updates main contrib non-free Deb Http://mirrors.aliyun.com/debian-security Wheezy/updates Main contrib non-free deb-src http://mirrors.aliyun.com/debian-security wheezy/updates main contrib Non-free ">/etc/apt/sources.listrun apt-get updaterun apt-get install libgdiplus-y && ln-s libgdiplus.so GDI Plus.dllworkdir/appcopy. /appexpose 5000ENTRYPOINT ["dotnet", "NetCoreDraw.dll"]

  

Run again, finally see the picture, but the Chinese characters are not shown.

Refer to the above article, copy the font files to the container, then install the font-related functions. Eventually the dockerfile grew like this.

From Microsoft/dotnet:2.1-aspnetcore-runtimerun ln-s/lib/x86_64-linux-gnu/libdl-2.24.so/lib/x86_64-linux-gnu/ Libdl.sorun echo "Deb Http://mirrors.aliyun.com/debian wheezy main contrib non-free deb-src http://mirrors.aliyun.com/ Debian wheezy main contrib non-free Deb Http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free deb-src http ://mirrors.aliyun.com/debian wheezy-updates main contrib non-free Deb Http://mirrors.aliyun.com/debian-security Wheezy/updates Main contrib non-free deb-src http://mirrors.aliyun.com/debian-security wheezy/updates main contrib  Non-free ">/etc/apt/sources.listrun apt-get updaterun apt-get install libfontconfig1-yrun apt-get Install Libgdiplus -y && ln-s libgdiplus.so gdiplus.dllcopy./fonts/msyh.ttc/usr/share/fonts/dejavuworkdir/appcopy. /appexpose 5000ENTRYPOINT ["dotnet", "NetCoreDraw.dll"]

  

Put Win10 Microsoft Jas font file MSYH.TTC into the fonts directory of the project, set the file properties "copy to Output directory" to "copy if newer".

Run the container again, it's done.

The implementation of the ASP. Cross-platform deployment to the Linux container is a leap forward in technology, but occasionally encounters problems related to Linux systems, always feeling like love and hate, too tired.

ASP. NET core uses System.Drawing.Common to deploy to Docker error issues

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.