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

Build a docker arm32 image for Raspberry Pi Debian Jessie - From Linux Ubuntu x64 #775

Closed
tonyawad88 opened this issue Oct 29, 2018 · 7 comments
Labels

Comments

@tonyawad88
Copy link

tonyawad88 commented Oct 29, 2018

Hello,

I tried running your image from the docker repo on the raspberry pi 3 debian jessie and it works great:
docker run --rm -it -p 8000:80 microsoft/dotnet-samples:aspnetapp

However, when I try to build a simple barebone aspnet core app v2.1 from my linux ubuntu x64 dev box, I can't seem to make it run on the rpi.

Dockerfile: (repo: https://github.com/tonyawad88/AspNetCore-with-Docker)

FROM microsoft/dotnet:2.1-sdk-stretch-arm32v7 AS build
#FROM microsoft/dotnet:2.1-sdk AS build
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 -r linux-arm

# Build runtime image
FROM microsoft/dotnet:2.1-runtime-deps-stretch-slim-arm32v7 AS runtime
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "aspnetcoreapp.dll"]

Running the above on the ubuntu dev box: returns:
standard_init_linux.go:190: exec user process caused "exec format error"

I tried switching the
FROM microsoft/dotnet:2.1-sdk-stretch-arm32v7 AS build to
FROM microsoft/dotnet:2.1-sdk AS build to build on the ubuntu x64. It builds fine but when I try to run on rpi3:
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"dotnet\": executable file not found in $PATH": unknown.

Any help is greatly appreciated.

Minor note: The arm32 Dockerfile is missing from this repo.

Thank you!

Output of docker version

Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:24:51 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:23:15 2018
  OS/Arch:          linux/amd64
  Experimental:     false

Output of docker info

Containers: 4
 Running: 0
 Paused: 0
 Stopped: 4
Images: 35
Server Version: 18.06.1-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 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: 468a545b9edcd5932818eb9de8e72413e616e86e
runc version: 69663f0bd4b60df09991c08812a60108003fa340
init version: fec3683
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.15.0-38-generic
Operating System: Ubuntu 18.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 3.852GiB
Name: ubuntudesktop-VirtualBox
ID: ZXHW:G4HK:O5SW:JPOU:LARS:BKXJ:Z2GR:S22R:OTKK:7272:ZLIQ:RU2C
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

WARNING: No swap limit support
@MichaelSimons
Copy link
Member

@tonyawad88 - Building arm32 images on amd64 is not supported. There are some general workarounds various people have some success with involving QEMU but .NET Core does not support running w/QEMU.

When you changed the base image to microsoft/dotnet:2.1-sdk you are actually switching to an amd64 base image. The 2.1-sdk tag is a multi-arch tag. When you pull a multi-arch tag, you will get the appropriate image for the platform you are pulling from. This means if you pull a multi-arch tag from an arm platform you will get an arm image, if you pull from an amd64 platform you will get an amd64 image.

Can you clarify what you meant by the following?

Minor note: The arm32 Dockerfile is missing from this repo.

Were you following a link from the full description on Docker Hub or this repo's readme? If so what link were you using? The Dockerfile for the microsoft/dotnet:2.1-sdk-stretch-arm32v7 tag is located at https://github.com/dotnet/dotnet-docker/blob/master/2.1/sdk/stretch/arm32v7/Dockerfile

@tonyawad88
Copy link
Author

tonyawad88 commented Oct 30, 2018

@MichaelSimons It was the link for the arm32 sample on the main dotnet-docker page. Link: https://github.com/dotnet/dotnet-docker, broken link is under section ARM32 / Raspberry Pi (first bullet, second link)
Also, under https://store.docker.com/community/images/microsoft/dotnet-samples the link to the Dockerfile.debian-arm32 is broken under Linux arm32 Tags

If I understand correctly, there's 2 ways to tackle this:

  1. either I pull the code to an arm32 platform, build the dotnet core app there and run it using the multi-arch tag microsoft/dotnet:2.1-sdk and that will get me a runnable dotnet core app?

  2. Or is the other way, to push to a remote docker repo under my docker cloud account for example, using the multi-arch tag and then pull from the arm32 platform and run? Similar to the remote repo you guys have hosted? And technically you only need 1 Dockerfile https://github.com/dotnet/dotnet-docker/blob/master/samples/aspnetapp/Dockerfile ?

Thank you for the information !

@tonyawad88
Copy link
Author

tonyawad88 commented Oct 30, 2018

I tried #2 with the Dockerfile using the multi-arch tag "https://github.com/tonyawad88/AspNetCore-with-Docker/blob/master/Dockerfile" and pushed to docker cloud. Then ran the following command from the raspberry pi with no luck: sudo docker run -it --rm -p 8000:80 --name aspnetcore_sample tonyawad/aspnetcore-docker_raspberrypi

I still got the following:
standard_init_linux.go:190: exec user process caused "exec format error"

Any help is greatly appreciated.
Cheers.

@MichaelSimons
Copy link
Member

@tonyawad88 - there are three ways I'd suggest building your arm Dockerfiles.

  1. Build your application and Dockerfile on an arm32 platform. You can use a multi-stage Dockerfile to achieve this. In this scenario, you can use the mutli-arch tags as done in the sample and therefore your Dockerfile would be x-platform. If your app/Dockerfile is arch specific, I would suggest using the platform specific tags such as microsoft/dotnet:2.1-runtime-stretch-slim-arm32v7.

  2. Build your application on amd64, publish the artifacts someplace, and then build your arm Dockerfile on an arm32 platform coping the published artifacts into the image. A reason to use this approach is if your product build is big/complex and doesn't work on arm or would be very slow.

  3. Build your application and Dockerfile on amd64 but target arm. This scenario will work if you are explicit with the tags being used and you do not invoke dotnet within your arm container. This option is noted here. If you want to try it out with the samples, change this line to use the microsoft/dotnet:2.1-runtime-stretch-slim-arm32v7 image. Build on your linux amd64 environment and copy the resulting image to a Docker registry. You can then test your built image by pulling it from your arm machine.

@tonyawad88
Copy link
Author

tonyawad88 commented Oct 31, 2018

@MichaelSimons Thank you Michael. The first one worked great, pulled the code to the arm32 system, built and ran the app and it worked great.

The 2nd one, I didn't quite understand, if you can elaborate that would be amazing.

The 3rd point, I tried building on amd64 the following dockerfile: sudo docker build -t aspnetcoreapp/v2 -f Dockerfile.debian-arm32-selfcontained

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

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

# Copy everything else and build
COPY . ./
#RUN dotnet add package ILLink.Tasks -v 0.1.5-preview-1841731 -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json
RUN dotnet publish -c Release -o out -r linux-arm

# Build runtime image
FROM microsoft/dotnet:2.1-runtime-deps-stretch-slim-arm32v7 AS runtime
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "aspnetcoreapp.dll"]

Tagged it and pushed it to docker cloud and then pulled and ran from the arm32 with no luck.
sudo docker pull tonyawad/aspnetcore-arm-test:latest
sudo docker run -d -p 8082:80 tonyawad/aspnetcore-arm-test

I am still getting the docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"dotnet\": executable file not found in $PATH": unknown.

Any thoughts on the point 3 you suggested, would be greatly appreciated.
Thank you!

@MichaelSimons
Copy link
Member

@tonyawad88, The second approach is to do the following.

  1. Build/publish your application on amd64. If you are building a self-contained application, you would target arm.
  2. Push the publish artifacts to some storage location - e.g. an azure blob storage account.
  3. From your arm environment build a Dockerfile that follows the following pattern:
FROM microsoft/dotnet:2.1-runtime-stretch-slim-arm32v7
WORKDIR /app
RUN curl -SL --output app.tar.gz https://yourstorage.blob.core.windows.net/app.v1.0.tar.gz \
    && tar -zxf app.tar.gz -C . \
    && rm app.tar.gz
ENTRYPOINT ["dotnet", "aspnetcoreapp.dll"]
  1. Test the resulting image.

Regarding your Dockerfile that follows my third suggestion. I see you are building a self-contained app. When building a self-contained app, an executable is created. This is what you would launch because there is no dotnet runtime installed that provides dotnet. If you look at the publish output, you should see an executable aspnetcoreapp file. See this Dockerfile, in particular notice how the ENTRYPOINT is defined. In comparison look at a framework-dependent Dockerfile. In case you are not familiar with the deployment types, this doc should help.

@MichaelSimons
Copy link
Member

@tonyawad88, hopefully I answered your questions. I also want to call out that the broken readme links were updated as well (#781). Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants