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
- first install nginx and setting up server block using this link (server block: vm2.arzval.com)
- on the next step Secure Nginx with Let's Encrypt using this link and install ssl on my domain (vm2.arzval.com)
- next install aspnetcore-runtime-6.0 on my VM
- 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