The recent Release Candidate 1 (RC1) for ASP.NET 5 includes support for Linux and OS X via .NET Core. After trying it out on OS X, I wanted to do some experiments on Linux as well. For that I used Vagrant to automate the creation and provision of the Linux development environments. In this post I describe the steps required for this task, using OS X as the host (the steps on a Windows host will be similar).
Start by ensuring Vagrant and VirtualBox are installed on your host machine.
Then open a shell and do the following commands.
vagrant up may take a while since it will not only download and boot the base virtual machine image, but also provision ASP.NET 5 RC1 and all its dependencies.
git clone https://github.com/pmhsfelix/vagrant-aspnet-rc1.git (or your own fork URL instead) cd vagrant-aspnet-rc1 vagrant up vagrant ssh
After the last command completes you should have a SSH session into a Ubuntu Server with ASP.NET RC1 installed, running on a virtual machine (VM). Port
5000 on the host is mapped into port
5000 on the guest.
vagrant-aspnet-rc1 host folder is mounted into the
/vagrant guest folder, so you can use this to share files between host and guest.
For instance, a ASP.NET project published to
vagrant-aspnet-rc1/published on the host will be visible on the
/vagrant/published guest path.
For any comment or issue that you have, please raise an issue at https://github.com/pmhsfelix/vagrant-aspnet-rc1.
Longer (and perhaps more instructive) version
Afterwards, create a new folder (e.g.
vagrant-aspnet-rc1) to host the Vagrant configuration.
dotnet pedro$ mkdir vagrant-aspnet-rc1 dotnet pedro$ cd vagrant-aspnet-rc1 vagrant-aspnet-rc1 pedro$
Then, initialize the Vagrant configuration using the
vagrant-aspnet-rc1 pedro$ vagrant init ubuntu/trusty64 A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on `vagrantup.com` for more information on using Vagrant. vagrant-aspnet-rc1 pedro$ ls Vagrantfile
The second parameter,
ubuntu/trusty64, is the name of a box available on the Vagrant public catalog, which in this case contains a Ubuntu Server 14.04 LTS.
Notice also how a
Vagrantfile file, containing the Vagrant configuration, was created on the current directory. We will be using this file latter on.
The next step is to start the virtual machine.
vagrant-aspnet-rc1 pedro$ vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==> default: Importing base box 'ubuntu/trusty64'... ==> default: Matching MAC address for NAT networking... ==> default: Checking if box 'ubuntu/trusty64' is up to date... ==> default: Setting the name of the VM: vagrant-aspnet_default_1451428161431_85889 ==> default: Clearing any previously set forwarded ports... ==> default: Fixed port collision for 22 =&gt; 2222. Now on port 2200. ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 22 (guest) =&gt; 2200 (host) (adapter 1) ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2200 default: SSH username: vagrant default: SSH auth method: private key default: default: Vagrant insecure key detected. Vagrant will automatically replace default: this with a newly generated keypair for better security. default: default: Inserting generated public key within guest... default: Removing insecure key from the guest if it's present... default: Key inserted! Disconnecting and reconnecting using new SSH key... ==> default: Machine booted and ready! ==> default: Checking for guest additions in VM... default: The guest additions on this VM do not match the installed version of default: VirtualBox! In most cases this is fine, but in rare cases it can default: prevent things such as shared folders from working properly. If you see default: shared folder errors, please make sure the guest additions within the default: virtual machine match the version of VirtualBox you have installed on default: your host and reload your VM. default: default: Guest Additions Version: 4.3.34 default: VirtualBox Version: 5.0 ==> default: Mounting shared folders... default: /vagrant =&gt; /Users/pedro/code/dotnet/vagrant-aspnet-rc1
As can be seen in the command output, a VM was booted and SSH was configured. So the next step is to open a SSH session into the machine to check if everything is working properly. This is accomplished using the
vagrant-aspnet-rc1 pedro$ vagrant ssh Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.13.0-74-generic x86_64) * Documentation: https://help.ubuntu.com/ System information as of Tue Dec 29 22:29:41 UTC 2015 System load: 0.35 Processes: 80 Usage of /: 3.4% of 39.34GB Users logged in: 0 Memory usage: 25% IP address for eth0: 10.0.2.15 Swap usage: 0% Graph this data and manage this system at: https://landscape.canonical.com/ Get cloud support with Ubuntu Advantage Cloud Guest: http://www.ubuntu.com/business/services/cloud 0 packages can be updated. 0 updates are security updates. vagrant@vagrant-ubuntu-trusty-64:~$ hostname vagrant-ubuntu-trusty-64 vagrant@vagrant-ubuntu-trusty-64:~$ id uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant)
Notice how we end up with a session into a
vagrant-ubuntu-trusty-64 machine, running under the
In addition to setting up SSH, Vagrant also mounted the
vagrant-aspnet-rc1 host folder (the one were the
Vagrantfile was created) into the
/vagrant file on the guest.
vagrant@vagrant-ubuntu-trusty-64:~$ ls /vagrant Vagrantfile
We could now start to install ASP.NET 5 following the procedure outlined at http://docs.asp.net/en/latest/getting-started/installing-on-linux.html. However, that would be the “old way of doing things” and would not provide us with a reproducable development environment.
A better solution is to create a provision script, called
bootstrap.sh, and use it with Vagrant.
The provision script is simply a copy of the procedures at http://docs.asp.net/en/latest/getting-started/installing-on-linux.html, slightly changed to allow unsupervised installation.
#!/usr/bin/env bash # install dnvm pre-requisites sudo apt-get install -y unzip curl # install dnvm curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh &amp;&amp; source ~/.dnx/dnvm/dnvm.sh # install dnx pre-requisites sudo apt-get install -y libunwind8 gettext libssl-dev libcurl4-openssl-dev zlib1g libicu-dev uuid-dev # install dnx via dnvm dnvm upgrade -r coreclr # install libuv from source sudo apt-get install -y make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 &amp;&amp; cd ~/ sudo ldconfig
The next step is to edit the
Vagrantfile so this provision script is run automatically by Vagrant.
We also change the port forwarding rule so that is matches the default 5000 port used by ASP.NET.
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure(2) do |config| config.vm.box = &quot;ubuntu/trusty64&quot; config.vm.provision :shell, path: &quot;bootstrap.sh&quot;, privileged: false config.vm.network &quot;forwarded_port&quot;, guest: 5000, host: 5000 end
To check that everything is properly configured we redo the whole process by destroying the VM and creating it again.
vagrant-aspnet-rc1 pedro$ vagrant destroy default: Are you sure you want to destroy the 'default' VM? [y/N] y ==&gt; default: Forcing shutdown of VM... ==&gt; default: Destroying VM and associated drives... vagrant-aspnet-rc1 pedro$ vagrant up ( ... lots of things that take a while to happen ... )
vagrant ssh and check that
dnx is fully functional.
How about publish with runtime?
Instead of having to previously provision ASP.NET, wouldn’t it be nice to include all the dependencies on the published project so that we could deploy it on a plain vanilla Ubuntu or Debian machine?
Well, one one hand it is possible to configure the publish process to also include the runtime, via the
dnu publish --out ~/code/dotnet/vagrant-ubuntu/published --no-source --runtime dnx-coreclr-linux-x18.104.22.168-rc1-update1
On the other hand, in order to have the Linux DNX runtime available on OS X we just need to explicitly specify the OS on the
dnvm install latest -OS linux -r coreclr
Unfortunately, this approach does not work because the published runtime is not self-sufficient.
For it to work properly it still requires some dependencies to be previously provisioned on the deployed machine.
This can be seen if we try to run the ASP.NET project
vagrant@vagrant-ubuntu-trusty-64:~$ /vagrant/published/approot/web failed to locate libcoreclr with error libunwind-x86_64.so.8: cannot open shared object file: No such file or directory vagrant@vagrant-ubuntu-trusty-64:~$ Connection to 127.0.0.1 closed by remote host. Connection to 127.0.0.1 closed.
Notice how the
libunwind-x86_64.so.8 failed to be opened.
So, for the time being, we need to provision at least the runtime dependencies on the deployed machine.
The runtime itself can be contained in the published project.