.NET Core in Docker on a Raspberry Pi
Tags: docker, dotnet, raspberrypi
Published: 2018-05-04 03:28:58

---
title: .NET Core in Docker on a Raspberry Pi
published: true
description: We're living in the future.
tags: docker,dotnet,raspberrypi
cover_image: https://raw.githubusercontent.com/dustinsoftware/RPI-Docker-ASPNetCore/master/screenshot.png
---

### May 20, 2018 Update: This post is now obsolete as of .NET Core 2.1! Please see [this](https://blogs.msdn.microsoft.com/dotnet/2018/05/07/announcing-net-core-2-1-rc-1/) blog post for details.

---

### Out of date information below:

`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.

### ARM is supported by ASP.NET Core, so why doesn't it just work in Docker?

New projects by default include the metapackage [Microsoft.AspNetCore.All](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage), 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](https://hub.docker.com/r/microsoft/aspnetcore/). However, this poses a problem!

There is no ARM package for the microsoft/aspnetcore Docker image. The [dockerfile](https://github.com/aspnet/aspnet-docker/blob/3fb758ced1e1735d604b30dfc2ff554d2b7a2f5d/2.0/jessie/runtime/Dockerfile#L5) 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.

### Using a different base image

Fortunately, there is a docker image already for the [ARMv7 .NET Core runtime](https://github.com/dotnet/dotnet-docker/blob/master/2.0/runtime/stretch/arm32v7/Dockerfile), we are be able to use that as a base image! Now we just have to declare the AspNetCore dependencies explicitly.

### Getting started

A working example of this project lives at [this GitHub repo](https://github.com/dustinsoftware/RPI-Docker-ASPNetCore)

- Create a new project with `dotnet new react`
- Remove the `Microsoft.AspNetCore.All` reference in the project file and replace it with these references:
```xml
    <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 `dotnet run`
- Create a Dockerfile that looks something like this:
```docker
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:

```docker
FROM microsoft/dotnet:2.0.0-runtime-stretch-arm32v7
```

This allows the application to boot from the ARM version of the .NET SDK.

Now, ensure a local build works:

```sh
docker build -t netcore-local .
docker run -d -p 5000:5000 netcore-local
```

Once this is confirmed working, build an ARM specific image:
```sh
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! 

```sh
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)`



### Thanks for reading!

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!