.Net and Azure Development Setup on Unbuntu 19.04 Disco Dingo

a month ago

Disco Dingo is CoolLet's start with a note I spent some time trying to do something which didn't work and I want to point out first. I could not get VS Code, installed using snap, to work with the .NET Core SDK, also installed with snap, to work together. This

Disco Dingo is Cool

Let's start with a note
I spent some time trying to do something which didn't work and I want to point out first. I could not get VS Code, installed using snap, to work with the .NET Core SDK, also installed with snap, to work together. This always led to the following error when opening a C# project in VS Code:

Failed to swan 'dotnet --info'

I first saw this in 19.04. I spent too much time trying to debug it. The solution will be described below. But, it also had the same issue on 18.04.2 LTS. So, it appears to be snap related and not 19.04 related.

The process / goal

I've historically been a .Net and Microsoft appliation developer.  I dabble in a lot of environments, and my focus the last few years has been with .Net Core development on Linux.  Ubuntu 19.04, Disco Dingo, just came out last Friday so I decided to move to the new version and give it a try.  This documents my build for .Net / Azure development on Ubuntu 19.04, code name "Disco Dingo".  

This has been a great experience so far.  It's had a few hiccups, but the OS is smooth and the tools are working great.  So let's get going...

General Tools:


We start with git.

sudo apt-get install git
git config --global user.email "mike@heydt.org"
git config --global user.name "Michael Heydt"


Docker was a little bit of a challenge on 19.04.  I went through a few steps, but ultimately installing using apt and docker.io seemed to work.

sudo apt-get install docker.io

However, one time I did this (I've been through this process a few times), docker would not start.  The dockerd process was not available in the lists of tasks (using ps -A), so I tried to start it and got the following error:

$ sudo dockerd
INFO[2019-04-22T15:11:45.588681004-06:00] systemd-resolved is running, so using resolvconf: /run/systemd/resolve/resolv.conf 
INFO[2019-04-22T15:11:45.589844737-06:00] parsed scheme: "unix"                         module=grpc
INFO[2019-04-22T15:11:45.589876778-06:00] scheme "unix" not registered, fallback to default scheme  module=grpc
INFO[2019-04-22T15:11:45.589966069-06:00] parsed scheme: "unix"                         module=grpc
INFO[2019-04-22T15:11:45.589980106-06:00] scheme "unix" not registered, fallback to default scheme  module=grpc
INFO[2019-04-22T15:11:45.590083954-06:00] ccResolverWrapper: sending new addresses to cc: [{unix:///run/containerd/containerd.sock 0  }]  module=grpc
INFO[2019-04-22T15:11:45.590119753-06:00] ccResolverWrapper: sending new addresses to cc: [{unix:///run/containerd/containerd.sock 0  }]  module=grpc
INFO[2019-04-22T15:11:45.590193804-06:00] ClientConn switching balancer to "pick_first"  module=grpc
INFO[2019-04-22T15:11:45.590167624-06:00] ClientConn switching balancer to "pick_first"  module=grpc
INFO[2019-04-22T15:11:45.590330575-06:00] pickfirstBalancer: HandleSubConnStateChange: 0xc42020e1f0, CONNECTING  module=grpc
INFO[2019-04-22T15:11:45.590356214-06:00] pickfirstBalancer: HandleSubConnStateChange: 0xc42003b7f0, CONNECTING  module=grpc
INFO[2019-04-22T15:11:45.590355764-06:00] blockingPicker: the picked transport is not ready, loop back to repick  module=grpc
INFO[2019-04-22T15:11:45.590728916-06:00] pickfirstBalancer: HandleSubConnStateChange: 0xc42020e1f0, READY  module=grpc
INFO[2019-04-22T15:11:45.590754105-06:00] pickfirstBalancer: HandleSubConnStateChange: 0xc42003b7f0, READY  module=grpc
INFO[2019-04-22T15:11:45.591944369-06:00] [graphdriver] using prior storage driver: overlay2 
INFO[2019-04-22T15:11:45.610047373-06:00] Graph migration to content-addressability took 0.00 seconds 
WARN[2019-04-22T15:11:45.610427419-06:00] Your kernel does not support swap memory limit 
WARN[2019-04-22T15:11:45.610471834-06:00] Your kernel does not support cgroup rt period 
WARN[2019-04-22T15:11:45.610484748-06:00] Your kernel does not support cgroup rt runtime 
WARN[2019-04-22T15:11:45.610497924-06:00] Your kernel does not support cgroup blkio weight 
WARN[2019-04-22T15:11:45.610508333-06:00] Your kernel does not support cgroup blkio weight_device 
INFO[2019-04-22T15:11:45.611059306-06:00] Loading containers: start.                   
INFO[2019-04-22T15:11:45.675143646-06:00] stopping event stream following graceful shutdown  error="" module=libcontainerd namespace=moby
Error starting daemon: Error initializing network controller: list bridge addresses failed: no available network

This is an error I've seen before and is fixed by creating a new network bridge with the following commands:

$ sudo ip link add name docker0 type bridge
$ sudo ip addr add dev docker0

A reboot and docker was up and running.

Something else I like to do configure docker so I don't have to type sudo all the time.  This is done by creating a group named docker, which docker puts its socket in, and then add myself to that group:

sudo groupadd docker
sudo usermod -aG docker $USER

Core stuff

This is the meat of most things used: .Net Core, Azure CLI, and Powershell.

.Net Core SDK

Really easy to install using a snap:

$ sudo snap install dotnet-sdk --classic

However, the snap does not set up an alias for the dotnet command.  So we can set that with the following:

$ sudo snap alias dotnet-sdk.dotnet dotnet

This is something that I have historically lost hours figuring out, so hopefully this helps out a bit.

Azure CLI

Now available as a snap.  It's a candidate release, but great it's getting to snap!

$ sudo snap install azure-cli --classic --candidate

However, this at the time or writing did not make an az alias (the command would be azure-cli).  So, this sets up an alias of azure-cli of az.

$ sudo snap alias azure-cli az

I suspect from reading on the snap store discussion forums that this alias will be created by default in the future.


These days, installs easily with a snap.

$ sudo snap install powershell --classic

Azure PowerShell Module

From within PS, run the following command:

Install-Module -Name Az -AllowClobber

Now I have a lot of legacy powershell code that uses AzureRM, which requires the enabling of naming aliases for AzureRM commands to map into Az commands.

ENable-AzureRmAlias -Scope CurrentUser

But like many things, this doesn't work right away and gives this error:

Enable-AzureRmAlias -Scope CurrentUser
Enable-AzureRmAlias : Could not find a part of the path '/home/mike/.config/powershell/profile.ps1'.
At line:1 char:1    ]
+ Enable-AzureRmAlias -Scope CurrentUser     
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
+ CategoryInfo          : CloseError: (:) [Enable-AzureRmAlias], DirectoryNotFoundException                                     
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Profile.AzureRmAlias.EnableAzureRmAlias 

Now I'm not exactly sure why this happens. I suspect, and I can be completely wrong, that is is because PS is running as a snap.  There is no ~/.config/powershell directory yet alone the subdirectories and profiles.  So let's create it.

mkdir ~/.config/powershell

And now running the command again succeeds.  This writes a profile.ps1 file into the directory that contains the following content:

#Begin Azure PowerShell alias import
Import-Module Az.Accounts -ErrorAction SilentlyContinue -ErrorVariable importError
if ($importerror.Count -eq 0) { 
    Enable-AzureRmAlias -Module Az.Accounts, Az.Aks, Az.AnalysisServices, Az.ApiManagement, Az.ApplicationInsights, Az.Automation, Az.Backup, Az.Batch, Az.Billing, Az.Cdn, Az.CognitiveServices, Az.Compute, Az.Compute.ManagedService, Az.ContainerInstance, Az.ContainerRegistry, Az.DataFactory, Az.DataLakeAnalytics, Az.DataLakeStore, Az.DataMigration, Az.DeviceProvisioningServices, Az.DevSpaces, Az.Dns, Az.EventGrid, Az.EventHub, Az.FrontDoor, Az.HDInsight, Az.IotCentral, Az.IotHub, Az.KeyVault, Az.LogicApp, Az.MachineLearning, Az.ManagedServiceIdentity, Az.ManagementPartner, Az.Maps, Az.MarketplaceOrdering, Az.Media, Az.Monitor, Az.Network, Az.NotificationHubs, Az.OperationalInsights, Az.PolicyInsights, Az.PowerBIEmbedded, Az.RecoveryServices, Az.RedisCache, Az.Relay, Az.Reservations, Az.ResourceGraph, Az.Resources, Az.Scheduler, Az.Search, Az.Security, Az.ServiceBus, Az.ServiceFabric, Az.SignalR, Az.Sql, Az.Storage, Az.StorageSync, Az.StreamAnalytics, Az.Subscription, Az.TrafficManager, Az.Websites -ErrorAction SilentlyContinue; 
#End Azure PowerShell alias import

And every time you start powershell these aliases will be created.

Visual Studio Code

The core application

The must have IDE for anything on Linux.  Actually amazing how well it works. This can be installed easily with a snap:

$ sudo snap install code --classic


Now I like to install quite a few extensions.  Let's walk through a number of these that I commonly install. I start with the material theme (have to have my material theme):

$ code --install-extension PKief.material-icon-theme
$ code --install-extension Equinusocio.vsc-material-theme

Of course C#:

$ code --install-extension ms-vscode.csharp


$ code --install-extension peterjausovec.vscode-docker


$ code --install-extension ms-python.python

Various Azure tools:

$ code --install-extension ms-vscode.vscode-node-azure-pack

Azure Machine Learning:

$ code --install-extension ms-toolsai.vscode-ai

IoT Edge:

$ code --install-extension vsciot-vscode.azure-iot-edge	

HTML Preview:

$ code --install-extension tht13.html-preview-vscode


$ code --install-extension jmrog.vscode-nuget-package-manager

Useful Azure Tools

Azure Storage Explorer

Hey somebody, make this a snap!  For now, you can use the following to automate:

$ cd ~/Downloads
$ wget https://download.microsoft.com/download/A/E/3/AE32C485-B62B-4437-92F7-8B6B2C48CB40/StorageExplorer-linux-x64.tar.gz
$ sudo mkdir -p /opt/StorageExplorer-linux-x64 && sudo tar -C $_ -zxvf StorageExplorer-linux-x64.tar.gz && \
sudo ln -s /opt/StorageExplorer-linux-x64/StorageExplorer /usr/bin/StorageExplorer

Note that at the time of writing, this installed version 1.6.4, and it immediately told me 1.7 was available.  The link I have there is direct from the download on the Storage Explorer page, which didn't update to the new version.  However, I don't know the download URL of 1.7 as it's auto downloaded by the app.  Go figure...

Now I got an error when attempting to start it from the command line:

$ StorageExplorer
StorageExplorer: error while loading shared libraries: libgconf-2.so.4: cannot open shared object file: No such file or directory

The following will fix this:

sudo apt-get install -y libgconf-2-4

And then I got an error about the key ring.  This is particularly nasty as Ignore leaves it hanging.

So to fix this one up, run the following command:

sudo apt-get install -y libgnome-keyring0

To create a desktop resource so this can be started from say the Gnome start menu:

mkdir -p ~/.local/share/applications && \
cat > ~/.local/share/applications/StorageExplorer.desktop <

And if that wasn't enough, there's an issue with authentication with Azure that has a patch if you are using .Net Core > 2.0 (in the case of installing at the time of writing it is 2.2), you need to perform the patch at this link: [Patching Storage Explorer for newer versions of .NET Core](https://docs.microsoft.com/en-us/azure/storage/common/storage-explorer-troubleshooting?tabs=1804#patching-storage-explorer-for-newer-versions-of-net-core)

Azure Data Studio

Azure data studio can be installed with the following:

wget -O azuredatastudio.deb https://go.microsoft.com/fwlink/?linkid=2087415
sudo dpkg -i azuredatastudio.deb 

Redis Desktop Manager

Useful if you work with Azure Redis Cache.  Install with:

sudo snap install redis-desktop-manager

One note though, and just an issue with my multiple monitor system: the window opens across all monitors and is not usable.  Hence, I generally used this from within a VM.

Azurite: Azure Storage Emulator

Azurite is undergoing some changes / recoding, but it's still worthwhile for emulating a lot of blob, table and queue storage.  I find it best to install and run with docker:

docker pull arafato/azurite
docker run -e executable=blob -d -t -p 10000:10000 -v /path/to/folder:/opt/azurite/folder arafato/azurite

This is pretty cool.  If you installed Azure Storage Explorer, you can easily access these services.

Azure Functions Core Tools

Couldn't get them to install with the default instructions and using apt-get. Hence, went the manual path.

wget -q https://github.com/Azure/azure-functions-core-tools/releases/download/2.6.1071/Azure.Functions.Cli.linux-x64.2.6.1071.zip
unzip -d azure-functions-cli Azure.Functions.Cli.linux-x64.*.zip
sudo mv azure-functions-cli /opt
chmod +x /opt/azure-functions-cli/func

And then fire it up: