Setting up a Shiny Development Environment within Linux on Windows 10

While I was getting Ruby on Rails to work nicely under Ubuntu on Windows 10 I took the opportunity to set up my *nix bash environment, which was largely using defaults. Yes, I know I can use zsh or fish or other shells. Yes, I know I can use emacs and screen, but I am using Vim and tmux. Fight me. Anyway, once my post was done, I starting messing around with open source .NET Core on Linux (it runs on Windows, Mac, and Linux, but here I’m running on Linux on Windows. #Inception) and tweeted a pic of my desktop.

By the way, I feel totally vindicated by all the interest in “text mode” given my 2004 blog post “Windows is completely missing the TextMode boat.” ;)’

Also, for those of you who are DEEPLY NOT INTERESTED in the command line, that’s cool. You can stop reading now. Totally OK. I also use Visual Studio AND Visual Studio Code. Sometimes I click and mouse and sometimes I tap and type. There is room for us all.

WHAT IS ALL THIS LINUX ON WINDOWS STUFF? Here’s a FAQ on the Bash/Windows Subsystem for Linux/Ubuntu on Windows/Snowball in Hell and some detailed Release Notes. Yes, it’s real, and it’s spectacular. Can’t read that much text? Here’s a video I did on Ubuntu on Windows 10.

A number of people asked me how they could set up their WSL (Windows Subsystem for Linux) installs to be something like this, so here’s what I did. Note that will I’ve been using *nix on and off for 20+ years, I am by no means an expert. I am, and have been, Permanently Intermediate in my skills. I do not dream in RegEx, and I am offended that others can bust out an awk script without googling.

C9RT5_bUwAALJ-H

So there’s a few things going on in this screenshot.

  • Running .NET Core on Linux (on Windows 10)
  • Cool VIM theme with >256 colors
  • Norton Midnight Commander in the corner (thanks Miguel)
  • Desqview-esque tmux splitter (with mouse support)
  • Some hotkey remapping, git prompt, completion
  • Ubuntu Mono font
  • Nice directory colors (DIRCOLORS/LS_COLORS)

Let’s break them down one at a time. And, again, your mileage may vary, no warranty express or implied, any of this may destroy your world, you read this on a blog. Linux is infinitely configurable and the only constant is that my configuration rocks and yours sucks. Until I see something in yours that I can steal.

Running .NET Core on Linux (on Windows 10)

Since Linux on Windows 10 is (today) Ubuntu, you can install .NET Core within it just like any Linux. Here’s the Ubuntu instructions for .NET Core’s SDK. You may have Ubuntu 14.04 or 16.04 (you can upgrade your Linux on Windows if you like). Make sure you know what you’re running by doing a:

~ $ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.2 LTS
Release: 16.04
Codename: xenial
~ $

If you’re not on 16.04 you can easily remove and reinstall the whole subsystem with these commands at cmd.exe (note the /full is serious and torches the Linux filesystem):

> lxrun /uninstall /full
> lxrun /install

Or if you want you can run this within bash (will take longer but maintain settings):

sudo do-release-upgrade

Know what Ubuntu your Windows 10 has when you install .NET Core within it. The other thing to remember is that now you have two .NET Cores, one Windows and one Ubuntu, on the same (kinda) machine. Since the file systems are separated it’s not a big deal. I do my development work within Ubuntu on /mnt/d/github (which is a Windows drive). It’s OK for the Linux subsystem to edit files in Linux or Windows, but don’t “reach into” the Linux file system from Windows.

Cool Vim theme with >256 colors

That Vim theme is gruvbox and I installed it like this. Thanks to Rich Turner for turning me on to this theme.

$ cd ~/
$ mkdir .vim
$ cd .vim
$ mkdir colors
$ cd colors
$ curl -O https://raw.githubusercontent.com/morhetz/gruvbox/master/colors/gruvbox.vim
$ cd ~/
$ vim .vimrc

Paste the following (hit ‘i’ for insert and then right click/paste)

set number
syntax enable
set background=dark
colorscheme gruvbox
set mouse=a

if &term =~ '256color'
" disable Background Color Erase (BCE) so that color schemes
" render properly when inside 256-color tmux and GNU screen.
" see also http://snk.tuxfamily.org/log/vim-256color-bce.html
set t_ut=
endif

Then save and exit with Esc, :wq (write and quit). There’s a ton of themes out there, so try some for yourself!

Norton Midnight Commander in the corner (thanks Miguel)

Midnight Commander is a wonderful Norton Commander clone that Miguel de Icaza started, that’s licensed as part of GNU. I installed it via apt, as I would any Ubuntu software.

$ sudo apt-get install mc

There’s mouse support within the Windows conhost (console host) that bash runs within, so you’ll even get mouse support within Midnight Commander!

Midnight Commander

Great stuff.

Desqview-esque tmux splitter (with mouse support)

Tmux is a terminal multiplexer. It’s a text-mode windowing environment within which you can run multiple programs. Even better, you can “detach” from a running session and reattached from elsewhere. Because of this, folks love using tmux on servers where they can ssh in, set up an environment, detach, and reattach from elsewhere.

NOTE: The Windows Subsystem for Linux shuts down all background processes when the last console exits. So you can detach and attach tmux sessions happily, but just make sure you don’t close every console on your machine.

Here’s a nice animated gif of me moving the splitter on tmux on Windows. YES I KNOW YOU CAN USE THE KEYBOARD BUT THIS GIF IS COOL.

Some hotkey remapping, git prompt, completion

I am still learning tmux but here’s my .tmux.conf. I’ve made a few common changes to make the hotkey creation of windows easier.

#remap prefix from 'C-b' to 'C-a'
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix

# split panes using | and -
bind | split-window -h
bind _ split-window -v
unbind '"'
unbind %
bind k confirm kill-window
bind K confirm kill-server
bind < resize-pane -L 1
bind > resize-pane -R 1
bind - resize-pane -D 1
bind + resize-pane -U 1
bind r source-file ~/.tmux.conf

# switch panes using Alt-arrow without prefix
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D

# Enable mouse control (clickable windows, panes, resizable panes)
set -g mouse on
set -g default-terminal "screen-256color"

I’m using the default Ubuntu .bashrc that includes a check for dircolors (more on this below) but I added this for git-completion.sh and a git prompt, as well as these two alias. I like being able to type “desktop” to jump to my Windows Desktop. And the -x on Midnight Commander helps the mouse support.

alias desktop="cd /mnt/c/Users/scott/Desktop"
alias mc="mc -x"
export CLICOLOR=1
source ~/.git-completion.sh
PS1='\[\033[37m\]\W\[\033[0m\]$(__git_ps1 " (\[\033[35m\]%s\[\033[0m\])") \$ '
GIT_PS1_SHOWDIRTYSTATE=1
GIT_PS1_SHOWSTASHSTATE=1
GIT_PS1_SHOWUNTRACKEDFILES=1
GIT_PS1_SHOWUPSTREAM="auto"

Git Completion can be installed with:

sudo apt-get install git bash-completion

Ubuntu Mono font

I really like the Ubuntu Mono font, and I like the way it looks when running Ubuntu under Windows. You can download the Ubuntu Font Family free.

Ubuntu Mono

Nice directory colors (DIRCOLORS/LS_COLORS)’

If you have a black command prompt background, then default colors for directories will be dark blue on black, which sucks. Fortunately you can get .dircolors files from all over the wep, or set the LS_COLORS (make sure to search for LS_COLORS for Linux, not the other, different LSCOLORS on Mac) environment variable.

I ended up with “dircolors-solarized” from here, downloaded it with wget or curl and put it in ~. Then confirm this is in your .bashrc (it likely is already)

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'

alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi

Make a big difference for me, and as I mention, it’s totally, gloriously, maddeningly configurable.

Nice dircolors

Leave YOUR Linux on Windows tips in the comments!


Sponsor: Did you know VSTS can integrate closely with Octopus Deploy? Watch Damian Brady and Brian A. Randell as they show you how to automate deployments from VSTS to Octopus Deploy, and demo the new VSTS Octopus Deploy dashboard widget. Watch now


© 2017 Scott Hanselman. All rights reserved.
     

While I was getting Ruby on Rails to work nicely under Ubuntu on Windows 10 I took the opportunity to set up my *nix bash environment, which was largely using defaults. Yes, I know I can use zsh or fish or other shells. Yes, I know I can use emacs and screen, but I am using Vim and tmux. Fight me. Anyway, once my post was done, I starting messing around with open source .NET Core on Linux (it runs on Windows, Mac, and Linux, but here I'm running on Linux on Windows. #Inception) and tweeted a pic of my desktop.

By the way, I feel totally vindicated by all the interest in "text mode" given my 2004 blog post "Windows is completely missing the TextMode boat." ;)'

Also, for those of you who are DEEPLY NOT INTERESTED in the command line, that's cool. You can stop reading now. Totally OK. I also use Visual Studio AND Visual Studio Code. Sometimes I click and mouse and sometimes I tap and type. There is room for us all.

WHAT IS ALL THIS LINUX ON WINDOWS STUFF? Here's a FAQ on the Bash/Windows Subsystem for Linux/Ubuntu on Windows/Snowball in Hell and some detailed Release Notes. Yes, it's real, and it's spectacular. Can't read that much text? Here's a video I did on Ubuntu on Windows 10.

A number of people asked me how they could set up their WSL (Windows Subsystem for Linux) installs to be something like this, so here's what I did. Note that will I've been using *nix on and off for 20+ years, I am by no means an expert. I am, and have been, Permanently Intermediate in my skills. I do not dream in RegEx, and I am offended that others can bust out an awk script without googling.

C9RT5_bUwAALJ-H

So there's a few things going on in this screenshot.

  • Running .NET Core on Linux (on Windows 10)
  • Cool VIM theme with >256 colors
  • Norton Midnight Commander in the corner (thanks Miguel)
  • Desqview-esque tmux splitter (with mouse support)
  • Some hotkey remapping, git prompt, completion
  • Ubuntu Mono font
  • Nice directory colors (DIRCOLORS/LS_COLORS)

Let's break them down one at a time. And, again, your mileage may vary, no warranty express or implied, any of this may destroy your world, you read this on a blog. Linux is infinitely configurable and the only constant is that my configuration rocks and yours sucks. Until I see something in yours that I can steal.

Running .NET Core on Linux (on Windows 10)

Since Linux on Windows 10 is (today) Ubuntu, you can install .NET Core within it just like any Linux. Here's the Ubuntu instructions for .NET Core's SDK. You may have Ubuntu 14.04 or 16.04 (you can upgrade your Linux on Windows if you like). Make sure you know what you're running by doing a:

~ $ lsb_release -a

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.2 LTS
Release: 16.04
Codename: xenial
~ $

If you're not on 16.04 you can easily remove and reinstall the whole subsystem with these commands at cmd.exe (note the /full is serious and torches the Linux filesystem):

> lxrun /uninstall /full

> lxrun /install

Or if you want you can run this within bash (will take longer but maintain settings):

sudo do-release-upgrade

Know what Ubuntu your Windows 10 has when you install .NET Core within it. The other thing to remember is that now you have two .NET Cores, one Windows and one Ubuntu, on the same (kinda) machine. Since the file systems are separated it's not a big deal. I do my development work within Ubuntu on /mnt/d/github (which is a Windows drive). It's OK for the Linux subsystem to edit files in Linux or Windows, but don't "reach into" the Linux file system from Windows.

Cool Vim theme with >256 colors

That Vim theme is gruvbox and I installed it like this. Thanks to Rich Turner for turning me on to this theme.

$ cd ~/

$ mkdir .vim
$ cd .vim
$ mkdir colors
$ cd colors
$ curl -O https://raw.githubusercontent.com/morhetz/gruvbox/master/colors/gruvbox.vim
$ cd ~/
$ vim .vimrc

Paste the following (hit ‘i’ for insert and then right click/paste)

set number

syntax enable
set background=dark
colorscheme gruvbox
set mouse=a

if &term =~ '256color'
" disable Background Color Erase (BCE) so that color schemes
" render properly when inside 256-color tmux and GNU screen.
" see also http://snk.tuxfamily.org/log/vim-256color-bce.html
set t_ut=
endif

Then save and exit with Esc, :wq (write and quit). There's a ton of themes out there, so try some for yourself!

Norton Midnight Commander in the corner (thanks Miguel)

Midnight Commander is a wonderful Norton Commander clone that Miguel de Icaza started, that's licensed as part of GNU. I installed it via apt, as I would any Ubuntu software.

$ sudo apt-get install mc

There's mouse support within the Windows conhost (console host) that bash runs within, so you'll even get mouse support within Midnight Commander!

Midnight Commander

Great stuff.

Desqview-esque tmux splitter (with mouse support)

Tmux is a terminal multiplexer. It's a text-mode windowing environment within which you can run multiple programs. Even better, you can "detach" from a running session and reattached from elsewhere. Because of this, folks love using tmux on servers where they can ssh in, set up an environment, detach, and reattach from elsewhere.

NOTE: The Windows Subsystem for Linux shuts down all background processes when the last console exits. So you can detach and attach tmux sessions happily, but just make sure you don't close every console on your machine.

Here's a nice animated gif of me moving the splitter on tmux on Windows. YES I KNOW YOU CAN USE THE KEYBOARD BUT THIS GIF IS COOL.

Some hotkey remapping, git prompt, completion

I am still learning tmux but here's my .tmux.conf. I've made a few common changes to make the hotkey creation of windows easier.

#remap prefix from 'C-b' to 'C-a'

unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix

# split panes using | and -
bind | split-window -h
bind _ split-window -v
unbind '"'
unbind %
bind k confirm kill-window
bind K confirm kill-server
bind < resize-pane -L 1
bind > resize-pane -R 1
bind - resize-pane -D 1
bind + resize-pane -U 1
bind r source-file ~/.tmux.conf

# switch panes using Alt-arrow without prefix
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D

# Enable mouse control (clickable windows, panes, resizable panes)
set -g mouse on
set -g default-terminal "screen-256color"

I'm using the default Ubuntu .bashrc that includes a check for dircolors (more on this below) but I added this for git-completion.sh and a git prompt, as well as these two alias. I like being able to type "desktop" to jump to my Windows Desktop. And the -x on Midnight Commander helps the mouse support.

alias desktop="cd /mnt/c/Users/scott/Desktop"

alias mc="mc -x"
export CLICOLOR=1
source ~/.git-completion.sh
PS1='\[\033[37m\]\W\[\033[0m\]$(__git_ps1 " (\[\033[35m\]%s\[\033[0m\])") \$ '
GIT_PS1_SHOWDIRTYSTATE=1
GIT_PS1_SHOWSTASHSTATE=1
GIT_PS1_SHOWUNTRACKEDFILES=1
GIT_PS1_SHOWUPSTREAM="auto"

Git Completion can be installed with:

sudo apt-get install git bash-completion

Ubuntu Mono font

I really like the Ubuntu Mono font, and I like the way it looks when running Ubuntu under Windows. You can download the Ubuntu Font Family free.

Ubuntu Mono

Nice directory colors (DIRCOLORS/LS_COLORS)'

If you have a black command prompt background, then default colors for directories will be dark blue on black, which sucks. Fortunately you can get .dircolors files from all over the wep, or set the LS_COLORS (make sure to search for LS_COLORS for Linux, not the other, different LSCOLORS on Mac) environment variable.

I ended up with "dircolors-solarized" from here, downloaded it with wget or curl and put it in ~. Then confirm this is in your .bashrc (it likely is already)

# enable color support of ls and also add handy aliases

if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'

alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi

Make a big difference for me, and as I mention, it's totally, gloriously, maddeningly configurable.

Nice dircolors

Leave YOUR Linux on Windows tips in the comments!


Sponsor: Did you know VSTS can integrate closely with Octopus Deploy? Watch Damian Brady and Brian A. Randell as they show you how to automate deployments from VSTS to Octopus Deploy, and demo the new VSTS Octopus Deploy dashboard widget. Watch now


© 2017 Scott Hanselman. All rights reserved.
     

Ruby on Rails on Azure App Service (Web Sites) with Linux (and Ubuntu on Windows 10)

Running Ruby on Rails on Windows has historically sucked. Most of the Ruby/Rails folks are Mac and Linux users and haven’t focused on getting Rails to be usable for daily development on Windows. There have been some heroic efforts by a number of volunteers to get Rails working with projects like RailsInstaller, but native modules and dependencies almost always cause problems. Even more, when you go to deploy your Rails app you’re likely using a Linux host so you may run into differences between operating systems.

Fast forward to today and Windows 10 has the Ubuntu-based “Linux Subsystem for Windows” (WSL) and the native bash shell which means you can run real Linux elf binaries on Windows natively without a Virtual Machine…so you should do your Windows-based Rails development in Bash on Windows.

Ruby on Rails development is great on Windows 10 because you’ve Windows 10 handling the “windows” UI part and bash and Ubuntu handling the shell.

After I set it up I want to git deploy my app to Azure, easily.

Developing on Ruby on Rails on Windows 10 using WSL

Rails and Ruby folks can apt-get update and apt-get install ruby, they can install rbenv or rvm as they like. These days rbenv is preferred.

Once you have Ubuntu on Windows 10 installed you can quickly install “rbenv” like this within Bash. Here I’m getting 2.3.0.

~$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
~$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
~$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
~$ exec $SHELL
~$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
~$ echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
~$ exec $SHELL
~$ rbenv install 2.3.0
~$ rbenv global 2.3.0
~$ ruby -v
~$ gem install bundler
~$ rbenv reshash

Here’s a screenshot mid-process on my SurfaceBook. This build/install step takes a while and hits the disk a lot, FYI.

Installing rbenv on Windows under Ubuntu

At this point I’ve got Ruby, now I need Rails, as well as NodeJs for the Rails Asset Pipeline. You can change the versions as appropriate.

@ curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
$ sudo apt-get install -y nodejs
$ gem install rails -v 5.0.1

You will likely also want either PostgresSQL or MySQL or Mongo, or you can use a Cloud DB like Azure DocumentDB.

When you’re developing on both Windows and Linux at the same time, you’ll likely want to keep your code in one place or the other, not both. I use the automatic mount point that WSL creates at /mnt/c so for this sample I’m at /mnt/c/Users/scott/Desktop/RailsonAzure which maps to a folder on my Windows desktop. You can be anywhere, just be aware of your CR/LF settings and stay in one world.

I did a “rails new .” and got it running locally. Here you can se Visual Studio Code with Ruby Extensions and my project open next to Bash on Windows.

image

After I’ve got a Rails app running and I’m able to develop cleanly, jumping between Visual Studio Code on Windows and the Bash prompt within Ubuntu, I want to deploy the app to the web.

Since this is a simple “Hello World” default rails app I can’t deploy it somewhere where the Rails Environment is Production. There’s no Route in routes.rb (the Yay! You’re on Rails message is development-time only) and there’s no SECRET_KEY_BASE environment variable set which is used to verify signed cookies. I’ll need to add those two things. I’ll change routes.rb quickly to just use the default Welcome page for this demo, like this:

Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
    get '/' => "rails/welcome#index"
end

And I’ll add the SECRET_KEY_BASE in as an App Setting/ENV var in the Azure portal when I make my backend, below.

Deploying Ruby on Rails App to Azure App Service on Linux

From the New menu in the Azure portal, choose to Web App on Linux (in preview as of the time I wrote this) from the Web + Mobile option. This will make an App Service Plan that has an App within it. There are a bunch of application stacks you can use here including node.js, PHP, .NE Core, and Ruby.

NOTE: A few glossary and definition points. Azure App Service is the Azure PaaS (Platform as a Service). You run Web Apps on Azure App Service. An Azure App Service Plan is the underlying Virtual Machine (sall, medium, large, etc.) that hosts n number of App Services/Web Sites. I have 20 App Services/Web Sites running under a App Service Plan with a Small VM. By default this is Windows by can run Php, Python, Node, .NET, etc. In this blog post I’m using an App Service Plan that runs Linux and hosts Docker containers. My Rails app will live inside that App Service and you can find the Dockerfiles and other info here https://github.com/Azure-App-Service/ruby or use your own Docker image.

Here you can see my Azure App Service that I’ll now deploy to using Git. I could also FTP.

Ruby on Rails on Azure

I went into Deployment OPtions and setup a local (to Azure) git repro. Now I can see that under Overview.

image

On my local bash I add azure as a remote. This can be set up however your workflow is setup. In this case, Git is FTP for code.

$ git add remote azure https:[email protected]:443/RubyOnAzureAppService.git
$ git add .
$ git commit -m "initial"
$ git push azure master

This starts the deployment as the code is pushed to Azure.

Azure deploying the Rails app

IMPORTANT: I will also add “RAILS_ENV= production” and a SECRET_KEY_BASE=to my Azure Application Settings. You can make a new secret with “rake secret.”

If I’m having trouble I can turn on Application Logging, Web Server Logging, and Detailed Error Messages under Diagnostic Logs then FTP into the App Service and look at the logs.

FTPing into Azure to look at logs

This is all in Preview so you’ll likely run into issues. They are updating the underlying systems very often. Some gotchas I hit:

  • Deploying/redeploying requires an explicit site restart, today. I hear that’ll be fixed soon.
  • I had to dig log files out via FTP. They are going to expose logs in the portal.
  • I used the Kudu “sidecar” site at mysite.scm.azurewebsite.net to get shell access to the Kudu container, but I’d like to be able to ssh into or get to access to the actual running container from the Azure Portal one day.

That said, if you’d like more internal details on how this works, you can watch a session from Connect() last year with developer Nazim Lala. Thanks to James Christianson for his debugging help!


Sponsor: Did you know VSTS can integrate closely with Octopus Deploy? Watch Damian Brady and Brian A. Randell as they show you how to automate deployments from VSTS to Octopus Deploy, and demo the new VSTS Octopus Deploy dashboard widget. Watch now


© 2017 Scott Hanselman. All rights reserved.
     

Running Ruby on Rails on Windows has historically sucked. Most of the Ruby/Rails folks are Mac and Linux users and haven't focused on getting Rails to be usable for daily development on Windows. There have been some heroic efforts by a number of volunteers to get Rails working with projects like RailsInstaller, but native modules and dependencies almost always cause problems. Even more, when you go to deploy your Rails app you're likely using a Linux host so you may run into differences between operating systems.

Fast forward to today and Windows 10 has the Ubuntu-based "Linux Subsystem for Windows" (WSL) and the native bash shell which means you can run real Linux elf binaries on Windows natively without a Virtual Machine...so you should do your Windows-based Rails development in Bash on Windows.

Ruby on Rails development is great on Windows 10 because you've Windows 10 handling the "windows" UI part and bash and Ubuntu handling the shell.

After I set it up I want to git deploy my app to Azure, easily.

Developing on Ruby on Rails on Windows 10 using WSL

Rails and Ruby folks can apt-get update and apt-get install ruby, they can install rbenv or rvm as they like. These days rbenv is preferred.

Once you have Ubuntu on Windows 10 installed you can quickly install "rbenv" like this within Bash. Here I'm getting 2.3.0.

~$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv

~$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
~$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
~$ exec $SHELL
~$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
~$ echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
~$ exec $SHELL
~$ rbenv install 2.3.0
~$ rbenv global 2.3.0
~$ ruby -v
~$ gem install bundler
~$ rbenv reshash

Here's a screenshot mid-process on my SurfaceBook. This build/install step takes a while and hits the disk a lot, FYI.

Installing rbenv on Windows under Ubuntu

At this point I've got Ruby, now I need Rails, as well as NodeJs for the Rails Asset Pipeline. You can change the versions as appropriate.

@ curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -

$ sudo apt-get install -y nodejs
$ gem install rails -v 5.0.1

You will likely also want either PostgresSQL or MySQL or Mongo, or you can use a Cloud DB like Azure DocumentDB.

When you're developing on both Windows and Linux at the same time, you'll likely want to keep your code in one place or the other, not both. I use the automatic mount point that WSL creates at /mnt/c so for this sample I'm at /mnt/c/Users/scott/Desktop/RailsonAzure which maps to a folder on my Windows desktop. You can be anywhere, just be aware of your CR/LF settings and stay in one world.

I did a "rails new ." and got it running locally. Here you can se Visual Studio Code with Ruby Extensions and my project open next to Bash on Windows.

image

After I've got a Rails app running and I'm able to develop cleanly, jumping between Visual Studio Code on Windows and the Bash prompt within Ubuntu, I want to deploy the app to the web.

Since this is a simple "Hello World" default rails app I can't deploy it somewhere where the Rails Environment is Production. There's no Route in routes.rb (the Yay! You're on Rails message is development-time only) and there's no SECRET_KEY_BASE environment variable set which is used to verify signed cookies. I'll need to add those two things. I'll change routes.rb quickly to just use the default Welcome page for this demo, like this:

Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
    get '/' => "rails/welcome#index"
end

And I'll add the SECRET_KEY_BASE in as an App Setting/ENV var in the Azure portal when I make my backend, below.

Deploying Ruby on Rails App to Azure App Service on Linux

From the New menu in the Azure portal, choose to Web App on Linux (in preview as of the time I wrote this) from the Web + Mobile option. This will make an App Service Plan that has an App within it. There are a bunch of application stacks you can use here including node.js, PHP, .NE Core, and Ruby.

NOTE: A few glossary and definition points. Azure App Service is the Azure PaaS (Platform as a Service). You run Web Apps on Azure App Service. An Azure App Service Plan is the underlying Virtual Machine (sall, medium, large, etc.) that hosts n number of App Services/Web Sites. I have 20 App Services/Web Sites running under a App Service Plan with a Small VM. By default this is Windows by can run Php, Python, Node, .NET, etc. In this blog post I'm using an App Service Plan that runs Linux and hosts Docker containers. My Rails app will live inside that App Service and you can find the Dockerfiles and other info here https://github.com/Azure-App-Service/ruby or use your own Docker image.

Here you can see my Azure App Service that I'll now deploy to using Git. I could also FTP.

Ruby on Rails on Azure

I went into Deployment OPtions and setup a local (to Azure) git repro. Now I can see that under Overview.

image

On my local bash I add azure as a remote. This can be set up however your workflow is setup. In this case, Git is FTP for code.

$ git add remote azure https:[email protected]:443/RubyOnAzureAppService.git

$ git add .
$ git commit -m "initial"
$ git push azure master

This starts the deployment as the code is pushed to Azure.

Azure deploying the Rails app

IMPORTANT: I will also add "RAILS_ENV= production" and a SECRET_KEY_BASE=to my Azure Application Settings. You can make a new secret with "rake secret."

If I'm having trouble I can turn on Application Logging, Web Server Logging, and Detailed Error Messages under Diagnostic Logs then FTP into the App Service and look at the logs.

FTPing into Azure to look at logs

This is all in Preview so you'll likely run into issues. They are updating the underlying systems very often. Some gotchas I hit:

  • Deploying/redeploying requires an explicit site restart, today. I hear that'll be fixed soon.
  • I had to dig log files out via FTP. They are going to expose logs in the portal.
  • I used the Kudu "sidecar" site at mysite.scm.azurewebsite.net to get shell access to the Kudu container, but I'd like to be able to ssh into or get to access to the actual running container from the Azure Portal one day.

That said, if you'd like more internal details on how this works, you can watch a session from Connect() last year with developer Nazim Lala. Thanks to James Christianson for his debugging help!


Sponsor: Did you know VSTS can integrate closely with Octopus Deploy? Watch Damian Brady and Brian A. Randell as they show you how to automate deployments from VSTS to Octopus Deploy, and demo the new VSTS Octopus Deploy dashboard widget. Watch now



© 2017 Scott Hanselman. All rights reserved.
     

Writing and debugging Linux C++ applications from Visual Studio using the “Windows Subsystem for Linux”

I’ve blogged about the “Windows Subsystem for Linux” (also known as “Bash on Ubuntu on Windows“) many times before. Response to this Windows feature has been a little funny because folks try to:

  • Minimize it – “Oh, it’s just Cygwin.” (It’s actually not, it’s the actual Ubuntu elf binaries running on a layer that abstracts the Linux kernel.)
  • Design it – “So it’s a docker container? A VM?” (Again, it’s a whole subsystem. It does WAY more than you’d think, and it’s FASTer than a VM.)

Here’s a simple explanation from Andrew Pardoe:

1. The developer/user uses a bash shell.
2. The bash shell runs on an install of Ubuntu
3. The Ubuntu install runs on a Windows subsystem. This subsystem is designed to support Linux.

It’s pretty cool. WSL has, frankly, kept me running Windows because I can run cmd, powershell, OR bash (or zsh or Fish). You can run vim, emacs, tmux, and run Javascript/node.js, Ruby, Python, C/C++, C# & F#, Rust, Go, and more. You can also now run sshd, MySQL, Apache, lighttpd as long as you know that when you close your last console the background services will shut down. Bash on Windows is for developers, not background server apps. And of course, you apt-get your way to glory.

Bash on Windows runs Ubuntu user-mode binaries provided by Canonical. This means the command-line utilities are the same as those that run within a native Ubuntu environment.

I wanted to write a Linux Console app in C++ using Visual Studio in Windows. Why? Why not? I like VS.

Setting up Visual Studio 2017 to compile and debug C++ apps on Linux

Then, from the bash shell make sure you have build-essential, gdb’s server, and openssh’s server:

$ sudo apt update
$ sudo apt install -y build-essential
$ sudo apt install -y gdbserver
$ sudo apt install -y openssh-server

Then open up /etc/ssh/sshd_config with vi (or nano) like

sudo nano /etc/ssh/sshd_config

and for simplicity’s sake, set PasswordAuthentication to yes. Remember that it’s not as big a security issue as you’d think as the SSHD daemon closes when your last console does, and because WSL’s subsystem has to play well with Windows, it’s privy to the Windows Firewall and all its existing rules, plus we’re talking localhost also.

Now generate SSH keys and manually start the service:

$ sudo ssh-keygen -A
$ sudo service ssh start

Create a Linux app in Visual Studio (or open a Makefile app):

File | New Project | Cross Platform | Linux

Make sure you know your target (x64, x86, ARM):

Remote GDB Debugger options

In Visual Studio’s Cross Platform Connection Manager you can control your SSH connections (and set up ones with private keys, if you like.)

Tools | Options | Cross Platfrom | Connection Manager

 

Boom. I’m writing C++ for LInux in Visual Studio on Windows…running, compiling and debugging on the local Linux Subsystem

I'm writing C++ in Visual Studio on Windows talking to the local Linux Subsystem

BTW, for those of you, like me, who love your Raspberry Pi tiny Linux computers…this is a great way to write C++ for those little devices as well. There’s even a Blink example in File | New Project to start.

Also, for those of you who are very advanced, stop using Mingw-w64 and do cool stuff like compiling gcc 6.3 from source under WSL and having VS use that! I didn’t realize that Visual Studio’s C++ support lets you choose between a number of C++ compilers including both GCC and Clang.


Sponsor: Thanks to Redgate! Track every change to your database! See who made changes, what they did, & why, with SQL Source Control. Get a full version history in your source control system. See how.


© 2017 Scott Hanselman. All rights reserved.
     

I've blogged about the "Windows Subsystem for Linux" (also known as "Bash on Ubuntu on Windows") many times before. Response to this Windows feature has been a little funny because folks try to:

  • Minimize it - "Oh, it's just Cygwin." (It's actually not, it's the actual Ubuntu elf binaries running on a layer that abstracts the Linux kernel.)
  • Design it - "So it's a docker container? A VM?" (Again, it's a whole subsystem. It does WAY more than you'd think, and it's FASTer than a VM.)

Here's a simple explanation from Andrew Pardoe:

1. The developer/user uses a bash shell.
2. The bash shell runs on an install of Ubuntu
3. The Ubuntu install runs on a Windows subsystem. This subsystem is designed to support Linux.

It's pretty cool. WSL has, frankly, kept me running Windows because I can run cmd, powershell, OR bash (or zsh or Fish). You can run vim, emacs, tmux, and run Javascript/node.js, Ruby, Python, C/C++, C# & F#, Rust, Go, and more. You can also now run sshd, MySQL, Apache, lighttpd as long as you know that when you close your last console the background services will shut down. Bash on Windows is for developers, not background server apps. And of course, you apt-get your way to glory.

Bash on Windows runs Ubuntu user-mode binaries provided by Canonical. This means the command-line utilities are the same as those that run within a native Ubuntu environment.

I wanted to write a Linux Console app in C++ using Visual Studio in Windows. Why? Why not? I like VS.

Setting up Visual Studio 2017 to compile and debug C++ apps on Linux

Then, from the bash shell make sure you have build-essential, gdb's server, and openssh's server:

$ sudo apt update

$ sudo apt install -y build-essential
$ sudo apt install -y gdbserver
$ sudo apt install -y openssh-server

Then open up /etc/ssh/sshd_config with vi (or nano) like

sudo nano /etc/ssh/sshd_config

and for simplicity's sake, set PasswordAuthentication to yes. Remember that it's not as big a security issue as you'd think as the SSHD daemon closes when your last console does, and because WSL's subsystem has to play well with Windows, it's privy to the Windows Firewall and all its existing rules, plus we're talking localhost also.

Now generate SSH keys and manually start the service:

$ sudo ssh-keygen -A

$ sudo service ssh start

Create a Linux app in Visual Studio (or open a Makefile app):

File | New Project | Cross Platform | Linux

Make sure you know your target (x64, x86, ARM):

Remote GDB Debugger options

In Visual Studio's Cross Platform Connection Manager you can control your SSH connections (and set up ones with private keys, if you like.)

Tools | Options | Cross Platfrom | Connection Manager

 

Boom. I'm writing C++ for LInux in Visual Studio on Windows...running, compiling and debugging on the local Linux Subsystem

I'm writing C++ in Visual Studio on Windows talking to the local Linux Subsystem

BTW, for those of you, like me, who love your Raspberry Pi tiny Linux computers...this is a great way to write C++ for those little devices as well. There's even a Blink example in File | New Project to start.

Also, for those of you who are very advanced, stop using Mingw-w64 and do cool stuff like compiling gcc 6.3 from source under WSL and having VS use that! I didn't realize that Visual Studio's C++ support lets you choose between a number of C++ compilers including both GCC and Clang.


Sponsor: Thanks to Redgate! Track every change to your database! See who made changes, what they did, & why, with SQL Source Control. Get a full version history in your source control system. See how.


© 2017 Scott Hanselman. All rights reserved.
     

Publishing an ASP.NET Core website to a cheap Linux VM host

A little Linux VM on Azure is like $13 a month. You can get little Linux machines all over for between $10-15 a month. On Linode they are about $10 a month so I figured it would be interesting to setup an ASP.NET Core website running on .NET Core. As you may know, .NET Core is free, open source, cross platform and runs basically everywhere.

Step 0 – Get a cheap host

I went to Linode (or anywhere) and got the cheapest Linux machine they offered. In this case it’s an Ubuntu 14.04 LTS Profile, 640bit, 4.6.5 Kernel.

I signed up for a tiny VM at Linode

Since I’m on Windows but I want to SSH into this Linux machine I’ll need a SSH client. There’s a bunch of options.

Step 0.5 – Setup a user that isn’t root

It’s always a good idea to avoid being root. After logging into the system as root, I made a new user and give them sudo (super user do):

adduser scott
usermod -aG sudo scott

Then I’ll logout and go back in as scott.

Step 1 – Get .NET Core on your Linux Machine

Head over to http://dot.net to get .NET Core and follow the instructions. There’s at least 8 Linuxes supported in 6 flavors so you should have no trouble. I followed the Ubuntu instructions.

To make sure it works after you’ve set it up, make a quick console app like this and run it.

mkdir testapp
cd testapp
dotnet new
dotnet restore
dotnet run

If it runs, then you’ve got .NET Core installed and you can move on to making a web app and exposing it to the internet.

NOTE: If “dotnet restore” fails with a segmentation fault, you may be running into this issue with some 64-bit Linux Kernels. Here’s commands to fix it that worked for me on Ubuntu 14.04 when I hit this. The fix has been released as a NuGet now but it will be included with the next minor release of .NET Core, but if you ever need to manually update the CoreCLR you can.

Step 2 – Make an ASP.NET Core website

You can make an ASP.NET Core website that is very basic and very empty and that’s OK. You can also get Yeoman and use the ASP.NET yeoman-based generators to get more choices. There is also the great ASP.NET MVC Boilerplate project for Visual Studio.

Or you can just start with:

dotnet new -t web

Today, this default site uses npm, gulp, and bower to manage JavaScript and CSS dependencies. In the future there will be options that don’t require as much extra stuff but for now, in order to dotnet restore this site I’ll need npm and what not so I’ll do this to get node, npm, etc.

sudo install npm
sudo npm install gulp
sudo npm install bower

Now I can dotnet restore easily and run my web app to test. It will startup on localhost:5000 usually.

$ dotnet restore
$ dotnet run
[email protected]:~/dotnettest$ dotnet run
Project dotnettest (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
User profile is available. Using '/home/scott/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Hosting environment: Production
Content root path: /home/scott/dotnettest
Now listening on: http://localhost:5000

Of course, having something startup on localhost:5000 doesn’t help me as I’m over here at home so I can’t test a local website like this. I want to expose this site (via a port) to the outside world. I want something like http://mysupermachine -> inside my machine -> localhost:5000.

Step 3 – Expose your web app to the outside.

I could tell Kestrel – that’s the .NET Web Server – to expose itself to Port 80, although you usually want to have another process between you and the outside world.

You can do this a few ways. You can open open Program.cs with a editor like “pico” and add a .UseUrls() call to the WebHostBuilder like this.

var host = new WebHostBuilder()
.UseKestrel()
.UseUrls("http://*:80")
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();

Here the * binds to all the network adapters and it listens on Port 80. Putting http://0.0.0.0:80 also works.

You might have permission issues doing this and need to elevate the dotnet process and webserver which is also a problem so let’s just keep it at a high internal port and reverse proxy the traffic with something like Nginx or Apache. We’ll pull out the hard-coded port from the code and change the Program.cs to use a .json config file.

public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.Build();

var host = new WebHostBuilder()
.UseKestrel()
.UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();

host.Run();
}

The hosting.json file is just this:

{
"server.urls": "http://localhost:5123"
}

We can also use “AddCommandLine(args) instead of “AddJsonFile()” and pass in –server.urls=http://*:5123 on the command line. It’s up to you. You can also use the ASPNETCORE_URLS environment variable.

NOTE: I’m doing this work a folder under my home folder ~ or now. I’ll later compile and “publish” this website to something like /var/dotnettest when I want it seen.

Step 4 – Setup a Reverse Proxy like Nginx

I’m following the detailed instructions at the ASP.NET Core Docs site called “Publish to a Linux Production Environment.” (All the docs are on GitHub as well)

I’m going to bring in Nginx and start it.

sudo apt-get install nginx
sudo service nginx start

I’m going to change the default Nginx site to point to my (future) running ASP.NET Core web app. I’ll open and change /etc/nginx/sites-available/default and make it look like this. Note the port number. Nginx is a LOT more complex than this and has a lot of nuance, so when you are ready to go into Super Official Production, be sure to explore what the perfect Nginx Config File looks like and change it to your needs.

server {
listen 80;
location / {
proxy_pass http://localhost:5123;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

Then we’ll check it and reload the config.

sudo nginx -t 
sudo nginx -s reload

Step 5 – Keep your website running

The website isn’t up and running on localhost:5123 yet (unless you’ve run it yourself and kept it running!) so we’ll need an app or a monitor to run it and keep it running. There’s an app called Supervisor that is good at that so I’ll add it.

sudo apt-get install supervisor

Here is where you/we/I/errbody needs to get the paths and names right, so be aware. I’m over in ~/testapp or something. I need to publish my site into a final location so I’m going to run dotnet publish, then copy the reuslts into /var/dotnettest where it will live.

dotnet publish
publish: Published to /home/scott/dotnettest/bin/Debug/netcoreapp1.0/publish
sudo cp -a /home/scott/dotnettest/bin/Debug/netcoreapp1.0/publish /var/dotnettest

Now I’m going to make a file (again, I use pico because I’m not as awesome as emacs or vim) called /src/supervisor/conf.d/dotnettest.conf to start my app and keep it running:

[program:dotnettest]
command=/usr/bin/dotnet /var/dotnettest/dotnettest.dll --server.urls:http://*:5123
directory=/var/dotnettest/
autostart=true
autorestart=true
stderr_logfile=/var/log/dotnettest.err.log
stdout_logfile=/var/log/dotnettest.out.log
environment=ASPNETCORE_ENVIRONMENT=Production
user=www-data
stopsignal=INT

Now we start and stop Supervisor and watch/tail its logs to see our app startup!

sudo service supervisor stop
sudo service supervisor start
sudo tail -f /var/log/supervisor/supervisord.log
#and the application logs if you like
sudo tail -f /var/log/dotnettest.out.log

If all worked out (if it didn’t, it’ll be a name or a path so keep trying!) you’ll see the supervisor log with dotnet starting up, running your app.

Hey it's dotnet on linux

Remember the relationships.

  • Dotnet – runs your website
  • Nginx or Apache – Listens on Port 80 and forwards HTTP calls to your website
  • Supervisor – Keeps your app running

Next, I might want to setup a continuous integration build, or SCP/SFTP to handle deployment of my app. That way I can develop locally and push up to my Linux machine.

Hey it's my ASP.NET Core app on Linux

Of course, there are a dozen other ways to publish an ASP.NET Core site, not to mention Docker. I’ll post about Docker another time, but for now, I was able to get my ASP.NET Core website published to a cheap $10 host in less than an hour. You can use the same tools to manage a .NET Core site that you use to manage any site be it PHP, nodejs, Ruby, or whatever makes you happy.


Sponsor: Aspose makes programming APIs for working with files, like: DOC, XLS, PPT, PDF and countless more.  Developers can use their products to create, convert, modify, or manage files in almost any way.  Aspose is a good company and they offer solid products.  Check them out, and download a free evaluation.


© 2016 Scott Hanselman. All rights reserved.
     

A little Linux VM on Azure is like $13 a month. You can get little Linux machines all over for between $10-15 a month. On Linode they are about $10 a month so I figured it would be interesting to setup an ASP.NET Core website running on .NET Core. As you may know, .NET Core is free, open source, cross platform and runs basically everywhere.

Step 0 - Get a cheap host

I went to Linode (or anywhere) and got the cheapest Linux machine they offered. In this case it's an Ubuntu 14.04 LTS Profile, 640bit, 4.6.5 Kernel.

I signed up for a tiny VM at Linode

Since I'm on Windows but I want to SSH into this Linux machine I'll need a SSH client. There's a bunch of options.

Step 0.5 - Setup a user that isn't root

It's always a good idea to avoid being root. After logging into the system as root, I made a new user and give them sudo (super user do):

adduser scott

usermod -aG sudo scott

Then I'll logout and go back in as scott.

Step 1 - Get .NET Core on your Linux Machine

Head over to http://dot.net to get .NET Core and follow the instructions. There's at least 8 Linuxes supported in 6 flavors so you should have no trouble. I followed the Ubuntu instructions.

To make sure it works after you've set it up, make a quick console app like this and run it.

mkdir testapp

cd testapp
dotnet new
dotnet restore
dotnet run

If it runs, then you've got .NET Core installed and you can move on to making a web app and exposing it to the internet.

NOTE: If "dotnet restore" fails with a segmentation fault, you may be running into this issue with some 64-bit Linux Kernels. Here's commands to fix it that worked for me on Ubuntu 14.04 when I hit this. The fix has been released as a NuGet now but it will be included with the next minor release of .NET Core, but if you ever need to manually update the CoreCLR you can.

Step 2 - Make an ASP.NET Core website

You can make an ASP.NET Core website that is very basic and very empty and that's OK. You can also get Yeoman and use the ASP.NET yeoman-based generators to get more choices. There is also the great ASP.NET MVC Boilerplate project for Visual Studio.

Or you can just start with:

dotnet new -t web

Today, this default site uses npm, gulp, and bower to manage JavaScript and CSS dependencies. In the future there will be options that don't require as much extra stuff but for now, in order to dotnet restore this site I'll need npm and what not so I'll do this to get node, npm, etc.

sudo install npm

sudo npm install gulp
sudo npm install bower

Now I can dotnet restore easily and run my web app to test. It will startup on localhost:5000 usually.

$ dotnet restore

$ dotnet run
[email protected]:~/dotnettest$ dotnet run
Project dotnettest (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
User profile is available. Using '/home/scott/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Hosting environment: Production
Content root path: /home/scott/dotnettest
Now listening on: http://localhost:5000

Of course, having something startup on localhost:5000 doesn't help me as I'm over here at home so I can't test a local website like this. I want to expose this site (via a port) to the outside world. I want something like http://mysupermachine -> inside my machine -> localhost:5000.

Step 3 - Expose your web app to the outside.

I could tell Kestrel - that's the .NET Web Server - to expose itself to Port 80, although you usually want to have another process between you and the outside world.

You can do this a few ways. You can open open Program.cs with a editor like "pico" and add a .UseUrls() call to the WebHostBuilder like this.

var host = new WebHostBuilder()

.UseKestrel()
.UseUrls("http://*:80")
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();

Here the * binds to all the network adapters and it listens on Port 80. Putting http://0.0.0.0:80 also works.

You might have permission issues doing this and need to elevate the dotnet process and webserver which is also a problem so let's just keep it at a high internal port and reverse proxy the traffic with something like Nginx or Apache. We'll pull out the hard-coded port from the code and change the Program.cs to use a .json config file.

public static void Main(string[] args)

{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.Build();

var host = new WebHostBuilder()
.UseKestrel()
.UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();

host.Run();
}

The hosting.json file is just this:

{

"server.urls": "http://localhost:5123"
}

We can also use "AddCommandLine(args) instead of "AddJsonFile()" and pass in --server.urls=http://*:5123 on the command line. It's up to you. You can also use the ASPNETCORE_URLS environment variable.

NOTE: I'm doing this work a folder under my home folder ~ or now. I'll later compile and "publish" this website to something like /var/dotnettest when I want it seen.

Step 4 - Setup a Reverse Proxy like Nginx

I'm following the detailed instructions at the ASP.NET Core Docs site called "Publish to a Linux Production Environment." (All the docs are on GitHub as well)

I'm going to bring in Nginx and start it.

sudo apt-get install nginx

sudo service nginx start

I'm going to change the default Nginx site to point to my (future) running ASP.NET Core web app. I'll open and change /etc/nginx/sites-available/default and make it look like this. Note the port number. Nginx is a LOT more complex than this and has a lot of nuance, so when you are ready to go into Super Official Production, be sure to explore what the perfect Nginx Config File looks like and change it to your needs.

server {

listen 80;
location / {
proxy_pass http://localhost:5123;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

Then we'll check it and reload the config.

sudo nginx -t 

sudo nginx -s reload

Step 5 - Keep your website running

The website isn't up and running on localhost:5123 yet (unless you've run it yourself and kept it running!) so we'll need an app or a monitor to run it and keep it running. There's an app called Supervisor that is good at that so I'll add it.

sudo apt-get install supervisor

Here is where you/we/I/errbody needs to get the paths and names right, so be aware. I'm over in ~/testapp or something. I need to publish my site into a final location so I'm going to run dotnet publish, then copy the reuslts into /var/dotnettest where it will live.

dotnet publish

publish: Published to /home/scott/dotnettest/bin/Debug/netcoreapp1.0/publish
sudo cp -a /home/scott/dotnettest/bin/Debug/netcoreapp1.0/publish /var/dotnettest

Now I'm going to make a file (again, I use pico because I'm not as awesome as emacs or vim) called /src/supervisor/conf.d/dotnettest.conf to start my app and keep it running:

[program:dotnettest]

command=/usr/bin/dotnet /var/dotnettest/dotnettest.dll --server.urls:http://*:5123
directory=/var/dotnettest/
autostart=true
autorestart=true
stderr_logfile=/var/log/dotnettest.err.log
stdout_logfile=/var/log/dotnettest.out.log
environment=ASPNETCORE_ENVIRONMENT=Production
user=www-data
stopsignal=INT

Now we start and stop Supervisor and watch/tail its logs to see our app startup!

sudo service supervisor stop

sudo service supervisor start
sudo tail -f /var/log/supervisor/supervisord.log
#and the application logs if you like
sudo tail -f /var/log/dotnettest.out.log

If all worked out (if it didn't, it'll be a name or a path so keep trying!) you'll see the supervisor log with dotnet starting up, running your app.

Hey it's dotnet on linux

Remember the relationships.

  • Dotnet - runs your website
  • Nginx or Apache - Listens on Port 80 and forwards HTTP calls to your website
  • Supervisor - Keeps your app running

Next, I might want to setup a continuous integration build, or SCP/SFTP to handle deployment of my app. That way I can develop locally and push up to my Linux machine.

Hey it's my ASP.NET Core app on Linux

Of course, there are a dozen other ways to publish an ASP.NET Core site, not to mention Docker. I'll post about Docker another time, but for now, I was able to get my ASP.NET Core website published to a cheap $10 host in less than an hour. You can use the same tools to manage a .NET Core site that you use to manage any site be it PHP, nodejs, Ruby, or whatever makes you happy.


Sponsor: Aspose makes programming APIs for working with files, like: DOC, XLS, PPT, PDF and countless more.  Developers can use their products to create, convert, modify, or manage files in almost any way.  Aspose is a good company and they offer solid products.  Check them out, and download a free evaluation.



© 2016 Scott Hanselman. All rights reserved.
     

Installing Fish Shell on Ubuntu on Windows 10

So hopefully by now you’ve heard that you can run Bash via Ubuntu on Windows…and not in a VM. You can run the Bash Shell and real ELF Linux Binaries (this is not emulation) on Windows 10.

I’ve recorded a 30 min video with developers from the project and there’s a blog post from Dustin from Ubuntu about HOW this works if you want more technical details. You should also check out the Command Line Blog and subscribe and head over to User Voice to help pick the next features.

It’s beta, but it’s super fun. A common question is “hey bash is lovely but what about _____ shell.” Right now as I understand it supports bash and adding other shells may not work, and if it does, you’re hacking around. So, let’s hack around.

I noticed this shell called Fish Shell and noticed that Ruby Nealon had Fish tweaked and running. I asked for some more detail and they were happy to oblige with a medium post. Thanks Ruby!

Let me give it a try.

Add the Fish Apt Repo and install.

I headed over to the fish site and did this.

sudo apt-add-repository ppa:fish-shell/release-2
sudo apt-get update
sudo apt-get install fish

Oh, and I also changed my Console Font to use Ubuntu Mono because

Note: I’m hearing it will be WAY easier to add new fonts as the console continues improving. The conhost.exe stuff improves console for everyone, including cmd.exe, powershell.exe, and bash. That console work includes VT100, ANSI, and other stuff, and is separate, but complementary to the bash work.

Nice font.

Bash on Ubuntu on Windows - Cats and Dogs Living Together Mass Hysteria

Because we’re still launching bash, we need to use the .bashrc today to launch fish, so you’ll need to add ssh-agent fish, and exit to your .bashrc if you want to try this.

OK, next, kind of unrelated to fish, but still useful, I wanted to setup git and ssh-agent, so I generate a new key, add it to ssh agent, following these guides.

Theming Fish

Ruby also points out that Fish has a “Oh My Fish” framework for packages and themes. You can get it easily:

curl -L https://github.com/oh-my-fish/oh-my-fish/raw/master/bin/install | fish
omf help

Ruby also included their own fish_prompt.sh file here for the “chain” theme that I installed with “omf install chain” as some glyphs rendered weird. If you want unicode characters like → in your prompt, make sure your files are UTF-8 and not ANSI or you’ll get squares!

Now my prompt uses fish, has cool auto complete, nice colors, shows the git dirty bit and branch.

image

Yes, I realize there are literally fiftyleven billion ways to customize bash, zsh, and lots of other shells to do much cooler stuff than this. I too, am old, and I to have used *nix for years. But it was fun and easy to get fish running on Ubuntu on Windows. Thanks Ruby!


Sponsor: Quality instrumentation is critical for modern applications. Seq helps .NET teams make sense of complex, asynchronous, and distributed apps on-premises or in the cloud. Learn more about structured logging and try Seq free for 30 days at https://getseq.net.


© 2016 Scott Hanselman. All rights reserved.
     

So hopefully by now you've heard that you can run Bash via Ubuntu on Windows...and not in a VM. You can run the Bash Shell and real ELF Linux Binaries (this is not emulation) on Windows 10.

I've recorded a 30 min video with developers from the project and there's a blog post from Dustin from Ubuntu about HOW this works if you want more technical details. You should also check out the Command Line Blog and subscribe and head over to User Voice to help pick the next features.

It's beta, but it's super fun. A common question is "hey bash is lovely but what about _____ shell." Right now as I understand it supports bash and adding other shells may not work, and if it does, you're hacking around. So, let's hack around.

I noticed this shell called Fish Shell and noticed that Ruby Nealon had Fish tweaked and running. I asked for some more detail and they were happy to oblige with a medium post. Thanks Ruby!

Let me give it a try.

Add the Fish Apt Repo and install.

I headed over to the fish site and did this.

sudo apt-add-repository ppa:fish-shell/release-2

sudo apt-get update
sudo apt-get install fish

Oh, and I also changed my Console Font to use Ubuntu Mono because

Note: I'm hearing it will be WAY easier to add new fonts as the console continues improving. The conhost.exe stuff improves console for everyone, including cmd.exe, powershell.exe, and bash. That console work includes VT100, ANSI, and other stuff, and is separate, but complementary to the bash work.

Nice font.

Bash on Ubuntu on Windows - Cats and Dogs Living Together Mass Hysteria

Because we're still launching bash, we need to use the .bashrc today to launch fish, so you'll need to add ssh-agent fish, and exit to your .bashrc if you want to try this.

OK, next, kind of unrelated to fish, but still useful, I wanted to setup git and ssh-agent, so I generate a new key, add it to ssh agent, following these guides.

Theming Fish

Ruby also points out that Fish has a "Oh My Fish" framework for packages and themes. You can get it easily:

curl -L https://github.com/oh-my-fish/oh-my-fish/raw/master/bin/install | fish

omf help

Ruby also included their own fish_prompt.sh file here for the "chain" theme that I installed with "omf install chain" as some glyphs rendered weird. If you want unicode characters like → in your prompt, make sure your files are UTF-8 and not ANSI or you'll get squares!

Now my prompt uses fish, has cool auto complete, nice colors, shows the git dirty bit and branch.

image

Yes, I realize there are literally fiftyleven billion ways to customize bash, zsh, and lots of other shells to do much cooler stuff than this. I too, am old, and I to have used *nix for years. But it was fun and easy to get fish running on Ubuntu on Windows. Thanks Ruby!


Sponsor: Quality instrumentation is critical for modern applications. Seq helps .NET teams make sense of complex, asynchronous, and distributed apps on-premises or in the cloud. Learn more about structured logging and try Seq free for 30 days at https://getseq.net.



© 2016 Scott Hanselman. All rights reserved.