For a current project I am looking into running a dotnet core web application in Ubuntu Core this does require some extra work compared with running in docker or on bare metal. To illustrate the project I will use a simple dotnet webapi and a fresh install of Ubuntu 17.10 the snap will be deployed and used in the same operating system. In an effort to ensure consistent build we will be using an lxc container for our builds. This makes the process less dependend on operating system, the guide should be usable with only minor adjustments on other linux distros.
Requirements
It is possible to do the entire development process in a continer, however for this purpose i prefer to develop on my active OS and only deploy to a snap. That means that we will need to install dotnet core on our system. The process for this varies slightly depending on your distribution and I will limit this guide to Ubuntu. If you are using another distro Microsoft have documentation on how to install on all supported distributions.
Dotnet Core
The following commands should install dotnet core sdk on a system running Ubuntu 17.04 or 17.10 if you are running an alternative version the Microsoft documentation have repository links for other versions.
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-zesty-prod zesty main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apt-get update
sudo apt-get install -y dotnet-sdk-2.0.0
LXC containers
To have a clean build environment we need to install and prepare an lxc container. The following commands should install lxc and create a container with dotnet Core sdk and snapcraft tools.
sudo apt-get install -y lxc
sudo lxc launch ubuntu:16.04 snapcraft -c security.privileged=true
sudo lxc config device add snapcraft homedir disk source=/home/$USER path=/home/ubuntu
sleep 5 # wait for container to initilize
sudo lxc exec snapcraft -- apt update
sudo lxc exec snapcraft -- apt install -y snapcraft curl
sudo lxc exec snapcraft -- sh -c 'curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /home/ubuntu/microsoft.gpg'
sudo lxc exec snapcraft -- sudo mv /home/ubuntu/microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
sudo lxc exec snapcraft -- sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo lxc exec snapcraft -- apt update
sudo lxc exec snapcraft -- apt install -y dotnet-sdk-2.1.3
The commands in the rest of this project will assume that you have Visual Studio Code
installed on your system. If you prefer another editor you can replace all calls to code
with your editor of choice.
Project definition and build config
As previusly mentioned we will create a basic webapi and use that as an example for our snap.
The following commands will initialise a basic webapi in the folder dotnetSnap/src it will also create a Makefile and open that in Visual Studio Code.
mkdir -p dotnetSnap/src
cd dotnetSnap/src
dotnet new webapi
touch Makefile
code Makefile
Since snapcraft's make plugin calls make all
we need to ensure that make all
runs our build step.
In this case we want our dotnet project to be published as a self-contained application targeting x64 Ubuntu.
After snapcraft runs make all
it will run make install
which copies the binaries to a folder under bin in the snap.
all: build
build:
@dotnet publish --self-contained -o bin/publish \
-c Release --runtime ubuntu.16.04-x64
install:
@mkdir -p $(DESTDIR)/bin
@cp -r bin/publish $(DESTDIR)/bin/
clean:
@rm -rf bin
With our dotnet project ready for deployment we will shift our focus towards Snapcraft. The setup required here is fairly limited and the following commands should create a new snap project in your dotnetSnap folder.
cd ..
snapcraft init
code snap/snapcraft.yaml
The snapcraft defintion needs some minor editing to make it usable for our purpose.
Mainly we need to add an app that runs the application which have the default name of src
we also
need to define a part which include our build step.
We are using the make plugin which calls:
make all
make install
This will compile and publish our project to the snap's binary folder. We also add libunwind8 and libicu55 which are required for the dotnet application to function properly.
Our snapcraft.yaml will look like this:
name: Dotnet_snap # you probably want to 'snapcraft register <name>'
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: A simple example snap for dotnet in snaps
description: A simple example snap for dotnet in snaps
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
apps:
testapi:
command: bin/publish/src
parts:
testapi:
plugin: make
source: src/
stage-packages:
- libunwind8
- libicu55
Building installing and running
When we have configured our application we use the following command to build the project.
sudo lxc exec snapcraft -- sh -c "cd /home/ubuntu/dotnetSnap; snapcraft"
This will create Dotnet_snap_0.1_amd64.snap which can be installed on your system using:
sudo snap install Dotnet_snap_0.1_amd64.snap --devmode
We should now be able to run our api using
sudo Dotnet_snap.testapi
Hopefully this guide have provided some help in running your dotnet core applications in a snap, the code from my project is available on github.