Docker on Windows: First Steps

Last night I wasted a few hours getting nowhere: various problems with the spec or config of machines I was trying Docker out against not matching up to assumptions in the msdn pages, blogs I was reading. However, remember this is firmly Windows. Sure, I dare say it is a breeze on Linux – I would not know.

Tonight in fact was a much better contrast. I have any number of SQLServer instances running on a single Windows Server 2016 Azure VM.

Let’s take it real slow… The first important step is to grab the right image in Azure for these purposes. One that works is this:

Always select the Resource Manager deployment model:

This is the size I usually pick: shut it down between use and it won’t be too expensive. I would not use 2 cores – I tried one a couple of days back, and it was REALLY slow. This speed is fine, for me:

That takes no more than 10 minutes to create.

Once it has been created, rdp onto it, and you will see that the Docker service is already running:

Then start a PowerShell admin session, and start playing. You will find there are already some images there:

docker images

Try these commands as well:

docker --help

docker --version

Across the Cloud of course the file transfers are blindingly fast – pulling down 10GB images is done in a matter of minutes, so this lot took me a max of minutes I think:

To get a new image, for example the latest SQL Server for Windows (as opposed these days to Linux, for example):

docker pull microsoft/mssql-server-windows

With that downloaded we can start the SQLServer instance:

docker run -d -p 1433:1433 -e sa_password=$dbpw -e ACCEPT_EULA=Y microsoft/mssql-server-windows

How to connect to the SQLServer instance

Run docker ps, and that gives you the Container Ids of all the running Docker… Containers:

docker ps

Stick that container id in a variable for later use, and run the inspect switch to get the ip address of the container..

docker inspect -format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $containerId

I could not see how to get the ip address directly into a variable, so again you have to do that by hand, e.g.


Now test your connectivity with sqlcmd before trying through ssms:

Now see my recent post on SSMS installation, and you see that what you created through the command line now appears in SSMS:

And finally for now shut down the container. In this shot, I try to stop a nonsense container, just to see how failure looks, and then stop the actual container. However I’d like better feedback than that (see the 2 docker stop lines). The second one has presumably silently failed. Trying to run sqlcmd against that ip address now fails… as you would want and expect. And although not shown, [docker ps] returns an empty set.



I don’t yet know how to run many containers against a single image, but this suggests to me it is possible.


Visual Studio Code: Roslyn and OmniSharp with the C# compiler on Windows

(A month is a long time in .Net, right now. Looking back at this, it clearly predates my getting to grips with project.json. I’m leaving it here as I find it instructive to leave my naive attempts in place.)

  • Visual Studio 2015: I abbreviate this to VS
  • Visual Studio Code: I abbreviate this to VSC


This is aimed at C# programmers on Windows, who are used to doing all their editing and dev compilation in VS. In VSC, you can edit existing .cs files which are already part of a parent .sln file. Doing this, you will get Intellisense and a whole bunch of richness. However if you create new .cs files, then to get Intellisense etc, you must first go to VS and add that new file to a .csproj and .sln (or write some command line transformer to add the .cs files… or a Task in VS). With a little one-off effort, you can compile inside VSC. 

If you are using VSC on Windows, and you are writing C#, and you want OmniSharp and Intellisense to work… then you must have a VS Solution in place. I emphasise that, because I first did not entirely digest this point here:


As a C# programmer, just heed the stuff in the orange borders. As ever, some screenshots illustrate the point. Firstly, this is what happens if you naively open a .cs file in VSC that does not ultimately have a parent .sln file:


After typing [System.] above, I pressed [ctrl-space], which returns [No suggestion]. That is because App1.cs is standalone, and has no VS Solution context. It is however perfectly valid C#  (once I fix the syntax):


But if in VS I now create a simple console app, and therefore get a .sln file, with the simple .cs existing in the context of that Solution, we see this in VS:


I then locate the solution in VSC:


, and open the program file. We then get all the Intellisense and OmniSharp checks:


Doing a bit more editing shows that you get:

  • IntelliSense (as said)
  • Redundant Usings warnings
  • A summary of warnings
  • snippet/auto completion (I haven’t yet worked out where it gets these), but e.g. CW does the right thing
  • Code formatting (I haven’t worked out how you set this to your standards)
  • Code Lens


So all in all, I THINK it was worth the pain… my use-case is that for the trade-off of creating at least a skeleton project in VS, I can edit on a non-full-power box. But right now, I see this being more for a scratchpad or POC application, rather than an enterprise-size application. That might not be true for an AngularJS app – I suspect it is not true given all the passion on Twitter etc for this from JavaScript people. But it does have a very small footprint. I have a Linx 2GB/32GB Windows 10 tablet, and whereas it struggled to cope with a full VS environment, I’m sure this will be easy for it. That is the use-case I guess (note I am specifically talking about C# usage, not JavaScript etc)

And note that you don’t somehow download OmniSharp, or direct VSC to find it as an extension. No, it is evidently part of VSC, on Windows anyway.