Yesterday, Microsoft announced the release of a new open-source project called YARP (Yet Another Reverse Proxy). YARP is a reverse proxy built using .NET and my initial thought was to try it to see how different it is from using Nginx.

I basically copy/pasted the code from the blog announcement, built the app using VS Code, and was able to run it as is.  OK, but what if I wanted to replace Nginx in one of my course's labs? How easy it is to configure the routes compared to Nginx?  What I wanted to achieve is something similar to this image they show in the blog post: a simple reverse proxy with 2 routes pointing to 2 containers.

Here's the Docker Compose file I was using:

version: "3.5"
services: 
  hello1: 
    depends_on: 
      - reverseproxy
    image: "nginxdemos/hello"
    restart: always

  hello2: 
    depends_on: 
      - reverseproxy
    image: "nginxdemos/hello"
    restart: always

  reverseproxy: 
    image: k8sacademy/reverseproxy
    ports: 
      - "80:80"
    restart: always

And the Nginx config file:

worker_processes 1;
events { worker_connections 1024; }
http {
    sendfile on;

    upstream docker-hello1 {
        server hello1:80;
    }

    upstream docker-hello2 {
        server hello2:80;
    }
    
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Host $server_name;
    
    server {
        listen 80;
        server_name   test.com;
 
        location /hello/ {
            proxy_pass         http://docker-hello1;
            proxy_redirect     off;
        }

        location /bonjour/ {
            proxy_pass         http://docker-hello2;
            proxy_redirect     off;
        }
    }
}

Nothing fancy, typing localhost/hello will route the call to container hello1 and localhost/bonjour will route it to hello2.  How hard it is to create these routes using YARP?  Well, it turns out that the syntax is not that different from the Nginx syntax and I was able to find what I was looking for in the documentation. Instead of an upstream, you define a cluster.  I even added a catch-all route, something I did not bother to do using Nginx.

{
  "Logging": {
      "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
      }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
      "Routes": {
          "catchallroute": {
              "ClusterId": "rickrollcluster",
              "Match": {
                  "Path": "{**catch-all}"
              }
          },
          "helloroute": {
            "ClusterId": "hellocluster",
            "Match": {
                "Path": "/hello/"
            }
        },
        "bonjourroute": {
          "ClusterId": "bonjourcluster",
          "Match": {
              "Path": "/bonjour/"
          }
      }

      },
      "Clusters": {
          "hellocluster": {
              "Destinations": {
                  "hello": {
                      "Address": "http://hello1"
                  }
              }
          },
          "bonjourcluster": {
            "Destinations": {
                "bonjour": {
                    "Address": "http://hello2"
                }
            }
        },
        "rickrollcluster": {
          "Destinations": {
              "rickroll": {
                  "Address": "https://youtu.be/dQw4w9WgXcQ"
              }
          }
      }
      }
  }
}

I then added a Dockerfile, built the container, edited the compose file to use the YARP image, and bang! It worked on 1st try. All of that in about 10 minutes!!! 😮

I then checked the size of the images using the proposed focal version and the alpine version of the aspnet 6 runtime:

mcr.microsoft.com/dotnet/aspnet:6.0-focal
mcr.microsoft.com/dotnet/aspnet:6.0-alpine

Turns out that the alpine version is 100MB while the alpine version of Nginx is about 23MB. Not too bad for .NET!

Granted, I only scratched the surface but turns out that replacing Nginx was super easy in this simple scenario. I'll keep an eye on this project for sure.