Home > Software engineering >  Host ASP.NET Core grpc service on Linux with Nginx
Host ASP.NET Core grpc service on Linux with Nginx

Time:10-15

I'm trying to host my asp.net core (.NET 6.0) grpc service on linux (ubuntu 20.04) with nginx. I Managed to make the hosting work with below steps

  1. first install nginx and setting up server block using this link (server block: vm2.arzval.com)
  2. on the next step Secure Nginx with Let's Encrypt using this link and install ssl on my domain (vm2.arzval.com)
  3. next install aspnetcore-runtime-6.0 on my VM
  4. finally paste my published files to VM and using this link to config nginx to support grpc and HHTP/2 protocol

Apparently, everything is right but when I using a sample clint(.net 6 console app) project to connect my grpc server The following error occurs

Status(StatusCode="Unavailable", Detail="Bad gRPC response. HTTP status code: 502")

here is my sample that on the third line throw an Exception.

using var channel = GrpcChannel.ForAddress("https://vm2.arzval.com");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
                   new HelloRequest { Name = "GreeterClient" });

here is my csproj server file

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" />
  </ItemGroup>

</Project>

appsetting.json file content

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "Endpoints": {
      "Grpc": {
        "Url": "https://localhost:5001",
        "Protocols": "Http2"
      }
    }
  }
}

program.cs

using GrpcService.Services;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using System.Net.Security;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(options =>
{
    // gRPC
    options.ListenAnyIP(5001, o => o.Protocols = HttpProtocols.Http2);
});
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682

// Add services to the container.
builder.Services.AddGrpc();

var app = builder.Build();

if (app.Environment.IsProduction())
{
    app.UseHttpsRedirection();
}
// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");

app.Run();

here is my nginx server block config file

server {

        root /var/www/vm2.arzval.com/html;

        server_name vm2.arzval.com;

        location /greet.Greeter {
            grpc_pass grpc://127.0.0.1:5001;
        }

    listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
    listen 443 ssl http2; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/vm2.arzval.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/vm2.arzval.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = vm2.arzval.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name vm2.arzval.com;
    return 404; # managed by Certbot


}

I have no idea where my mistake is Any suggestion about how to solve this error? Thanks in advance.

CodePudding user response:

Update nginx server block config

server {
    
           root /var/www/vm2.arzval.com/html;
    
            server_name vm2.arzval.com;
    
            location / {
               proxy_pass         http://dotnetapi;
               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;
               proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
               proxy_set_header   X-Forwarded-Proto $scheme;
            }
            location /greet.Greeter {
                grpc_pass              grpc://dotnetgrpc;
            }
    
    
        listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
        listen 443 ssl http2; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/vm2.arzval.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/vm2.arzval.com/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    
    }
    server {
        if ($host = vm2.arzval.com) {
            return 301 https://$host$request_uri;
        } # managed by Certbot
    
    
            listen 80;
            listen [::]:80;
    
            server_name vm2.arzval.com;
        return 404; # managed by Certbot
    
    
    }
    upstream dotnetapi {
        zone dotnet 64k;
        server 127.0.0.1:5000;
    }
    upstream dotnetgrpc {
        zone dotnet 64k;
        server 127.0.0.1:7332;
    }

appsetting.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "Endpoints": {
      "http": {
        "Url": "http://localhost:5000",
        "Protocols": "Http1AndHttp2"
      },
      "Grpc": {
        "Url": "http://localhost:7332",
        "Protocols": "Http2"
      }
    }
  }
}

Program.cs

using GrpcService.Services;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using System.Net.Security;

var builder = WebApplication.CreateBuilder(args);
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682

// Add services to the container.
builder.Services.AddGrpc();
builder.Services.AddControllers();

var app = builder.Build();

if (app.Environment.IsProduction())
{
    app.UseHttpsRedirection();
}
// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapControllers();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");

app.Run();

and everything must be fixed

  • Related