-
-
Notifications
You must be signed in to change notification settings - Fork 565
Bundling .NET Core apps
- Introduction
- Bundling an AppImage
- Prerequisites
- Bundling
- TODO
- Bundling within a Docker container
.NET Core is a new .NET platform that's open source, modular, and runs on various operating systems like:
- Windows 7, 8, 10, both x86 and x64
- Windows 10 on ARM
- Ubuntu 14.04, 16.04, 16.10
- Other Linux distributions: Red Hat Enterprise Linux 7 Server, Linux Mint 17, 18, Debian 8, Fedora 23, 24, CentOS 7.1, openSUSE 13.2, 42.1
- macOS 10.11 or higher
- Docker (microsoft/dotnet)
.NET Core apps can be distributed as framework-dependent deployments (FDD) and self-contained deployments (SCD). Read more about that here.
While an SCD already is self-contained, which means the .NET Core framework doesn't need to be installed on the system where the app is supposed to run, an AppImage still has advantages:
- It's just one file. The SCD on the other hand contains lots of files in one directory and the user either has to create a symlink in
/usr/local/bin
for example, or create an alias or something alike. - There's desktop integration: MIME type registration, inclusion in the start menu
- Delta updates with zsync
- Standard compliant package meta info with AppStream
And as with .NET Core SCDs, there's no need to install a runtime, which is an advantage in comparison to Snap or Flatpak packages.
Prior to bundling, you created your .NET Core app and checked that it worked. Like:
dotnet new console -o hwapp
cd hwapp
dotnet restore
dotnet run
Hello World!
Add some runtime identifiers (RIDs) to the hwapp.csproj
, like <RuntimeIdentifiers>win10-x64;ubuntu.16.04-x64;osx.10.12-x64</RuntimeIdentifiers>
. For more RIDs, see the catalog.
Create an SCD for ubuntu.16.04-x64
:
# After adding RIDs to the csproj, you need to restore some packages again
dotnet restore -r ubuntu.16.04-x64
dotnet publish -c Release -r ubuntu.16.04-x64
Now you want to bundle the ubuntu.16.04-x64
release files. They're located in bin/Release/netcoreapp1.1/ubuntu.16.04-x64/publish/
and contain 123 files (this number might be different on your system, and certainly when your app is more than a Hello World
-app).
-
Create a directory
AppDir
-
Create some files inside that directory:
- Create
usr/bin/
and copy all those 123 files from the above mentioned.../publish
directory into it:
mkdir -p AppDir/usr/bin cp bin/Release/netcoreapp1.1/ubuntu.16.04-x64/publish/* AppDir/usr/bin/
- Create a file
AppDir/AppRun
with the contents:
#!/bin/sh HERE="$(dirname "$(readlink -f "${0}")")" export PATH="${HERE}"/usr/bin/:"${PATH}" EXEC=$(grep -e '^Exec=.*' "${HERE}"/*.desktop | head -n 1 | cut -d "=" -f 2 | cut -d " " -f 1) exec "${EXEC}" $@
- Make it executable:
chmod 755 ./AppDir/AppRun
- Create a file
AppDir/hwapp.desktop
with the contents:
# Desktop Entry Specification: https://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html [Desktop Entry] Type=Application Name=hwapp Comment=Self-contained .NET Core console application that prints Hello World Icon=hwapp Exec=hwapp Path=~ Terminal=true Categories=Development;
- Create an icon for your app,
AppDir/hwapp.png
orAppDir/hwapp.svg
(48x48 pixels)
- Create
-
You should now have the following file structure:
AppDir
|-- AppRun
|-- hwapp.desktop
|-- hwapp.png
|-- usr
|--bin
|-- ...snip (all SCD files)
bin
hwapp.csproj
obj
Program.cs
- Download the AppImage creation tool and make it executable:
wget "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod a+x appimagetool-x86_64.AppImage
- Create the AppImage:
./appimagetool-x86_64.AppImage ./AppDir
ls
AppDir appimagetool-x86_64.AppImage bin hwapp.csproj hwapp-x86_64.AppImage obj Program.cs
- Test the AppImage:
./hwapp-x86_64.AppImage
Hello World!
The previous steps were just sample steps to your first .NET Core AppImage. For a production setup, you would also:
- Have a proper directory structure for having all AppImage related files in one directory (also the downloaded appimagetool and the created AppImage of your app)
- Have a build script that does all the above mentioned steps for you
- Have your AppImage deployed somewhere, like GitHub Releases or Bintray
- Look into AppStream meta data
- Look into zsync delta updates
- Consider using an AppImage recipe build script
You should also read AppImage/AppImageKit/wiki/Creating-AppImages.
When building a .NET Core app with Docker, you're probably using Microsoft's official containers. These containers currently don't contain fuse and libglib2.0-0.
Regarding fuse: See AppImage/AppImageKit/wiki/FUSE
In short, don't use the appimagetool-x86_64.AppImage
directly, but first extract it with appimagetool-x86_64.AppImage --appimage-extract
and then execute ./squashfs-root/AppRun
in place of the AppImage.
Regarding libglib2.0-0: You need to install this in your container. For example when having a buildscript that you execute in the Container, you can use something like:
docker run --rm \
...snip (mount source code directory etc)
microsoft/dotnet:1.1-sdk \
bash -c "apt update && apt install -y libglib2.0-0 && build.sh"