dotnet / dotnet-docker

Docker images for .NET and the .NET Tools.
https://hub.docker.com/_/microsoft-dotnet
MIT License
4.38k stars 1.91k forks source link

arm32 image build crashes when using asp.net core react app project. #879

Closed oblomingo closed 5 years ago

oblomingo commented 5 years ago

Context:

I am developing Asp.Net Core application (with React front-end) for my Raspberry Pi 3 Model B+. Application based on template (dotnet new react -o react-app).

I want to develop and debug application locally in my Windows OS laptop, then build application for ARM32 architecture, push image to docker hub and pull and run image on Raspberry device.

I found that, if I build application using microsoft/dotnet:2.2-sdk and microsoft/dotnet:2.2-aspnetcore-runtime on my Windows laptop, then I can't run this image on Raspberry device with error message: 'standard_init_linux.go:190: exec user process caused "exec format error"'. Looks like Windows builded image siutable only for AMD64 architecture.

Then I tried to change builder and runtime images to AMD32, but now build process crashes

Steps to reproduce the issue

  1. Create project with command dotnet new react -o react-app
  2. Add .dockerignore with content:
    **/obj/
    **/bin/
    **/node_modules/
  3. Add Dockerfile with content:
    
    #FROM microsoft/dotnet:2.2-sdk AS builder
    FROM microsoft/dotnet:2.2-sdk-stretch-arm32v7 AS builder
    WORKDIR /source

RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - RUN apt-get install -y nodejs

COPY *.csproj . RUN dotnet restore

COPY ./ ./

RUN dotnet publish "./react-app.csproj" --output "./dist" --configuration Release --no-restore

FROM microsoft/dotnet:2.2-aspnetcore-runtime

FROM microsoft/dotnet:2.2-aspnetcore-runtime-stretch-slim-arm32v7 as runtime WORKDIR /app COPY --from=builder /source/dist . EXPOSE 80 ENTRYPOINT ["dotnet", "react-app.dll"]

4. Run command  **docker build -t test/react-app .**
## Expected behavior
Docker builds image 

## Actual behavior
Build process crashes with messages:

Sending build context to Docker daemon 12.88MB Step 1/13 : FROM microsoft/dotnet:2.2-sdk-stretch-arm32v7 AS builder ---> 790bf01f39eb Step 2/13 : WORKDIR /source ---> Using cache ---> df80839bc7cb Step 3/13 : RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - ---> Using cache ---> 18f903f9592e Step 4/13 : RUN apt-get install -y nodejs ---> Using cache ---> bab99e359b76 Step 5/13 : COPY *.csproj . ---> Using cache ---> 3a3fff94fb2a Step 6/13 : RUN dotnet restore ---> Running in afa26aa5a029 qemu: Unsupported syscall: 389 qemu: Unsupported syscall: 345 qemu: uncaught target signal 11 (Segmentation fault) - core dumped Segmentation fault The command '/bin/sh -c dotnet restore' returned a non-zero code: 139


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

## Output of `docker version`

Client: Docker Engine - Community Version: 18.09.0 API version: 1.39 Go version: go1.10.4 Git commit: 4d60db4 Built: Wed Nov 7 00:47:51 2018 OS/Arch: windows/amd64 Experimental: false

Server: Docker Engine - Community Engine: Version: 18.09.0 API version: 1.39 (minimum version 1.12) Go version: go1.10.4 Git commit: 4d60db4 Built: Wed Nov 7 00:55:00 2018 OS/Arch: linux/amd64 Experimental: false


## Output of `docker info`

Containers: 20 Running: 3 Paused: 0 Stopped: 17 Images: 74 Server Version: 18.09.0 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 macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: 468a545b9edcd5932818eb9de8e72413e616e86e runc version: 69663f0bd4b60df09991c08812a60108003fa340 init version: fec3683 Security Options: seccomp Profile: default Kernel Version: 4.9.125-linuxkit Operating System: Docker for Windows OSType: linux Architecture: x86_64 CPUs: 2 Total Memory: 1.934GiB Name: linuxkit-00155d089d03 ID: LI7I:MFZC:QP57:2PO6:WR3J:TA6N:TM6Q:FFUF:XX7O:AWKH:UKKH:BNNG Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): true File Descriptors: 35 Goroutines: 56 System Time: 2019-01-05T12:17:35.7127918Z EventsListeners: 1 Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false Product License: Community Engine

MichaelSimons commented 5 years ago

For illustration purposes, let's use the following example which utilizes multi-arch tags.

FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /app

# copy csproj and restore as distinct layers
COPY dotnetapp/*.csproj ./dotnetapp/
WORKDIR /app/dotnetapp
RUN dotnet restore

# copy and publish app and libraries
WORKDIR /app/
COPY dotnetapp/. ./dotnetapp/
WORKDIR /app/dotnetapp
RUN dotnet publish -c Release -o out

FROM microsoft/dotnet:2.2-runtime AS runtime
WORKDIR /app
COPY --from=build /app/dotnetapp/out ./
ENTRYPOINT ["dotnet", "dotnetapp.dll"]

If you build this in a Linux amd64 container environment, it will produce a Linux amd64 image. If you build it in a Linux arm32 container environment, it will produce a Linux arm32 image. The same thing happens within Windows amd64 and arm32 environments. In order to run the resulting images, they must be run on a container platform that is compatible/matching the image (e.g. linux/windows and arch). Hopefully this helps explain the behavior you saw when using the multi-arch tags.

You have two options for building your arm32 images.

  1. Build the image on arm32 hardware. When doing this you can use either the multi-arch tags or the arm32 tags. Either way will product the same arm32 image. One factor that may influence your decision on which tags to use is whether or nor your app is multi-platform. If it is you may be able to define a single Dockerfile that is capable of producing multiple platform specific images (e.g. for example build it on amd64 and again on arm32)

  2. Create a hybrid Dockerfile that is capable of being built on amd64 but produces an arm32 image. Here we will use the amd64 sdk image to build the application. You cannot utilize the arm32 sdk on an amd64 host because .NET Core doesn't support running with QEMU which is what Docker utilizes under the covers

FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /app

# copy csproj and restore as distinct layers
COPY dotnetapp/*.csproj ./dotnetapp/
WORKDIR /app/dotnetapp
RUN dotnet restore

# copy and publish app and libraries
WORKDIR /app/
COPY dotnetapp/. ./dotnetapp/
WORKDIR /app/dotnetapp
RUN dotnet publish -c Release -o out

FROM microsoft/dotnet:2.2-runtime-stretch-slim-arm32v7 AS runtime
WORKDIR /app
COPY --from=build /app/dotnetapp/out ./
ENTRYPOINT ["dotnet", "dotnetapp.dll"]

It sounds like you are looking for the second option.

MichaelSimons commented 5 years ago

Closing due to inactivity