May 20, 2018 Update: This post is now obsolete as of .NET Core 2.1! Please see this blog post for details.
dotnet new react by default will give you a project that runs fine on x86/x64 architectures. The RPI, however, runs on arm32v7. We'll need to make a few small changes to support this architecture within Docker.
New projects by default include the metapackage Microsoft.AspNetCore.All, which makes some assumptions about what libraries are already on the runtime target. For this to work with Docker, this means the runtime image needs to be microsoft/aspnetcore. However, this poses a problem!
There is no ARM package for the microsoft/aspnetcore Docker image. The dockerfile indicates that pre-made binaries for this image are pulled from a CDN, but there don't appear to be any that exist for armv7.
Fortunately, there is a docker image already for the ARMv7 .NET Core runtime, we are be able to use that as a base image! Now we just have to declare the AspNetCore dependencies explicitly.
A working example of this project lives at this GitHub repo
- Create a new project with
dotnet new react
- Remove the
Microsoft.AspNetCore.Allreference in the project file and replace it with these references:
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
- Verify the app still works with
- Create a Dockerfile that looks something like this:
FROM microsoft/aspnetcore-build:2 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 microsoft/dotnet:2.0-runtime WORKDIR /app COPY --from=build-env /app/out ./ ENTRYPOINT ["dotnet", "DpmWebsite.dll"] EXPOSE 5000
Then, copy this dockerfile to a new file named
Dockerfile.arm32. This should be identical, except we're going to change the runtime image to:
This allows the application to boot from the ARM version of the .NET SDK.
Now, ensure a local build works:
docker build -t netcore-local . docker run -d -p 5000:5000 netcore-local
Once this is confirmed working, build an ARM specific image:
docker build -t yourdockerid/rpi-net-core -f Dockerfile.arm32 . docker push yourdockerid/rpi-net-core
Finally, pull the image and run it on your Raspberry Pi!
docker pull yourdockerid/rpi-net-core docker run --restart=always -d -p 5000:5000 yourdockerid/rpi-net-core
If you are having trouble, get the ID of the image, then use
docker logs (containerid)
This was a fun exercise. It's so exciting to see the .NET platform become more accessible, hats off to the whole team for making this a reality!