Caddy v2 lb based on $arg_NAME (Nginx)

1. The problem I’m having:

Hello!
Help me please migrate from Nginx to Caddy v2. I have nginx config with few upstreams and Hash load balace policy based on $arg_NAME. How I can do this in Caddy v2? I did’t find example in Docs.

upstream backends {
  hash $arg_NAME consistent;
  server 1.1.1.1:80;
  server 1.1.1.2:80;
}

server {
  listen 80;
  server_name test.example.com;

    location / {
        proxy_pass http://backends ;
        proxy_set_header Connection "upgrade";
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

2. Error messages and/or full log output:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

3. Caddy version:

v2.6.4

4. How I installed and ran Caddy:

a. System environment:

Debian

b. Command:

docker run -ti caddy:2.6.4-alpine sh

c. Service/unit/compose file:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

d. My complete Caddy config:

http://test.example.com {
  reverse_proxy {arg.NAME} 1.1.1.1:80 1.1.1.2:80 {
    lb_policy uri_hash
    header_up Connection Upgrade
    header_up Upgrade websocket
  }
}

5. Links to relevant resources:

Please completely fill out the help topic template. We can’t help you otherwise.

First post updated

I don’t know what $arg_NAME is supposed to be. Where is it getting this value?

I don’t think we have support for arbitrary value’d hashing for load balancing. You can see the policies we have here reverse_proxy (Caddyfile directive) — Caddy Documentation

That placeholder doesn’t make sense there, since it’s not an upstream address.

$arg_NAME, NAME - it’s argument name from uri. Caddy can’t map upstreams based on args?

I still don’t understand what you mean by “args”. That’s vague. How is the URI parsed? Show an example request (i.e. a URI you would receive on your server) and what the “arg” would be in that case.

But yes, the uri_hash policy doesn’t take arguments. It hashes the entire URI and the same URI will reach the same upstream, consistently.

What I need. Web server can accept requests with different path or fragment but with same argument like ?hello=world in uri. All this requests must be forwarded to one backend. In nginx configuration I can set lb policy hash and set var $arg_NAME where NAME is argument name. How I can do set same policy in Caddy?

Ah okay, so you mean by query, not by “args”.

Currently there’s no LB policy by query, but it would be trivial to add one. You’re the first to ask for that.

Second question please. How I can map same query with different arguments like
/qwerty?arg1=asd
/qwerty?arg4=hjjj#frag
to same backend in pool?

I’m not sure that’s possible to predict. Load balancing uses a hashing algorithm given a value. If you provide a different value, there’s no way to predict it’ll end up at the same backend.

Also btw, the URI fragment (i.e. the #frag part) never gets sent to the server. That’s client-side only. It’s impossible to route based on the fragment.

If you want to route specific query params to a specific upstream, you probably want to use the map directive instead:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.