Wednesday, November 25, 2020

Setting up SSH on a Custom Linux Docker Container

I had some Azure App Services for Containers and when I wanted to SSH, it was giving this annoying error: SSH CONNECTION CLOSE - Error: connect ECONNREFUSED <ipaddress>:2222.

SSH CONNECTION CLOSE - Error: connect ECONNREFUSED

In this post let's see how we can set up SSH on a Custom Linux Docker Container and get past this error. It's actually pretty easy, there is official documentation: Configure SSH in a custom container. I feel it's not that intuitive, hence this post.

First, you need to install openssh-server inside your docker image, I happen to be using aspnet:3.1-buster-slim as the base in my case. It shouldn't matter.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base

RUN apt-get update -y \
    && apt-get install -y --no-install-recommends openssh-server 
Now you need to set a password for the root account.
RUN mkdir -p /run/sshd && echo "root:Docker!" | chpasswd
Then you need to add this sshd_config file inside /etc/ssh in the image.
# This is ssh server systemwide configuration file.
#
# /etc/sshd_config

Port                 2222
ListenAddress  0.0.0.0
LoginGraceTime  180
X11Forwarding  yes
Ciphers aes128-cbc,3des-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr
MACs hmac-sha1,hmac-sha1-96
StrictModes  yes
SyslogFacility  DAEMON
PasswordAuthentication  yes
PermitEmptyPasswords  no
PermitRootLogin  yes
Subsystem sftp internal-sftp

You can copy the file as below,
COPY sshd_config /etc/ssh/
In sshd_config, SSH port is 2222, so we need to expose it.
EXPOSE 2222
We are almost there now. The final step is to start the SSH server (here, I am just running 2 commands, in my case I needed to run a .NET application as well).
ENTRYPOINT ["/bin/bash""-c""/usr/sbin/sshd && dotnet SomeApplication.dll"]
And now when this container is running, you should be able to SSH into it.
SSH

SSH Connection Established
Hope this helps.

Happy Coding.

Regards,
Jaliya

Tuesday, November 24, 2020

Azure Static Web Apps with Blazor

In this post let's see what Azure Static Web Apps are and how we can easily set up an Azure Static Web App using Blazor. 

Azure Static Web Apps is a service that automatically builds and deploys full-stack web apps to Azure from a GitHub repository. As of today I am writing this post, it's still in its Preview stage and is completely free to try out. 

One of the nicest things about Static Web Apps is, static assets are separated from a traditional web server and are instead served from points geographically distributed around the world. And this makes serving files much faster as files are physically closer to end-users. In addition, API endpoints are hosted using a serverless architecture, which avoids the need for a full back-end server altogether. 

And Blazor WebAssembly Apps makes a nice fit for Azure Static Web Apps.

Now let's see how we can easily create an Azure Static Web App with Blazor powered with Azure Functions Backend API.

First I am creating a Blazor Web Assembly app.
Blazor WebAssembly App
Once the project is created, I am adding an Azure Functions App to the the project with a simple HTTP Trigger function (nothing fancy here)
public static class WeatherForecastFunction
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing""Bracing""Chilly""Cool""Mild""Warm""Balmy""Hot""Sweltering""Scorching"
    };
    [FunctionName("WeatherForecast")]
    public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest request)
    {
        var rng = new Random();
        return await Task.FromResult(new OkObjectResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray()));
    }
}
Next, in the Blazor Project, I am changing the default the code in FetchData page to call this function instead of loading from a sample JSON file.

Then I am chaning the Program.cs to setup the HttpClient to pick its' BaseAddress from app settings for local development. So I can run the app locally and make sure all works.
public class Program
{
    public static async Task Main(string[] args)
    {
        var builder = WebAssemblyHostBuilder.CreateDefault(args);
        builder.RootComponents.Add<App>("#app");
        var baseAddress = builder.Configuration["ApiUrl"] ?? builder.HostEnvironment.BaseAddress;
        builder.Services.AddScoped(sp => new HttpClient
        {
            BaseAddress = new Uri(baseAddress)
        });
        await builder.Build().RunAsync();
    }
}
And for local app settings, I have set the local ApiUrl.
{
  "ApiUrl""http://localhost:7071"
}
Now I am all set. This is how my solution looks like.
Solution
I am running both the projects locally to make sure all is good.
Running Locally
That's promising. Now I am pushing the source into a GitHub repo (you can actually avoid all the above and fork this repo: https://github.com/jaliyaudagedara/hello-serverless-blazor)

Now the next step is to create an Azure Static Web App. 

Create a Static Web App
Search for Static Web App and click on Create.
Sign in with GitHub
       Here I have given some name. Then I need to Sign in with GitHub to chose the Repo.
Static Web App Setup
Here I have selected my repo and then under Build Presets, I have selected Blazor. There you can see is a nice list of supported presets, some I actually haven't even heard before.

 Build Presets
Then you need to select the App location. This is the location of our Blazor Application. For the Api location,  we have a function app, so I have specified the Azure Function location. Once you specify all, it will create a GitHub actions workflow file that you can preview(it's read-only). And then we can click on Create.

Once we clicked on Create, Azure will commit the workflow file to our repo and the workflow will get triggered. It will basically build and deploy the code to the Static Web App we just created.
GitHub Workflow
Once the workflow is completed, I can try navigating to the Static Web App. It's running and just had a look at Fetch data page, and yes, it's calling our API and displaying data.

Hope this helps.

Happy Coding.

Regards,
Jaliya

Thursday, November 12, 2020

C# 9.0: Target-typed new expressions

C# 9.0 is finally here along with .NET 5. Happy times.

In this post, let's have a look at a small but nice feature which can make some part of our code looks much nicer. 

In C#, all this time when you are using new expression, you needed to specify the type (which type you are going to be newing on) except when newing an array.  

// Type is required when newing
var person = new Person("John""Doe");
var fruits = new List<string>() { "Apple""Orange" };

// Except this one
int[] arrray = new[] { 1, 2, 3 };

With C# 9.0, you can do something like this.

Person person = new ("John""Doe");

List<string> fruits = new() { "Apple""Orange" };

Now instead of using implicit type on the left-hand side, we can be specific by putting the explicit type and then on the right-hand side when we are newing, we can omit the type. Because the compiler knows what type of object we are going to create based on the left-hand side.

It's really becoming handy when it comes to a more complex collection initializer. Consider the below Dictionary initializer.

var keyValuePairs = new Dictionary<intPerson>()
{     { 1, new Person("John""Doe") },
    { 2, new Person("Jane""Doe") }
};

With Target-typed new expressions,

Dictionary<intPerson> keyValuePairs = new ()
{
    { 1, new ("John""Doe") },
    { 2, new ("Jane""Doe") }
};

Isn't it pretty neat?

Happy Coding.

Regards,
Jaliya