Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use System.Drawing.Common in microsoft/dotnet:runtime #618

Closed
sddev-dotnet opened this issue Jul 7, 2018 · 27 comments

Comments

@sddev-dotnet
Copy link

commented Jul 7, 2018

Steps to reproduce the issue

  1. pull microsoft/dotnet:runtime
  2. add .net core app that is using System.Drawing.Common package
  3. try and run app

Expected behavior

Should be able to create thumbnail images using the Bitmap class from System.Drawing.Common

Actual behavior

Get error:
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 shared object file: No such file or directory

Additional information (e.g. issue happens only occasionally)

A little research says we need to install libgdiplus and libc6-dev. I used the following to attempt that:

# install libgdiplus for System.Drawing
RUN apt-get update && \
    apt-get install -y --allow-unauthenticated libgdiplus libc6-dev

# install x11 for System.Drawing
RUN apt-get update && \
    apt-get install -y --allow-unauthenticated libx11-dev

That fails with errors about hashes not matching or size being greater than expected

Output of docker version

Client:
 Version:      18.05.0-ce
 API version:  1.37
 Go version:   go1.9.5
 Git commit:   f150324
 Built:        Wed May  9 22:12:05 2018
 OS/Arch:      windows/amd64
 Experimental: false
 Orchestrator: swarm

Server:
 Engine:
  Version:      18.05.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.10.1
  Git commit:   f150324
  Built:        Wed May  9 22:20:16 2018
  OS/Arch:      linux/amd64
  Experimental: true

Output of docker info

Containers: 33
 Running: 4
 Paused: 0
 Stopped: 29
Images: 134
Server Version: 18.05.0-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host ipvlan macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 773c489c9c1b21a6d78b5c538cd395416ec50f88
runc version: 4fc53a81fb7c994640722ac585fa9ca548971871
init version: 949e6fa
Security Options:
 seccomp
  Profile: default
Kernel Version: 4.9.93-linuxkit-aufs
Operating System: Docker for Windows
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.934GiB
Name: linuxkit-00155d46f121
ID: JJAR:3NTY:2RV6:SQ7D:NF45:XVEM:QA3J:SHDB:ZEJS:BHIC:X3D2:VRT5
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): true
 File Descriptors: 51
 Goroutines: 70
 System Time: 2018-07-07T02:51:21.9916291Z
 EventsListeners: 1
Registry: https://index.docker.io/v1/
Labels:
Experimental: true
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

@sddev-dotnet sddev-dotnet changed the title Can use System.Drawing.Common in microsoft/dotnet:runtime Can't use System.Drawing.Common in microsoft/dotnet:runtime Jul 7, 2018

@sddev-dotnet

This comment has been minimized.

Copy link
Author

commented Jul 7, 2018

It turns out that I couldn't add that library from windows machine (where I was trying to build the container). After I pushed the Dockerfile out to a linux build agent, it was able to add the library and build properly. This causes some problem because I can't build the container the locally for development purposes but I can work around that for now.

@MichaelSimons

This comment has been minimized.

Copy link
Collaborator

commented Jul 18, 2018

@sddev-dotnet - Hmm, sounds like the underlying issue was an intermittent issue with the apt feed you are using to pull from. Try it again on your Windows machine. I just tried a Bitmap sample app and everything worked as expected from both a Windows and Linux Docker host. FYI - I was using the microsoft/dotnet:2.1-sdk image which is based on Debian Stretch.

One tip regarding the pattern used to install the apt packages. Make sure you cleanup the apt cache within your Dockerfile as this bloats the resulting image. It is a Docker best practice.

# install System.Drawing native dependencies
RUN apt-get update \
    && apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \
     && rm -rf /var/lib/apt/lists/*
@MichaelSimons

This comment has been minimized.

Copy link
Collaborator

commented Jul 18, 2018

Closing but feel free to continue the conversation.

@jugglingthebits

This comment has been minimized.

Copy link

commented Jul 26, 2018

I am having the same problem. I am trying to run tests in a GitLab CI task using the microsoft/dotnet:2.1-sdk (Debian Stretch) Docker image.

@MichaelSimons do I understand you correctly that this is working for you without building your own Docker image?

@MichaelSimons

This comment has been minimized.

Copy link
Collaborator

commented Aug 7, 2018

@jugglingthebits - No, the microsoft/dotnet images do not contain the native libgdiplus library required by System.Drawing. You will need to add this yourself. For my scenario, I added the following to my Dockerfile

# install System.Drawing native dependencies
RUN apt-get update \
    && apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \
     && rm -rf /var/lib/apt/lists/*
@jugglingthebits

This comment has been minimized.

Copy link

commented Aug 8, 2018

@MichaelSimons Thanks for the workaround! IMHO this is a bug in the docker image though, why did you close this?

@MichaelSimons

This comment has been minimized.

Copy link
Collaborator

commented Aug 8, 2018

The runtime Dockerfiles only install the core dependencies. There are additional dependencies that are required for non-mainline scenarios that are not included by default such as libgdiplus. The Docker images align with the product installers in this way. We did this in order to keep the runtime images to a reasonable size (something we receive a fair amount of feedback on).

@jugglingthebits

This comment has been minimized.

Copy link

commented Aug 8, 2018

Ah ok, tradeoffs :-)

Just my 2 cents, it would have helped me if there was documentation referenced from https://hub.docker.com/r/microsoft/dotnet/ where "non-mainline" apis were listed together with the packages required to enable them.

@MichaelSimons

This comment has been minimized.

Copy link
Collaborator

commented Aug 8, 2018

@jugglingthebits - That is a good suggestion. Would you mind logging a new issue specific to documenting these non-mainline scenarios? Please reference this issue. Thanks for the feedback!

@autukill

This comment has been minimized.

Copy link

commented Aug 28, 2018

This is my Dockerfile:

FROM docker.io/microsoft/dotnet:2.1-aspnetcore-runtime
COPY . /app
WORKDIR /app    

# soft link
RUN ln -s /lib/x86_64-linux-gnu/libdl-2.24.so /lib/x86_64-linux-gnu/libdl.so

# configure apt sources, only for Chinese users
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
   echo "deb http://mirrors.163.com/debian/ jessie main non-free contrib" >/etc/apt/sources.list && \
   echo "deb http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list && \
   echo "deb-src http://mirrors.163.com/debian/ jessie main non-free contrib" >>/etc/apt/sources.list && \
   echo "deb-src http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list

# install System.Drawing native dependencies
RUN apt-get update \
    && apt-get install -y --allow-unauthenticated \
   		libgdiplus \
#         libc6-dev \
#         libgdiplus \
#         libx11-dev \
     && rm -rf /var/lib/apt/lists/*

CMD ["dotnet", "Thinktank.Web.dll"]
@jbdhacf

This comment has been minimized.

Copy link

commented Sep 24, 2018

@autukill Dockerfile worked for me.

My Dockerfile starts with FROM microsoft/dotnet:2.1-sdk AS builder-stage. But remember to put @autukill fix after the runtime stage (FROM microsoft/dotnet:2.1-aspnetcore-runtime AS runtime-stage in my case)

@MaitePerez

This comment has been minimized.

Copy link

commented Jan 14, 2019

Hi!
I have the same problema but when i insall all the libgdiplus libreary then i have another error about Kernel32, im using dotnet core 2.0, is there any suggestion?

"Unable to load shared library 'kernel32.dll or one of its dependencies. In order to help diagnose problems, consider setting the LD_DEBUG enviroment variable: kernel32.dll: cannot open shared file: no such file or directory."

@MichaelSimons

This comment has been minimized.

Copy link
Collaborator

commented Jan 14, 2019

@MaitePerez - Please upgrade to .NET 2.1 or newer. 2.0 is EOL and no longer supported. I'm sure you will got more support once you upgrade to a supported version.

@MaitePerez

This comment has been minimized.

Copy link

commented Jan 14, 2019

@MichaelSimons Thank you so much for the replay.

I'm actually using net core 2.1 and net and net standar 2.0, sorry for the confusión.

@apincik

This comment has been minimized.

Copy link

commented Feb 10, 2019

For alpine dotnet runtime, add additional repository

RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && apk update && apk add --no-cache libgdiplus

@peterdeme

This comment has been minimized.

Copy link

commented Feb 15, 2019

Quick confirmation here. libgdiplus wasn't enough, I needed to use

RUN apt-get update \
    && apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \
     && rm -rf /var/lib/apt/lists/*

to have it working on microsoft/dotnet:2.1.2-aspnetcore-runtime.

@GustavSt

This comment has been minimized.

Copy link

commented Feb 23, 2019

I added the install of libgdiplus, but I still get this runtime error. Am I missing something from my Dockerfile?

I'm on windows but docker set to linux containers.

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM microsoft/dotnet:2.2-sdk AS build

# install System.Drawing native dependencies
RUN apt-get update \
    && apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \
     && rm -rf /var/lib/apt/lists/*

WORKDIR /src
COPY ["projectx/projectx.csproj", "projectx/"]
RUN dotnet restore "projectx/projectx.csproj"
COPY . .
WORKDIR "/src/projectx"
RUN dotnet build "projectx.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "projectx.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "projectx.dll"]
@sergey-brutsky

This comment has been minimized.

Copy link

commented Feb 26, 2019

RUN apk add libgdiplus-dev fontconfig ttf-dejavu --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted

For microsoft/dotnet:3.0-runtime-alpine

@jbdhacf

This comment has been minimized.

Copy link

commented Feb 27, 2019

I added the install of libgdiplus, but I still get this runtime error. Am I missing something from my Dockerfile?

I'm on windows but docker set to linux containers.

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM microsoft/dotnet:2.2-sdk AS build

# install System.Drawing native dependencies
RUN apt-get update \
    && apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \
     && rm -rf /var/lib/apt/lists/*

WORKDIR /src
COPY ["projectx/projectx.csproj", "projectx/"]
RUN dotnet restore "projectx/projectx.csproj"
COPY . .
WORKDIR "/src/projectx"
RUN dotnet build "projectx.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "projectx.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "projectx.dll"]

Make sure you install it in your runtime and not in your dotnet build.

e.g. here is my solution

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS runtime-stage

WORKDIR /app

#######################################################
# Add dependencies for Gdip in the runtime application. System.Drawing. 
#######################################################

RUN ln -s /lib/x86_64-linux-gnu/libdl-2.24.so /lib/x86_64-linux-gnu/libdl.so

RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
   echo "deb http://mirrors.163.com/debian/ jessie main non-free contrib" >/etc/apt/sources.list && \
   echo "deb http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list && \
   echo "deb-src http://mirrors.163.com/debian/ jessie main non-free contrib" >>/etc/apt/sources.list && \
   echo "deb-src http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list


# install System.Drawing native dependencies
RUN apt-get update \
    && apt-get install -y --allow-unauthenticated \
   		libgdiplus \
#         libc6-dev \
#         libgdiplus \
#         libx11-dev \
     && rm -rf /var/lib/apt/lists/*


############################### END of Gdip dependencies
@GustavSt

This comment has been minimized.

Copy link

commented Feb 27, 2019

@jbdhacf Thanks!
That was the issue. Moving the install up to under
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base solved my issue

@sandhaka

This comment has been minimized.

Copy link

commented Mar 22, 2019

With microsoft/dotnet:2.2-aspnetcore-runtime still have similar problems.

FROM microsoft/dotnet:2.2-aspnetcore-runtime
EXPOSE $PORT

# install System.Drawing native dependencies
RUN apt-get update \
    && apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \
     && rm -rf /var/lib/apt/lists/*

COPY bin/Release/netcoreapp2.2/publish/ /app/

WORKDIR /app

CMD /bin/bash -c "dotnet ea.Api.dll"

Unable to load shared library 'user32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libuser32.dll: cannot open shared object file: No such file or directory

tokmancev added a commit to tokmancev/dotnetcore-buildpack that referenced this issue Apr 17, 2019
@cmathewsgh

This comment has been minimized.

Copy link

commented May 9, 2019

With microsoft/dotnet:2.2-aspnetcore-runtime still have similar problems.

FROM microsoft/dotnet:2.2-aspnetcore-runtime
EXPOSE $PORT

# install System.Drawing native dependencies
RUN apt-get update \
    && apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \
     && rm -rf /var/lib/apt/lists/*

COPY bin/Release/netcoreapp2.2/publish/ /app/

WORKDIR /app

CMD /bin/bash -c "dotnet ea.Api.dll"

Unable to load shared library 'user32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libuser32.dll: cannot open shared object file: No such file or directory

Were you able to move past this issue?

@JetstreamRoySprowl

This comment has been minimized.

Copy link

commented Jun 7, 2019

For folks as noobish about Docker as I am, make sure that these changes (which worked for me - thanks!) get put in the LAST layer of your dockerfile. The provided code shows that clearly in the FROM statement, but I didn't notice that at first and added this stuff in my build layer, which of course was useless.

@WeihanLi

This comment has been minimized.

Copy link

commented Jul 30, 2019

can I use it with alpine docker images? seemed there's libgdiplus support for alpine https://pkgs.alpinelinux.org/packages?name=libgdiplus&branch=edge

-------------- update ---------------------

absolutely yes, you can specific the repository url

for example:

apk add libgdiplus --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted

you get the complete Dockerfile I used here https://github.com/WeihanLi/ActivityReservation/blob/dev/Dockerfile

@Dangelo123

This comment has been minimized.

Copy link

commented Aug 23, 2019

Hi!
I have the same problema but when i insall all the libgdiplus libreary then i have another error about Kernel32, im using dotnet core 2.0, is there any suggestion?

"Unable to load shared library 'kernel32.dll or one of its dependencies. In order to help diagnose problems, consider setting the LD_DEBUG enviroment variable: kernel32.dll: cannot open shared file: no such file or directory."

Same problem here @MaitePerez. Have you managed to find the solution?

@Dangelo123

This comment has been minimized.

Copy link

commented Aug 23, 2019

Hi!
I have the same problema but when i insall all the libgdiplus libreary then i have another error about Kernel32, im using dotnet core 2.0, is there any suggestion?

"Unable to load shared library 'kernel32.dll or one of its dependencies. In order to help diagnose problems, consider setting the LD_DEBUG enviroment variable: kernel32.dll: cannot open shared file: no such file or directory."

@MaitePerez I found the solution to my case, see if it's useful to you. I was using a library to convert html to pdf that depends on windows to run (even being .net core compatible). Here is the link of the issue: selectpdf/selectpdf-free-html-to-pdf-converter#2
The solution naturally was change to a lib that don't rely on windows dlls.

@JetstreamRoySprowl

This comment has been minimized.

Copy link

commented Aug 23, 2019

This line plus the next 10 lines gave us what we needed to use a Bitmap

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.