In the previous part we covered configuration of Nginx as a reverse proxy on Raspberry Pi.
This part will cover packaging the .NET API application and running the application as a background service. Raspberry Pi requires .Net runtime to run .NET applications.
1. Steps to install .Net Runtime
a. Install .NET on the device using the dotnet-install scripts. Run the following command to install .NET:
Bash
curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel STS
b. For path resolution, add a DOTNET_ROOT environment variable and add the .dotnet directory to $PATH with the following commands:
Bash
echo 'export DOTNET_ROOT=$HOME/.dotnet' >> ~/.bashrc
echo 'export PATH=$PATH:$HOME/.dotnet' >> ~/.bashrc
source ~/.bashrc
c. Verify the .NET installation with the following command:
.NET CLI
dotnet --version
2. Application Deployment
For Linux, there is no .exe file. Instead, you will be copying the .NET application binaries (such as .dll files) to the server directory and then use Kestrel/Nginx to serve the app.
a. Publish Your .NET Application
Raspberry Pi has ARM based processors. To make your .NET Web application compliant on an ARM device, run the following command:
bash
dotnet publish --configuration Release --output ./publish --runtime linux-arm64
b. Copy Files to Your Raspberry Pi Server
/var
directory is used to store content and log files by Nginx. Copy the published Files to appropriate directory.
bash
sudo cp -a ~/yourapp/bin/Debug/net5.0/publish/ /var/www/yourapp/
use sudo
before the copy command, standard users don't have write permission to /var
directory. Therefore, you must run the command as a superuser.
To run your application from a published folder, run the following command:
dotnet /var/www/yourapp/yourapp.dll
If you want, you can run tests by using the curl and wget commands.
This application will listen on port 5000 for HTTP requests.
c. Ensure permissions
Ensure that the application folder has the correct permissions for your web server or user to execute the application:
bash
sudo chmod -R 755 /var/www/yourapp
d. Create Service File
For production, you would want to run your application as a service using systemd or another process manager to keep it running in the background. This will restart the services even if it fails due to unknown issues.
Here's an example of how you might create a systemd service file for your .NET application:
Create a file yourapp.service under /etc/systemd/system/ with the below content:
ini
[Unit]
Description=Your .NET Web API
After=network.target
[Service]
WorkingDirectory=/var/www/yourapp
ExecStart=$Home/.dotnet /var/www/yourapp/yourapp.dll
Restart=always
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
WorkingDirectory
- indicates the path of the directory where the application package is available
ExecStart
- indicates the path of the dotnet sdk and the application package (.dll)
After creating this service, enable and start it with:
bash
sudo systemctl enable yourapp.service
sudo systemctl start yourapp.service
using journalctl
gives detailed messages and can be helpful in trouble shooting.
sudo journalctl -fu yourapp.service
Once your application is running, NGINX will forward incoming requests to your .NET Web API application.
Summary
Key points to remember for hosting on Raspberry Pi:
-
Location of Application Files: Since Raspberry Pi is Linux-based, choose a standard location for your application files, such as
/var/www/yourapp
(or any other appropriate directory). - Process Management: For a production environment on Linux, you should always run your .NET application as a service so it will automatically start when the server boots and will be restarted if it crashes. Use systemd, supervisord, or forever (for Node.js apps) to manage the application processes.
- Security: Ensure the appropriate file permissions and user ownership for the application folder. For production applications, run the application as a non-root user, and configure your firewall to allow traffic only on the necessary ports (e.g., 80 and 443 for HTTP and HTTPS).