Scott Hanselman

Penny Pinching in the Cloud: Deploying Containers cheaply to Azure

June 15, '18 Comments [12] Posted in Azure
Sponsored By

imageI saw a tweet from a person on Twitter who wanted to know the easiest and cheapest way to get an Web Application that's in a Docker Container up to Azure. There's a few ways and it depends on your use case.

Some apps aren't web apps at all, of course, and just start up in a stateless container, do some work, then exit. For a container like that, you'll want to use Azure Container Instances. I did a show and demo on this for Azure Friday.

Azure Container Instances

Using the latest Azure CLI  (command line interface - it works on any platform), I just do these commands to start up a container quickly. Billing is per-second. Shut it down and you stop paying. Get in, get out.

Tip: If you don't want to install anything, just go to https://shell.azure.com to get a bash shell and you can do these command there, even on a Chromebook.

I'll make a "resource group" (just a label to hold stuff, so I can delete it en masse later). Then "az container create" with the image. Note that that's a public image from Docker Hub, but I can also use a private Container Registry or a private one in Azure. More on that in a second.

Anyway, make a group (or use an existing one), create a container, and then either hit the IP I get back or I can query for (or guess) the full name. It's usually dns=name-label.location.azurecontainer.io.

> az group create --name someContainers --location westus
Location Name
---------- --------------
westus someContainers
> az container create --resource-group someContainers --name fancypantscontainer --image microsoft/aci-helloworl
d --dns-name-label fancy-container-demo --ports 80
Name ResourceGroup ProvisioningState Image IP:ports CPU/Memory OsType Location
------------------- --------------- ------------------- ------------------------ ---------------- --------------- -------- ----------
fancypantscontainer someContainers Pending microsoft/aci-helloworld 40.112.167.31:80 1.0 core/1.5 gb Linux westus
> az container show --resource-group someContainers --name fancypantscontainer --query "{FQDN:ipAddress.fqdn,ProvisioningState:provisioningState}" --out table
FQDN ProvisioningState
--------------------------------------------- -------------------
fancy-container-demo.westus.azurecontainer.io Succeeded

Boom, container in the cloud, visible externally (if I want) and per-second billing. Since I made and named a resource group, I can delete everything in that group (and stop billing) easily:

> az group delete -g someContainers 

This is cool because I can basically run Linux or Windows Containers in a "serverless" way. Meaning I don't have to think about VMs and I can get automatic, elastic scale if I like.

Azure Web Apps for Containers

ACI is great for lots of containers quickly, for bringing containers up and down, but I like my long-running web apps in Azure Web Apps for Containers. I run 19 Azure Web Apps today via things like Git/GitHub Deploy, publish from VS, or CI/CD from VSTS.

Azure Web Apps for Containers is the same idea, except I'm deploying containers directly. I can do a Single Container easily or use Docker Compose for multiple.

I wanted to show how easy it was to set this up so I did a video (cold, one take, no rehearsal, real accounts, real app) and put it on YouTube. It explains "How to Deploy Containers cheaply to Azure" in 21 minutes. It could have been shorter, but I also wanted to show how you can deploy from both Docker Hub (public) or from your own private Azure Container Registry.

I did all the work from the command line using Docker commands where I just pushed to my internal registry!

> docker login hanselregistry.azurecr.io
> docker build -t hanselregistry.azurecr.io/podcast .
> docker push hanselregistry.azurecr.io/podcast

Took minutes to get my podcast site running on Azure in Web Apps for Containers. And again - this is the penny pinching part - keep control of the App Service Plan (the VM underneath the App Service) and use the smallest one you can and pack the containers in tight.

Watch the video, and note when I get to the part where I add create an "App Service Plan." Again, that's the VM under a Web App/App Service. I have 19 smallish websites inside a Small (sometime a Medium, I can scale it whenever) App Service. You should be able to fit 3-4 decent sites in small ones depending on memory and CPU characteristics of the site.

Click Pricing Plan and you'll get here:

Recommend Pricing tiers have many choices

Be sure to explore the Dev/Test tab on the left as well. When you're making a non-container-based App Service you'll see F1 and D1 for Free and Shared. Both are fine for small websites, demos, hosting your github projects, etc.

Free, Shared, or Basic Infrastructure

If you back up and select Docker as the "OS"...

Windows, Linux, or Docker

Again check out Dev/Test for less demanding workloads and note B1 - Basic.

B1 is $32.74

The first B1 is free for 30 days! Good to kick the tires. Then as of the timing of this post it's US$32.74 (Check pricing for different regions and currencies) but has nearly 2 gigs of RAM. I can run several containers in there.

Just watch your memory and CPU and pack them in. Again, more money means better perf, but the original ask here was how to save money.

Low CPU and 40% memory

To sum up, ACI is great for per-second billing and spinning up n containers programmatically and getting out fast) and App Service for Containers is an easy way to deploy your Dockerized apps. Hope this helps.


Sponsor: Check out dotMemory Unit, a free unit testing framework for fighting all kinds of memory issues in your code. Extend your unit testing with the functionality of a memory profiler.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

EarTrumpet 2.0 makes Windows 10's audio subsystem even better...and it's free!

June 13, '18 Comments [9] Posted in Open Source | Win10
Sponsored By

EarTrumpetLast week I blogged about some new audio features in Windows 10 that make switching your inputs and outputs easier, but even better, allow you to set up specific devices for specific programs. That means I can have one mic and headphones for Audition, while another for browsing, and yet another set for Skype.

However, while doing my research and talking about this on Twitter, lots of people started recommending I check out "EarTrumpet" - it's an applet that lets you control the volume of classic and modern Windows Apps in one nice UI! Switching, volume, and more. Consider EarTrumpet a prosumer replacement for the little Volume icon down by the clock in Windows 10. You'll hide the default one and drag EarTrumpet over in its place and use it instead!

EarTrumpet

EarTrumpet is available for free in the Windows Store and works on all versions of Windows 10, even S! I have no affiliation with the team that built it and it's a free app, so you have literally nothing to lose by trying it out!

EarTrumpet is also open source and on GitHub. The team that built it is:

  • Rafael Rivera - a software forward/reverse engineer
  • David Golden - lead engineer on MetroTwit, the greatest WPF Twitter Client the world has never known.
  • Dave Amenta - ex-Microsoft, worked on shell and Start menu for Windows 8 and 10

It was originally built as a replacement for the Volume Control in Windows back in 2015, but EarTrumpet 2.0's recent release makes it easy to use the new audio capabilities in the Windows 10's April 2018 Update.

Looks Good

It's easy to make a crappy Windows App. Heck, it's easy to make a crappy app. But EarTrumpet is NOT just an "applet" or an app. It's a perfect example of how a Windows 10 app - not made by Microsoft - can work and look seamlessly with the operating system. You'll think it's native - and it adds functionality that probably should be built in to Windows!

It's got light/dark theme support (no one bothers to even test this, but EarTrumpet does) and a nice acrylic blur. It looks like it's built-in/in-box. There's a sample app so you can make your apps look this sharp up on Rafael's GitHub and here's the actual BlurWindowExtensions that EarTrumpet uses.

Works Good

Quickly switch outputEarTrumpet 1.x works on Windows "RS3 and below" so that's 10.0.16299 and down. But 2.0 works on the latest Windows and is also written entirely in C#. Any remaining C++ code has been removed with no missing functionality.

EarTrumpet may SEEM like a simple app but there's a lot going on to be this polished AND work with any combination of audio hardware. As a podcaster and remote workers I have a LOT of audio devices but I now have one-click control over it all.

Given how fast Windows 10 has been moving with Insiders Builds and all, it seems like there's a bunch of APIs with new functionality that lacks docs. The EarTrumpet team has reverse engineered the parts the needed.

Modern Resource Technology (MRT) Resource Manager

Internal Audio Interface: IAudioPolicyConfigFactory

  • Gets them access to new APIs (GetPersistedDefaultAudioEndpoint / SetPersistedDefaultAudioEndpoint) in RS4 that let's them 'redirect' apps to different playback devices. Same API used in modern sound settings.
      • Code here with no public API yet?

    Internal Audio Interface: IPolicyConfig

    • Gets them access to SetDefaultEndpoint API; lets us change the default playback device
    • Code here and no public API yet?

    Acrylic Blur (win32)

    From a development/devops perspective, I am told EarTrumpet's team is able to push a beta flight through the Windows 10 Store in just over 30 minutes. No waiting for days to get beta test data. They use Bugsnag for their generous OSS license to catch crashes and telemetry. So far they're getting >3000 new users a month as the word gets out with nearly 100k users so far! Hopefully +1 as you give EarTrumpet a try yourself!


    Sponsor: Check out dotMemory Unit, a free unit testing framework for fighting all kinds of memory issues in your code. Extend your unit testing with the functionality of a memory profiler.

    About Scott

    Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

    facebook twitter subscribe
    About   Newsletter
    Sponsored By
    Hosting By
    Dedicated Windows Server Hosting by SherWeb

    ASP.NET Core Architect David Fowler's hidden gems in 2.1

    June 11, '18 Comments [11] Posted in ASP.NET | DotNetCore
    Sponsored By

    ASP.NET Architect David FowlerOpen source ASP.NET Core 2.1 is out, and Architect David Fowler took to twitter to share some hidden gems that not everyone knows about. Sure, it's faster, builds faster, runs faster, but there's a number of details and fun advanced techniques that are worth a closer look at.

    .NET Generic Host

    ASP.NET Core introduced a new hosting model. .NET apps configure and launch a host.

    The host is responsible for app startup and lifetime management. The goal of the Generic Host is to decouple the HTTP pipeline from the Web Host API to enable a wider array of host scenarios. Messaging, background tasks, and other non-HTTP workloads based on the Generic Host benefit from cross-cutting capabilities, such as configuration, dependency injection (DI), and logging.

    This means that there's not just a WebHost anymore, there's a Generic Host for non-web-hosting scenarios. You get the same feeling as with ASP.NET Core and all the cool features like DI, logging, and config. The sample code for a Generic Host is up on GitHub.

    IHostedService

    A way to run long running background operations in both the generic host and in your web hosted applications. ASP.NET Core 2.1 added support for a BackgroundService base class that makes it trivial to write a long running async loop. The sample code for a Hosted Service is also up on GitHub.

    Check out a simple Timed Background Task:

    public Task StartAsync(CancellationToken cancellationToken)
    {
    _logger.LogInformation("Timed Background Service is starting.");

    _timer = new Timer(DoWork, null, TimeSpan.Zero,
    TimeSpan.FromSeconds(5));

    return Task.CompletedTask;
    }

    Fun!

    Windows Services on .NET Core

    You can now host ASP.NET Core inside a Windows Service! Lots of people have been asking for this. Again, no need for IIS, and you can host whatever makes you happy. Check out Microsoft.AspNetCore.Hosting.WindowsServices on NuGet and extensive docs on how to host your own ASP.NET Core app without IIS on Windows as a Windows Service.

    public static void Main(string[] args)
    {
    var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
    var pathToContentRoot = Path.GetDirectoryName(pathToExe);

    var host = WebHost.CreateDefaultBuilder(args)
    .UseContentRoot(pathToContentRoot)
    .UseStartup<Startup>()
    .Build();

    host.RunAsService();
    }

    IHostingStartup - Configure IWebHostBuilder with an Assembly Attribute

    Simple and clean with source on GitHub as always.

    [assembly: HostingStartup(typeof(SampleStartups.StartupInjection))]
    

    Shared Source Packages

    This is an interesting one you should definitely take a moment and pay attention to. It's possible to build packages that are used as helpers to share source code. We internally call these "shared source packages." These are used all over ASP.NET Core for things that should be shared BUT shouldn't be public APIs. These get used but won't end up as actual dependencies of your resulting package.

    They are consumed like this in a CSPROJ. Notice the PrivateAssets attribute.

    <PackageReference Include="Microsoft.Extensions.ClosedGenericMatcher.Sources" PrivateAssets="All" Version="" />
    <PackageReference Include="Microsoft.Extensions.ObjectMethodExecutor.Sources" PrivateAssets="All" Version="" />

    ObjectMethodExecutor

    If you ever need to invoke a method on a type via reflection and that method could be async, we have a helper that we use everywhere in the ASP.NET Core code base that is highly optimized and flexible called the ObjectMethodExecutor.

    The team uses this code in MVC to invoke your controller methods. They use this code in SignalR to invoke your hub methods. It handles async and sync methods. It also handles custom awaitables and F# async workflows

    SuppressStatusMessages

    A small and commonly requested one. If you hate the output that dotnet run gives when you host a web application (printing out the binding information) you can use the new SuppressStatusMessages extension method.

    WebHost.CreateDefaultBuilder(args)
    .SuppressStatusMessages(true)
    .UseStartup<Startup>();

    AddOptions

    They made it easier in 2.1 to configure options that require services. Previously, you would have had to create a type that derived from IConfigureOptions<TOptions>, now you can do it all in ConfigureServices via AddOptions<TOptions>

    public void ConfigureServicdes(IServiceCollection services)
    {
    services.AddOptions<MyOptions>()
    .Configure<IHostingEnvironment>((o,env) =>
    {
    o.Path = env.WebRootPath;
    });
    }

    IHttpContext via AddHttpContextAccessor

    You likely shouldn't be digging around for IHttpContext, but lots of folks ask how to get to it and some feel it should be automatic. It's not registered by default since having it has a performance cost. However, in ASP.NET Core 2.1 a PR was put in for an extension method that makes it easy IF you want it.

    services.AddHttpContextAccessor();
    

    So ASP.NET Core 2.1 is out and ready to go

    New features in this release include:

    Check out What's New in ASP.NET Core 2.1 in the ASP.NET Core docs to learn more about these features. For a complete list of all the changes in this release, see the release notes.

    Go give it a try. Follow this QuickStart and you can have a basic Web App up in 10 minutes.


    Sponsor: Check out JetBrains Rider: a cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!

    About Scott

    Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

    facebook twitter subscribe
    About   Newsletter
    Sponsored By
    Hosting By
    Dedicated Windows Server Hosting by SherWeb

    Carriage Returns and Line Feeds will ultimately bite you - Some Git Tips

    June 5, '18 Comments [24] Posted in Linux | Win10
    Sponsored By

    Typewriter by Matunos used under Creative CommonsWhat's a Carriage and why is it Returning? Carriage Return Line Feed WHAT DOES IT ALL MEAN!?!

    The paper on a typewriter rides horizontally on a carriage. The Carriage Return or CR was a non-printable control character that would reset the typewriter to the beginning of the line of text.

    However, a Carriage Return moves the carriage back but doesn't advance the paper by one line. The carriage moves on the X axes...

    And Line Feed or LF is the non-printable control character that turns the Platen (the main rubber cylinder) by one line.

    Hence, Carriage Return and Line Feed. Two actions, and for years, two control characters.

    Every operating system seems to encode an EOL (end of line) differently. Operating systems in the late 70s all used CR LF together literally because they were interfacing with typewriters/printers on the daily.

    Windows uses CRLF because DOS used CRLF because CP/M used CRLF because history.

    Mac OS used CR for years until OS X switched to LF.

    Unix used just a single LF over CRLF and has since the beginning, likely because systems like Multics started using just LF around 1965. Saving a single byte EVERY LINE was a huge deal for both storage and transmission.

    Fast-forward to 2018 and it's maybe time for Windows to also switch to just using LF as the EOL character for Text Files.

    Why? For starters, Microsoft finally updated Notepad to handle text files that use LF.

    BUT

    Would such a change be possible? Likely not, it would break the world. Here's NewLine on .NET Core.

    public static String NewLine {
        get {
            Contract.Ensures(Contract.Result() != null);
    #if !PLATFORM_UNIX
            return "\r\n";
    #else
            return "\n";
    #endif // !PLATFORM_UNIX
        }
    }

    Regardless, if you regularly use Windows and WSL (Linux on Windows) and Linux together, you'll want to be conscious and aware of CRLF and LF.

    I ran into an interesting situation recently. First, let's review what Git does

    You can configure .gitattributes to tell Git how to to treat files, either individually or by extension.

    When

    git config --global core.autocrlf true

    is set, git will automatically convert files quietly so that they are checked out in an OS-specific way. If you're on Linux and checkout, you'll get LF, if you're on Windows you'll get CRLF.

    Viola on Twitter offers an important clarification:

    "gitattributes controls line ending behaviour for a repo, git config (especially with --global) is a per user setting."

    99% of the time system and the options available works great.

    Except when you are sharing file systems between Linux and Windows. I use Windows 10 and Ubuntu (via WSL) and keep stuff in /mnt/c/github.

    However, if I pull from Windows 10 I get CRLF and if I pull from Linux I can LF so then my shell scripts MAY OR MAY NOT WORK while in Ubuntu.

    I've chosen to create a .gitattributes file that set both shell scripts and PowerShell scripts to LF. This way those scripts can be used and shared and RUN between systems.

    *.sh eol=lf
    *.ps1 eol=lf

    You've got lots of choices. Again 99% of the time autocrlf is the right thing.

    From the GitHub docs:

    You'll notice that files are matched--*.c, *.sln, *.png--, separated by a space, then given a setting--text, text eol=crlf, binary. We'll go over some possible settings below.

    • text=auto
      • Git will handle the files in whatever way it thinks is best. This is a good default option.
    • text eol=crlf
      • Git will always convert line endings to CRLF on checkout. You should use this for files that must keep CRLF endings, even on OSX or Linux.
    • text eol=lf
      • Git will always convert line endings to LF on checkout. You should use this for files that must keep LF endings, even on Windows.
    • binary
      • Git will understand that the files specified are not text, and it should not try to change them. The binary setting is also an alias for -text -diff.

    Again, the defaults are probably correct. BUT - if you're doing weird stuff, sharing files or file systems across operating systems then you should be aware.

    Edward Thomson, a co-maintainer of libgit2, has this to say and points us to his blog post on Line Endings.

    I would say this more strongly. Because `core.autocrlf` is configured in a scope that's per-user, but affects the way the whole repository works, `.gitattributes` should _always_ be used.

    If you're having trouble, it's probably line endings. Edward's recommendation is that ALL projects check in a .gitattributes.

    The key to dealing with line endings is to make sure your configuration is committed to the repository, using .gitattributes. For most people, this is as simple as creating a file named .gitattributes at the root of your repository that contains one line:
    * text=auto

    Hope this helps!

    * Typewriter by Matunos used under Creative Commons


    Sponsor: Check out JetBrains Rider: a cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!

    About Scott

    Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

    facebook twitter subscribe
    About   Newsletter
    Sponsored By
    Hosting By
    Dedicated Windows Server Hosting by SherWeb

    Automatically change your Audio Input, Output and Volume per application in Windows 10

    May 31, '18 Comments [16] Posted in Win10
    Sponsored By

    I recently blogged about an amazing little utility called AudioSwitcher that makes it two-clicks easy to switch your audio inputs and outputs. I need to switch audio devices a lot as I'm either watching video, doing a podcast, doing a conference call, playing a game, etc. That's at least three different "scenarios" for my audio setup. I've got 5 inputs and 5 outputs and I've seen PC audiophiles with even more.

    • I set up this AudioSwitcher and figured, cool, solved that silly problem.
    • Then I got "EarTrumpet" - it's an applet that lets you control the volume of classic and modern Windows Apps in one nice UI! Switching, volume, and more. Very "prosumer," which is me, so I dig it.

    A little birdie said that I should also look closer at Windows 10 itself. What? I know this OS like the back of my hand! Nonsense!

    Hit the Start Menu and search for either "Sound Mixer" or "App Volume"

    Sound mixer options

    There's a page that does double duty called App Volume and Device Preferences.

    You can also get to it from the regular Settings | Audio page:

    change the device or app volume

    See where it says "Change the device or app volume?" Ok, now DRINK THIS IN.

    You can set the volume in active apps on an app-by-app basis. Cool. NOT IMPRESSED ARE YOU? Of course not, because while that's a lovely feature it's not the hidden power I'm talking about.

    You can set the Preferred Input and Output device on an App by App Basis.

    App Volume and Device Preferences

    You can set the Preferred Input and Output device on an App by App Basis.

    Read that again. I'll wait.

    Rather than me constantly using the Audio Switcher (lovely as it is) I'll just set my ins and outs for each app.

    The only catch is that this list only shows the apps that are currently using the mic/speaker, so if you want to get a nice setup, you'll want to run apps in order to change the settings for your app.

    • Here I've got the system sounds running through Default (usually the main speakers and the default mic is a webcam)
    • The Speech Runtime (I use WIN+H to use Windows 10 built-in Dragon-Naturally-Style-But-Not free dictation in any app) uses the Webcam mic explicitly as it has the best recognition in my experience.
    • Skype for Business is now using the phone. You can certainly set these things in the apps themselves, but in my experience Skype for Business doesn't care about your feelings or your audio settings. ;)
    • I record my podcast with Zencastr so I've setup Chrome for my preferred/optimal settings.

    I can still use the AudioSwitcher but now my defaults are contextual so I'm switching a LOT LESS.

    Be sure to pick up "EarTrumpet" for even more advanced options!

    What do you think? Did YOU know this existed?


    Sponsor: Learn how .NET in 2018 addresses the challenges developers are working on with future-focused technology. Get the new whitepaper on "The State of .NET in 2018" by the Progress Telerik team!

    About Scott

    Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

    facebook twitter subscribe
    About   Newsletter
    Sponsored By
    Hosting By
    Dedicated Windows Server Hosting by SherWeb

    Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.