Deploying a Speckle server using Aspire and YARP

I am trying to configure a local deployment of Speckle and all of it’s dependencies using .NET Aspire and YARP.
This is my Aspire configuration which is a direct translation of the Docker compose found in the guide.

void DeploySpeckleServer(string version)
{
    var postgresUsername = builder.CreateResourceBuilder(new ParameterResource("username", _ => "speckle", true));
    var postgresPassword = builder.CreateResourceBuilder(new ParameterResource("password", _ => "speckle", true));
    var postgres = builder.AddPostgres("postgres", postgresUsername, postgresPassword, 9302)
        .WithImageTag("14.5-alpine")
        .WithDataVolume("postgres-data");
    var speckleDatabase = postgres.AddDatabase("speckle");

    var redis = builder.AddRedis("redis", 9303)
        .WithImageTag("7-alpine")
        .WithDataVolume("speckle-redis-data");

    var minio = builder.AddContainer("minio", "minio/minio")
        .WithHttpEndpoint(9304, 9000)
        .WithHttpEndpoint(9305, 9001, "console")
        .WithArgs("server", "/data", "--console-address", ":9001")
        .WithVolume("speckle-minio-data", "/data");

    var speckleServer = builder.AddContainer("speckle-server", "speckle/speckle-server")
        .WithImageTag(version)
        .WithReference(speckleDatabase)
        .WithHttpEndpoint(9306, 3000)
        .WithEnvironment("CANONICAL_URL", "http://127.0.0.1:9307")
        .WithEnvironment("SESSION_SECRET", "TODO:ReplaceWithLongString")
        .WithEnvironment("STRATEGY_LOCAL", "true")
        .WithEnvironment("DEBUG", "speckle:*")
        .WithEnvironment("POSTGRES_URL", "host.docker.internal:9302")
        .WithEnvironment("POSTGRES_USER", "speckle")
        .WithEnvironment("POSTGRES_PASSWORD", "speckle")
        .WithEnvironment("POSTGRES_DB", "speckle")
        .WithEnvironment("REDIS_URL", redis.GetEndpoint("tcp"))
        .WithEnvironment("S3_ENDPOINT", minio.GetEndpoint("http"))
        .WithEnvironment("S3_ACCESS_KEY", "minioadmin")
        .WithEnvironment("S3_SECRET_KEY", "minioadmin")
        .WithEnvironment("S3_BUCKET", "speckle-server")
        .WithEnvironment("S3_CREATE_BUCKET", "true")
        .WithEnvironment("FILE_SIZE_LIMIT_MB", "100")
        .WithEnvironment("ENABLE_MP", "true")
        .WithEnvironment("USE_FRONTEND_2", "true")
        .WithEnvironment("FRONTEND_ORIGIN", "http://127.0.0.1:9307");

    builder.AddContainer("speckle-frontend", "speckle/speckle-frontend-2")
        .WithImageTag(version)
        .WithHttpEndpoint(9307, 8080)
        .WithEnvironment("NUXT_PUBLIC_SERVER_NAME", "local")
        .WithEnvironment("NUXT_PUBLIC_API_ORIGIN", "http://127.0.0.1:9306")
        .WithEnvironment("NUXT_PUBLIC_BACKEND_API_ORIGIN", speckleServer.GetEndpoint("http"))
        .WithEnvironment("NUXT_PUBLIC_BASE_URL", "http://127.0.0.1:9306")
        .WithEnvironment("NUXT_PUBLIC_LOG_LEVEL", "warn")
        .WithEnvironment("NUXT_REDIS_URL", redis.GetEndpoint("tcp"));

    builder.AddContainer("speckle-preview-service", "speckle/speckle-preview-service")
        .WithImageTag(version)
        .WithEnvironment("DEBUG", "preview-service:*")
        .WithEnvironment("PG_CONNECTION_STRING", "postgres://speckle:speckle@host.docker.internal:9302/speckle");

    builder.AddContainer("speckle-webhook-service", "speckle/speckle-webhook-service")
        .WithImageTag(version)
        .WithEnvironment("DEBUG", "webhook-service:*")
        .WithEnvironment("PG_CONNECTION_STRING", "postgres://speckle:speckle@host.docker.internal:9302/speckle")
        .WithEnvironment("WAIT_HOSTS", "host.docker.internal:9302");

    builder.AddContainer("speckle-fileimport-service", "speckle/speckle-fileimport-service")
        .WithImageTag(version)
        .WithEnvironment("DEBUG", "fileimport-service:*")
        .WithEnvironment("PG_CONNECTION_STRING", "postgres://speckle:speckle@host.docker.internal:9302/speckle")
        .WithEnvironment("WAIT_HOSTS", "host.docker.internal:9302")
        .WithEnvironment("S3_ENDPOINT", minio.GetEndpoint("http"))
        .WithEnvironment("S3_ACCESS_KEY", "minioadmin")
        .WithEnvironment("S3_SECRET_KEY", "minioadmin")
        .WithEnvironment("S3_BUCKET", "speckle-server")
        .WithEnvironment("SPECKLE_SERVER_URL", speckleServer.GetEndpoint("http"));
}

Then instead of using the Speckle ingress container, I have a gateway that uses YARP configured as follows:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "speckle-server": {
        "ClusterId": "speckle-server",
        "Match": {
          "Path": "/speckle/{path:regex(graphql|explorer|(auth/.*)|(objects/.*)|(preview/.*)|(api/.*)|(static/.*))}/{**catch-all}"
        },
        "Transforms": [
          {
            "PathPattern": "/{path}/{**catch-all}"
          }
        ]
      },
      "speckle-frontend": {
        "ClusterId": "speckle-frontend",
        "Match": {
          "Path": "/speckle/{**catch-all}"
        },
        "Transforms": [
          {
            "PathPattern": "/{**catch-all}"
          }
        ]
      }
      }
    },
    "Clusters": {
      "speckle-server": {
        "Destinations": {
          "destination": {
            "Address": "http://localhost:9306"
          }
        }
      },
      "speckle-frontend": {
        "Destinations": {
          "destination": {
            "Address": "http://localhost:9307"
          }
        }
      }
    }
  }
}

When connecting to http://localhost:9307 directly, I am able to navigate the frontend with no issues but if I connect via the gateway, for example http://localhost:9000/speckle I get redirected to the root with Error 404## Page not found: /speckle.

Is it possible to configure the Speckle frontend to not redirect to the root path?
I tried setting the Nuxt environment variables and FRONTEND_ORIGIN to http://127.0.0.1:9000/speckle but that broke the redirection completely.

P.S.: any plans on creating Aspire nuget component for Speckle? :smile: keep up the great work

Hi @Davide

Welcome to the Speckle community. I’m unfamiliar with either Aspire or YARP so unable to help you with the specific details.

We have designed speckle with the expectation that it will be at the root path, not a sub-path, so placing the frontend at /speckle/* is not a supported behaviour.

If you haven’t seen it already, our nginx configuration for docker-compose deployments might be helpful: speckle-server/utils/docker-compose-ingress/nginx at main · specklesystems/speckle-server · GitHub

Good luck,

Iain

1 Like