Skip to content
Draft
204 changes: 109 additions & 95 deletions Documentation/README.md

Large diffs are not rendered by default.

577 changes: 577 additions & 0 deletions Documentation/deployment/containers.md

Large diffs are not rendered by default.

78 changes: 78 additions & 0 deletions Documentation/deployment/cross-compilation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# How to Deploy an IoT App

This provides information how to prepare a Publish Profile and deploy an application to a development board.

## Using Visual Studio

1. Once you have an application setup in Visual Studio, right-click the project in the Solution Explorer and select Publish...
2. In the Pick a publish target dialog, select Folder, choose a folder to publish your application files and click Create Profile. The example below shows a path of C:\PublishedApps.
3. A default profile, FolderProfile.pubxml, will now be created and added to your project. You can view it in the Solution Explorer under your project > Properties > PublishProfiles folder.
4. It is a good practice to rename your profile to something you can relate with your project. In the Publish Window, click the Actions dropdown and select Rename Profile. A Rename Profile dialog prompts you to rename your profile. Click Save after renaming.
5. You can configure the profile's settings by clicking Configure... in the Publish Window. A Profile Settings dialog prompt includes a few options. **Notes**:
* Prior to Visual Studio 2019, the Target Runtime doesn't offer a selection for Linux ARM or Windows ARM. When using an older version of Visual Studio, you will need to manually open the profile's XML and change the RuntimeIdentifier element to **linux-arm** or **win-arm** shown below:

```csharp
<RuntimeIdentifier>linux-arm</RuntimeIdentifier>
or..
<RuntimeIdentifier>win-arm</RuntimeIdentifier>
or both..
<RuntimeIdentifiers>linux-arm;win-arm</RuntimeIdentifiers>
```

* Deployment Mode Options:
* **Framework Dependent** - App relies on the presence of a shared system-wide version of .NET Core on the target system. This will create a smaller size package.
* **Self-contained** - .NET Core and required libraries will be bundled with your application creating a larger size package. IoT devices are usually constrained by memory resources. There is a useful NuGet package available that helps trim unused files. Reference [Microsoft.Packaging.Tools.Trimming](https://www.nuget.org/packages/Microsoft.Packaging.Tools.Trimming/) for more information.
* While there are more options available that can be modified, this only shows the basics. It is recommended to read more in the provided **References** section below.
6. You can view the contents by double-clicking the profile. The content should look similar to the XML below after your modifications.
* Example:

```xml
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<TargetFramework>netcoreapp3.1</TargetFramework>
<PublishDir>C:\PublishedApps</PublishDir>
<RuntimeIdentifier>linux-arm</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<_IsPortable>false</_IsPortable>
</PropertyGroup>
</Project>
```

7. You can now publish your application by clicking Publish in the Publish Window. All folders/files should now be packaged in the specified publish folder.
8. Your application is now ready for deployment to the target device.

## Using .NET Core CLI

1. Once you have an application setup, navigate to the directory where the project is located and run the `dotnet publish` command. Below shows a few common options and example.
* -c defines the build configuration (Debug or Release).
* -o specifies the output path where application will be packaged.
* -r publishes the application for given runtime (e.g. linux-arm, win-arm, etc.) being targeted.

```shell
dotnet publish -c Release -o C:\DeviceApiTester -r linux-arm
```

2. Your application is now ready for deployment to the target device.

## How to Copy an IoT App to Target Device

The application can be deployed to a target device once the Publish Profile and related files have been packaged. There are various tools for transferring files depending on the platform being used. Below are a few popular tools available.

* [PuTTy](https://www.putty.org/)
* PSCP (provided with PuTTy install)
* [FileZilla](https://filezilla-project.org/)

## References

* [Have Your Pi and Eat It Too: .NET Core 2.1 on Raspberry Pi](https://channel9.msdn.com/Events/dotnetConf/2018/S314)
* [Visual Studio publish profiles for ASP.NET Core app deployment](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/visual-studio-publish-profiles?view=aspnetcore-2.2)
* [Deploy an app to a local folder using Visual Studio](https://docs.microsoft.com/en-us/visualstudio/deployment/quickstart-deploy-to-local-folder?view=vs-2017)
* [Deploy .NET Core apps with Visual Studio](https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-vs?tabs=vs156)
* [How to: Edit Deployment Settings in Publish Profile (.pubxml) Files and the .wpp.targets File in Visual Studio Web Projects](https://go.microsoft.com/fwlink/?LinkID=208121)
* [.NET Core application deployment](https://docs.microsoft.com/en-us/dotnet/core/deploying/)
* [dotnet publish](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore21)
* [.NET Core RID Catalog](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog)
152 changes: 152 additions & 0 deletions Documentation/deployment/systemd-services.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# How to start app automatically on boot using systemd

## Create your app

For the purpose of this document let's assume you have deployed your app under:

`
/home/pi/myiotappfolder/myiotapp
`

The app name is `<myiotapp>` in this documentation you would replace the entire string including the carrots in your files.

To run this you will need to make your app run as root please read the section on [Security Considerations](#security-considerations)

Make sure to make your app ```<myiotapp>``` is executable by using the command:

```shell
# Requires root permissions
chmod +x <myiotapp>
```

## Create systemd.service unit

For this example a script titled `<myiotapp>.service` will be used. The folder that this application is ran from is `/home/pi/myiotappfolder` Please replace accordingly with your app name or the location you decide to save your script. Remember to add the `.service` as the file extension

Here is an example systemd.service file that you can use as a template. Make sure to use a Unix end of line when creating the systemmd.service file.

```shell
[Unit]
#The # is a comment line
#Documentation https://www.freedesktop.org/software/systemd/man/systemd.service.html

#Place short description here
Description=My IOT Device Service

#This will not start execution of this file until the network connection is made
#It can be replaced with other parameters of your choosing
After=network.target

[Service]
#Default: Startup type
Type=Simple

#Edit this with your file name. In this example the app executable is in the /home/pi/myiotappfolder
#The file we are running and made executable is <myiotapp>
#ExecStart runs this executable script
ExecStart=/home/pi/myiotappfolder/myiotapp

#Optional: Saves the output and error log of the terminal to a .log file in a directory of your choosing.
StandardOutput=file:/home/pi/myiotapp.log
StandardError=file:/home/pi/myiotapp-error.log

#Optional: To cleanly end the file on stop use this command. This sends a terminal interrupt command on the executable script
KillSignal=SIGINT

#Automatically restart on kill
Restart=always

[Install]
WantedBy=multi-user.target

```

The systemmd service file which we will call `<myiotapp>.service` must be saved to `/etc/systemd/system` to be ran on boot.

Note that you must have admin priviliges to save a file to the system etc folder. You can use the following to copy the service in a terminal to this folder:

```shell
# Requires root permissions
cp <myiotapp>.service /etc/systemd/system
```

Once in the folder make the file executable by going to the directory and then use the chmod command:

```shell
# Requires root permissions
chmod +x <myiotapp>.service
```

### Notes

Please use care and refer to the manual when using this code
You may also look at the other scripts under /etc/systemd/system for reference.

## Test your service

This will start the service but will not run it on boot.

```shell
# Requires root permissions
systemctl start <myiotapp>.service
```

Now you can look at the log file you created to see the output of the terminal. `/home/pi/myiotapp.log`

Or you can check the status of the service by using in a terminal:

```shell
# Requires root permissions
systemctl is-active status <myiotapp>.service
```

To stop the service run:

```shell
# Requires root permissions
systemctl stop <myiotapp>.service
```

## To make your service automatically run on boot

```shell
# Requires root permissions
systemctl daemon-reload
systemctl enable myscript.service
```

## To disable your service

Run this in terminal to disable the program on boot:

```shell
# Requires root permissions
systemctl daemon-reload
systemctl disable myscript.service
```

## Security considerations

Your app will be running with root permissions.

Please ensure only root can write to the files related with your app.
That includes any binary dependencies or any other scripts which you app may run.

Not doing so may add a risk of elevation of privileges to your device.

```shell
# The commands below should be run as root (i.e. sudo)

# Owner of every dependency and app should be root
chown -R root:root /your/app/directory/

# permissions for dependencies (files) should be rw for owner, read or none for anyone else
chmod -R 644 /your/app/directory/*

# your app additionally will need executable permissions which you may have accidentally removed with previous command
chmod 755 /your/app/directory/yourapp

# permissions for directories/subdirectories
chmod 755 /your/app/directory
chmod 755 /your/app/directory/subdirectory
```
Loading