#RaspberryPi – Build #docker 🐳 images from Visual Studio @Code remotely using a Raspberry Pi. #AzureIoT

Buy Me A Coffee

Hi !

The post title is very descriptive, however let me share some more context on why I needed this scenario.

I’m currently working in an Azure IoT custom module. I got installed the Azure IoT extensions on Visual Studio Code, so everything works great on the Hello World mode. Once I wrote my code logic in C#, I can easily build my IoT Edge Solution.

My default configuration focus to an amd64 platform. I got this defined in my settings.json

    "azure-iot-edge.defaultPlatform": {
        "platform": "amd64",
        "alias": null

This is a sample log output, using my local docker in Windows 10. Everything works fine.

[+] Building 0.7s (16/16) FINISHED
 => [internal] load build definition from Dockerfile.amd64                                                                                                                                                                                  0.1s
 => => transferring dockerfile: 38B                                                                                                                                                                                                         0.1s 
 => [internal] load .dockerignore                                                                                                                                                                                                           0.1s 
 => => transferring context: 34B                                                                                                                                                                                                            0.1s 
 => [internal] load metadata for mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim                                                                                                                                                      0.5s
 => [internal] load metadata for mcr.microsoft.com/dotnet/core/sdk:3.1-buster                                                                                                                                                               0.5s 
 => [build-env 1/6] FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster@sha256:0fece15a102530aa2dad9d247bc0d05db6790917696377fc56a8465604ef1aff                                                                                               0.0s
 => [internal] load build context                                                                                                                                                                                                           0.0s 
 => => transferring context: 446B                                                                                                                                                                                                           0.0s 
 => [stage-1 1/4] FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim@sha256:e84300e54209cad66611b0b483cfe8c007d3bb5450388ff58e7f15d025917817                                                                                        0.0s 
 => CACHED [stage-1 2/4] WORKDIR /app                                                                                                                                                                                                       0.0s
 => CACHED [build-env 2/6] WORKDIR /app                                                                                                                                                                                                     0.0s 
 => CACHED [build-env 3/6] COPY *.csproj ./                                                                                                                                                                                                 0.0s 
 => CACHED [build-env 4/6] RUN dotnet restore                                                                                                                                                                                               0.0s 
 => CACHED [build-env 5/6] COPY . ./                                                                                                                                                                                                        0.0s 
 => CACHED [build-env 6/6] RUN dotnet publish -c Release -o out                                                                                                                                                                             0.0s 
 => CACHED [stage-1 3/4] COPY --from=build-env /app/out ./                                                                                                                                                                                  0.0s 
 => CACHED [stage-1 4/4] RUN useradd -ms /bin/bash moduleuser                                                                                                                                                                               0.0s 
 => exporting to image                                                                                                                                                                                                                      0.0s 
 => => exporting layers                                                                                                                                                                                                                     0.0s 
 => => writing image sha256:8d38fb01640fb566e761231c1a646df35bb83f24dfbb0fdea92bc4db62576e12                                                                                                                                                0.0s 
 => => naming to <...>

If I want to change the target platform to build an arm32 image, I change my settings.json file to:

    "azure-iot-edge.defaultPlatform": {
        "platform": "arm32v7",
        "alias": null

Note: if you don’t have this file, simply add a new settings.json file to the [.vscode] folder

However I got this ugly error, trying to build this

=> CACHED [build-env 2/6] WORKDIR /app                                                                                                                                                                                                     0.0s 
 => CACHED [build-env 3/6] COPY *.csproj ./                                                                                                                                                                                                 0.0s 
 => ERROR [build-env 4/6] RUN dotnet restore                                                                                                                                                                                                0.5s
 > [build-env 4/6] RUN dotnet restore:
#10 0.450 A fatal error occurred, the folder [/usr/share/dotnet/host/fxr] does not contain any version-numbered child folders
executor failed running [/bin/sh -c dotnet restore]: exit code: 131

There seems to be an error here, outside of my docker knowledge.

Of course, a test path could involve the use of a remote ARM32 Docker Environment to build my Azure IoT Edge C# Module. I followed my previous posts steps to enable SSH password-less access to my Raspberry Pi and also manage docker as non-root users (see references).

Now I can define a specific DOCKER EXECUTOR to build my images. I changed my settings.json file to define this executor. Note that you must define a standard SSH connection, this may involve your device name or IP Address.

    "azure-iot-edge.defaultPlatform": {
        "platform": "arm32v7",
        "alias": null
    "azure-iot-edge.executor.env": {
         "DOCKER_HOST": "ssh://pi@<Raspberry PI Address>"

Important: once you changed your settings.json configuration, you need to reload your VSCode environment. You can close and open the IDE, or even better, invoke the [Reload Window] command.

visual studio code reload window

Now we can sucesfully build the Azure IoT module. the output log will be similar to this one:

Sending build context to Docker daemon  24.06kB
Step 1/12 : FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster-arm32v7 AS build-env
 ---> 3cdfdcca7cd6
Step 2/12 : WORKDIR /app
 ---> Using cache
 ---> 8c3252bfdefb
Step 3/12 : COPY *.csproj ./
 ---> Using cache
 ---> e6fe11cb659e
Step 4/12 : RUN dotnet restore
 ---> Using cache
 ---> 12453c83de65
Step 5/12 : COPY . ./
 ---> Using cache
 ---> 107c1dfccfa3
Step 6/12 : RUN dotnet publish -c Release -o out
 ---> Using cache
 ---> 603a93c80b0e
Step 7/12 : FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim-arm32v7
 ---> 2bb8fc093aad
Step 8/12 : WORKDIR /app
 ---> Using cache
 ---> c8a93a2a7b90
Step 9/12 : COPY --from=build-env /app/out ./
 ---> Using cache
 ---> f72a492270ad
Step 10/12 : RUN useradd -ms /bin/bash moduleuser
 ---> Using cache
 ---> 082a4568867b
Step 11/12 : USER moduleuser
 ---> Using cache
 ---> 2c5e7b562289
Step 12/12 : ENTRYPOINT ["dotnet", "UDPFwder.dll"]
 ---> Using cache
 ---> f523123332f9
Successfully built f523123332f9
Successfully tagged <...>
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

And that’s it! Using a Raspberry Pi device to build Net Azure IoT modules seems to be the fix to build ARM32 platforms.


Happy coding!


El Bruno

More posts in my blog ElBruno.com.

My posts on Raspberry Pi ⚡🐲⚡

Dev posts for Raspberry Pi
Tools and Apps for Raspberry Pi
Setup the device

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría:


Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: