Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] How to connect Orleans Client to Orleans Server in Docker? #8985

Open
NikHusachenko opened this issue May 8, 2024 · 2 comments
Open

Comments

@NikHusachenko
Copy link

I try to deploy Silo client and silo server on Docker via docker-compose, but I get error that silo client cannot connect to other container on port 30000. I set upped containers for talking, and I can send simple http request from first project to second and get response. But I can't run project using Orleans. This is code for client:

var builder = WebApplication.CreateBuilder(args);
builder.Host
    .UseOrleansClient(client =>
    {
        client
            .UseLocalhostClustering(30000)
            .Configure<ClusterOptions>(options =>
            {
                options.ClusterId = "<Dev>";
                options.ServiceId = "<Quiz>";
            })
            .Configure<EndpointOptions>(options =>
            {
                options.AdvertisedIPAddress = IPAddress.IPv6Loopback;
                options.GatewayPort = 30_000;
                options.SiloPort = 11_111;
            });
    })
    .ConfigureLogging(logging => logging.AddConsole());

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

Server code:

var builder = WebApplication.CreateBuilder(args);
builder.Host
    .UseOrleans(siloBuilder =>
    {
        siloBuilder
            .UseLocalhostClustering(30000)
            .AddMemoryGrainStorage("<DevStore>")
            .Configure<ClusterOptions>(options =>
            {
                options.ClusterId = "<Dev>";
                options.ServiceId = "<Quiz>";
            })
            .Configure<EndpointOptions>(options => options.AdvertisedIPAddress = IPAddress.Loopback)
            .Configure<EndpointOptions>(options =>
            {
                options.SiloListeningEndpoint = new IPEndPoint(IPAddress.Loopback, 11111);
                options.GatewayListeningEndpoint = new IPEndPoint(IPAddress.Loopback, 30000);
                options.AdvertisedIPAddress = IPAddress.Loopback;
                options.SiloPort = 11_111;
                options.GatewayPort = 30_000;
            });
    })
    .ConfigureLogging(logging => logging.AddConsole());

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

In the future I have to use UseRedisClustering instead a UseLocalhostClustering. This project successfully run in local PC, but in Docker I get exception ''Connection attempt to endpoint S127.0.0.1:30000:0 failed". This is Dockerfile.silo for server project:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base

WORKDIR /app
EXPOSE 5034
EXPOSE 11111
EXPOSE 30000

# ...

ENTRYPOINT ["dotnet", "DockerSilo.Orleans.dll", "--urls", "http://*:5034" ]

And Dockerfile for client project:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base

WORKDIR /app
EXPOSE 5131

# ...

ENTRYPOINT ["dotnet", "DockerSilo.Api.dll", "--urls", "http://*:5131"]

And docker-compose:

services:
  redis:
    image: redis
    ports:
      - 6379:6379

  api:
    build: 
      context: .
      dockerfile: Dockerfile.web
    ports:
      - 5131:5131
    networks:
      - siloNet

  silo:
    build: 
      context: .
      dockerfile: Dockerfile.silo
    ports:
      - 5034:5034
      - 11111:11111
      - 30000:30000
    networks:
      - siloNet

networks:
  siloNet:
    driver: bridge

As you are seen, all parts configured well, but I don't know why this doesn't work. Please, help me resolve this problem, because I did 250 container builds tries for last two days and can't solve this alone

@MickaelThumerel
Copy link

UseLocalhostClustering Is made to connect on same computer one silo and one client for dev purpose.
Orleans is not designed to pass in direct connection though part (client, silo, ...) except in specific local condition (For dev).

With the docker compose you create a virtual network where every container have a virtual IP in it like theire was on separate computer.

You can:

  1. Orlean Way: Use a db image and the nuget package associate to provide a meeting point

  2. You can change to gateway to redirect docker localhost to the computer one instead on the docker one. It will by pass the docker virtual network for localhost connection.

    • with extraHost host.docker.internal:host-gateway
    • Replace IPAddress.Loopback by "host.docker.internal"

Attention: Solution 2 will only work with One silo.

Orleans is designed to use a DB a meeting point for cluster nodes (Silo) and/or clients. Through docker it's easy to have one.
PS: Sometime the client close because it can connect to any silo. I advise you to delay the client start to prevent it

@cameliaonu
Copy link

@MickaelThumerel

The host.docker.internal should be mentioned in the Orleans-Server? I am using UseDevelopmentClustering for the server? Should I mention host.docker.internal for the PrimarySiloEndpoint, insteand of IPAddress.Loopback or IPAddress.Any?

  • What about the AdvertisedIPAddress should be set?

This host.docker.internal:host-gateway should be mentioned in the docker-compose, for the server container?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants