As you might be aware of with Windows 10 Anniversary Update there came a new feature on Windows which is very useful for developers and IT professionals. It’s the Bash running on Windows. Now people might ask who should be using this.
You might argue that nobody would ever need this or that Powershell is good enough and that you don’t want to learn new stuff or whatever. I think the answer can be much more pragmatic: Sometimes it just can make your live easier. Especially if you’re remoting into other servers.
Here’s a little story I came up with recently:
As a developer running Windows 10 I want to setup a docker swarm in the cloud without pain to be able to try things out.
Of course I know that there’s something called Azure Container Service. So I go to the portal and create a new Azure Container Service to let it do all the hard work for me.
It’s all pretty easy and super straight forward until the following dialog.
Creating SSH Keys with Bash on Windows
I’m now asked to provide an SSH public key. But where should I get this? So I start reading the documentation on ACS deployment and find a link how to create a key on Linux or Windows. It turns out following the Windows guidance requires to install Putty. Don’t get me wrong, that’s not a big deal, but I wish I could do it all on command line.
So I decide to instead just follow the Linux guidance in my Bash on Windows.
Here’s what I do:
- Start Bash on Windows
- Type ssh-keygen -t rsa -b 2048 -C firstname.lastname@example.org
So I get 2 new files, a public and a private key. I changed the name to sshdmxdemokeys. So I get a private key called “sshdmxdemokeys” and a public key called “sshdmxdemokeys.pub”. (I guess I should have chosen a name for the keys using singular not plural, but it really doesn’t matter.)
- With cat sshdmxdemokeys.pub I can view the content of the public key.
- I copy that content and paste it into the corresponding field in azure portal.
The green checkmark shows me things are looking good. So let’s follow the wizard. I decide for Docker Swarm and pick 5 agents.
After a few clicks more clicks (mostly confirming defaults) deployment starts. I have to wait for some minutes until deployment is done.
Connecting to the swarm using port forwarding and SSH with Bash on Windows
Now let’s connect to the Swarm master. I want to use my local docker cli but I want to “talk” to the swarm master running on Azure not to my local docker installation. So what I need is a forwarding of my local commands to the master running on Azure. I will setup an SSH connection to the swarm master on azure. Using this SSH connection I will set up a port forwarding that will forward my local docker commands to the swarm master.
Here’s how I set up port forwarding using Bash on Windows:
ssh -L 44444:localhost:2375 -f -N email@example.com -p 2200 -v -i sshdmxdemokeys -4
Here’s what this command basically says:
- Setup an SSH Connection to port 2200 on dmxacs7swarmmgmt.northeurope.cloudaapp.azure.com
The URL can be found in azure portal. It’s the DNS name of the swarm-agent public IP . See picture below.
- Use the private key file for authentication. In my case it’s sshdmxdemokeys
- Use the user name which is dmxonazure in my case.
- Forward all local requests to port 44444 to localhost:2375 on that remote host. Of course localhost:2375 on the remote host will be the remote host itself. I picked 44444 but you can choose any unused port here.
I run this command in Bash, so I don’t have to install anything. The ssh command is already pre installed within Bash. (At least I can’t remember installing it inside of Bash).
The nice thing here is that Bash running on Windows doesn’t live in a virtual machine but instead it is running in a subsystem. This is important in our scenario because we are setting up a port forwarding for Windows programs using Bash. As Bash and the rest of Windows share the same ports the forwarding hosted in Bash will also work for normal Windows programs.
Now I have to configure environment variables on Windows to make sure the docker commandline targets the correct host. Therefore I create a variable “DOCKER_HOST” with value “:44444”. This makes sure my docker commands run against the local port 44444. This port is forwarded to my Docker Swarm on Azure using a secure connection. So if all things work well now I should be able to run containers on Azure from my command line.
Let’s give it a try. I open up the Windows commandline (“cmd”). No when I run “docker run -d -p 80:80 yeasy/simple-web” it should create a container running on one of the agents.
Here’s what it looks like on my machine:
To make sure it really works I open up a browser and navigate to the agent’s URL.
Great! It works!
I think this is a fantastic proof that Bash on windows really helps you getting things done more smoothly. Don’t get me wrong – there are multiple ways to get this done without Bash, but I think this really is the most comfortable way out there.