
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.

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.
References
My posts on Raspberry Pi ⚡🐲⚡
Dev posts for Raspberry Pi
- How to grant permissions to a folder after git clone, to perform dotnet restore on a Raspberry Pi
- How to install .Net Core 3.1 in a Raspberry Pi 4
- Installing Visual Studio Code in a Raspberry Pi 4, run as root, fix black screen
- How to install .Net Core in a Raspberry Pi 4 and test with Hello World
- Build and Run C# NetCore projects in a Raspberry Pi 4 with Visual Studio Code
- Let’s do some Git dev in Raspberry Pi 4 (GitHub and Azure DevOps!)
- Install OpenCV
- Install Python 🐍 Virtual Environments in Raspberry Pi
- Setup SSH passwordless access to remote work with Docker 🐳
- Manage Docker 🐳 as a non-root user
- Build Docker 🐳 images from Visual Studio Code remotely using a Raspberry Pi
Tools and Apps for Raspberry Pi
- Where is my Task Manager in RaspberryPi? Let’s try htop
- Multi-monitor 📺 in Raspberry Pi 4 rocks !
- Double Commander on RaspberryPi4, because files are important
- How to install Docker 🐳 in a Raspberry Pi 4
- Installing Visual Studio Code in a Raspberry Pi
- Installing Visual Studio Code in a Raspberry Pi, run as root, fix black screen (Updated)
- 6 commands to install OpenCV for Python 🐍 in a Raspberry Pi 4
Setup the device
- 1st Setup without monitor 📺: auto connect to WiFi 📶, enable SSH, update and more
- Setup without monitor: enable VNC
- How to enable auto start with HDMI safe mode
- Running a Python 🐍 script in a Python Virtual Environment on reboot / startup
- Setup Wifi on Ubuntu
Hardware
- Ice Tower, the best cooler 🧊 for your device! From 70C to <40C in a 60 minutes process running at 100% in all 4 cores
- Intel Neural Stick 2, Performance differences in Face Recognition using OpenVino
¿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:
- Si tienes ganas de ponerte al día con Front End (ES6, Typescript, React, Angular, Vuejs…) te recomendamos nuestros Máster Front End: https://lemoncode.net/master-frontend#inicio-banner
- Si te quieres poner al día en Backend (stacks .net y nodejs), te aconsejamos nuestro Bootcamp Backend: https://lemoncode.net/bootcamp-backend#bootcamp-backend/banner
- Y si tienes ganas de meterte con Docker, Kubernetes, CI/CD…, tenemos nuestro Bootcamp Devops: https://lemoncode.net/bootcamp-devops#bootcamp-devops/inicio
2 comments