Setting up a Raspberry Pi to run and display an ASP.NET Core Web App

August 11, 2020


Contents


Introduction

If you want a monitor that displays a custom web app, here are the steps to do that using a Raspberry Pi and ASP.NET Core. To display the web app, we'll use the Chromium web browser.

This assumes you have created a web app using ASP.NET Core 3.1.

Hardware

  • Make sure you have everything required to run a raspberry pi 3 or 4.
  • To set up the wall display, you'll need and a monitor and HDMI cable.
  • To set it up as a kiosk, you'll need a keyboard and mouse. (optional)

Install Raspberry Pi OS on the SD card (reference)

I used Raspberry Pi Imager v1.3 to put Raspberry Pi OS Lite (32-bit) (2020-05-27 release) onto an SD Card.

You may also want to set up wifi and enable ssh here (especially if you don't have a keyboard attached to the device):

  1. Remove and reinsert the SD card.
  2. Create a file named "ssh" in the base directory. You can leave it empty or put a single space in it.
  3. Create a file named "wpa_supplicant.conf" in the base directory. Contents:

country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
  ssid="NETWORK-NAME"
  psk="NETWORK-PASSWORD"
}

Insert the SD card into the device and power it on.

Basic configuration

Find the rapberrypi IP address and SSH into it. The default username is pi, and the default password is raspberry.

Type sudo raspi-config

  1. (optional) Change your password
  2. (optional) Under Network Options, change the hostname of the device
  3. Under Boot Options, set it to "Console Autologin" (Open option B1 then B2)
  4. (optional) Under Localisation Options

(I1) Change locale to en_US.UTF-8
(I2) Change time zone to US - Central
5. (optional) Under Advanced Options
(A1) Expand filesystem
(A2) Overscan -> No


Select Finish

Restart the device using the command sudo reboot

Install and configure Chromium (reference)

  1. Update the system

sudo apt-get update -y
sudo apt-get upgrade -y 2. Keep the device from going to sleep
Enter the command sudo nano /etc/rc.local to edit the rc.local file
Add line /sbin/iw wlan0 set power_save off above exit 0
You can check if power save is on with the command /sbin/iw wlan0 get power_save
3. Install Openbox window manager
sudo apt-get install --no-install-recommends xserver-xorg x11-xserver-utils xinit openbox 4. Install Chromium browser
sudo apt-get install --no-install-recommends chromium-browser 5. Edit Openbox config
sudo nano /etc/xdg/openbox/autostart
Add the following text:


xset -dpms      # turn off display power management system
xset s noblank  # turn off screen blanking
xset s off      # turn off screen saver

# Remove exit errors from the config files that could trigger a warning
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' ~/.config/chromium/'Local State'
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/; s/"exit_type":"[^"]\+"/"exit_type":"Normal"/' ~/.config/chromium/Default/Preferences

# Run Chromium in kiosk mode
chromium-browser  --noerrdialogs --disable-infobars --kiosk --incognito --check-for-update-interval=31536000 $KIOSK_URL

  1. Set the KIOSK_URL environment value

sudo nano /etc/xdg/openbox/environment
Add the following line (we'll change the URL later):


export KIOSK_URL=https://www.wikipedia.org

  1. Start the X server on boot

sudo nano ~/.bash_profile
Add the following line:


[[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && startx -- -nocursor

  1. Load the bash profile

source ~/.bash_profile
9. Reboot
sudo reboot


Install Sqlite (optional)

sudo apt-get update
sudo apt-get install sqlite3 libsqlite3-dev

Publish your ASP.NET Core project (reference)

Note: Change specific locations and names below to your own!

  1. Create directory for our web app files

mkdir ~/myapp
2. On development machine, create self contained deployment
cd C:\Projects\myapp\MyWebApp
dotnet publish -r linux-arm --configuration Release
3. Copy files in the publish folder to the target machine. Here, we are using SCP to copy the files.
cd C:\Projects\myapp\MyWebApp\bin\Release\netcoreapp3.1\linux-arm\publish\
scp -r ./* pi@192.168.1.16:/home/pi/myapp


Set permissions

  1. Set executable permission

cd ~/myapp
sudo chmod +x MyWebApp
2. Copy to final location
sudo mkdir /var/www
sudo mkdir /var/www/myapp
sudo cp -R /home/pi/myapp/* /var/www/myapp
3. Create sqlite db file (optional)
cd /var/www/myapp
sudo sqlite3 SqliteDB.db
sudo chmod 664 SqliteDB.db
4. Update permissions
sudo chgrp -R www-data /var/www/myapp/
sudo chmod 775 /var/www/myapp/


Add service for your ASP.NET app (reference)

Note: We are executing using --urls http://*:5000 to listen on all network adapters on the device

  1. Add service to systemd

sudo nano /etc/systemd/system/kestrel-myapp.service


[Unit]
Description=My ASP.NET Core Web App

[Service]
WorkingDirectory=/var/www/myapp
ExecStart=/var/www/myapp/MyWebApp --urls http://*:5000
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=myapp
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

  1. Update openbox url env variable

sudo nano /etc/xdg/openbox/environment


export KIOSK_URL=http://localhost:5000

  1. Enable and start service

sudo systemctl enable kestrel-myapp.service
sudo systemctl start kestrel-myapp.service
Check the status of the service
sudo systemctl status kestrel-myapp.service
4. To check for errors
sudo journalctl -fu kestrel-myapp.service
Or
sudo journalctl -n 30 -u kestrel-myapp.service
5. Reboot
sudo reboot


After rebooting, our web service should automatically start up, and the Chromium browser should open to the URL that we configured.

Mount your display

After confirming that everything is working, you can shut down the device and mount it in its final location.

To shut down, use sudo halt. Do not unplug the raspberry pi while it is running because there is a chance that the SD card could get corrupted.

Set up in new location

If you need to change the wifi ssid and password for the new location

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

Modify the existing values, or add the following:

network={
   ssid="mywifi"
   psk="mywifipassword"
}