I can not understand how to add multiple reverse proxy hosts via API without removing the previous ones

1. Caddy version (caddy version):

v2.4.6

2. How I run Caddy:

a. System environment:

On Ubuntu LXC hosted on my Proxmox VE

b. Command:

Paste command here.

c. Service/unit/compose file:

I dont know where to find this file , Sorry , i am new to the CADDY world.

d. My complete Caddyfile or JSON config:

its empty as I am using api only to configure Caddy

3. The problem I’m having:

I am trying to automate adding multiple reverse proxy host to help me host multiple dynamic servers on my Proxmox VE.
For eg, I made a php web app that i can log on to and create virtual machines by giving them a hostname (that is already forwarded to my caddy server) and after the script is done creating the virtual machine it will via the api add that hostname to my caddy to begin reverse proxying that hostname to that virtual machine to make it accessible from the internet.

I can able to add just one reverse proxy server via api using the following curl :

curl 172.16.199.119:2020/load \
    -X POST \
    -H "Content-Type: application/json" \
    -d @- << EOF
 {
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [
            ":443"
          ],
          "routes": [
            {
              "match": [
                {
                  "host": [
                    "testing.abc.de"
                  ]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "192.168.88.20:80"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "terminal": true
            }
          ]
        }
      }
    }
  }
}
EOF

Here is the real problem :

If a change the IP and hostname in the above curl request, the old one gets replaced, and I know because of the POST method .
I have read on the api docs that i can update certain parts of the config using PUT method but don’t know how !

This is where I need help

Please can i get the exact curl to add and remove another host like test.abc.xyz and reverse proxy it to 192.168.88.20:80 without removing the previous entries.
I am trying to read the docs and unable to understand how to make it work.

4. Error messages and/or full log output:

5. What I already tried:

I have tried the following :

curl 172.16.199.119:2020/config/apps \
    -X PUT \
    -H "Content-Type: application/json" \
    -d @- << EOF
 {  
	"http": {
      "servers": {
        "srv0": {
          "listen": [
            ":443"
          ],
          "routes": [
            {
              "match": [
                {
                  "host": [
                    "test.abc.xyz "
                  ]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "192.168.88.20:80"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "terminal": true
            }
          ]
        }
      }
    }
}
EOF

And i get the this error :

{"error":"[/config/apps] key already exists: apps"}

6. Links to relevant resources:

When you use PUT, you should send just a subset of the config you want to add, with the URL path being the location in the config where you want to insert the new stuff.

So the URL would be /config/apps/http/servers/srv0/routes I think, and the payload would just be the new route you want to insert at the end (i.e. object with matcher and handler).

This depends how you’re running Caddy, which you haven’t specified. Are you running Caddy as a systemd service? In a Docker container? Standalone with caddy run?

Thank you sir for your msg,
Yes, I am running as a systemd service .

so if understood correct the curl would be :

curl 172.16.199.119:2020/config/apps \
    -X PUT \
    -H "Content-Type: application/json" \
    -d @- << EOF
 {  
	"match": [
                {
                  "host": [
                    "test.abc.xyz "
                  ]
                }
              ],
	"routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "192.168.88.20:80"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
EOF

Not quite, you need to adjust the request URL as well.

ok I tried :slight_smile:

curl 172.16.199.119:2020/config/apps/http/servers/srv0/routes \
    -X PUT \
    -H "Content-Type: application/json" \
    -d @- << EOF
 {  
 "match": [
                {
                  "host": [
                    "testing.vns.ae"
                  ]
                }
              ],
"routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "192.168.88.20:80"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
EOF

In return I got the following error :

{"error":"loading new config: loading http app module: decoding module config: http: json: cannot unmarshal object into Go struct field Server.servers.routes of type caddyhttp.RouteList"}

Ah, right – so if you use PUT, the index at which you want to insert the new route is required (so you would add /1 at the end of the URL to append it), but this requires knowing how many items are already in the array.

If you want to append to the array without knowing how many items already exist, then you can use POST (and don’t specify an index at the end of the path).

See the docs which explain this subtlety:

1 Like

Thank you sir for your quick replies!
adding /1 gives the same error and trying :

curl 172.16.199.119:2020/config/apps/http/servers/srv1/routes \
    -X POST \
    -H "Content-Type: application/json" \
    -d @- << EOF
 {  
 "match": [
                {
                  "host": [
                    "testing.vns.ae"
                  ]
                }
              ],
"routes": [
                    {
                      "handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "192.168.88.20:80"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
EOF

gives the error :

{"error":"loading new config: loading http app module: decoding module config: http: json: unknown field \"routes\""}

I am so lost and started losing hope!

Hurray I have done it via :

curl 172.16.199.119:2020/config/apps/http/servers/srv1/routes/ \
    -X POST \
    -H "Content-Type: application/json" \
    -d @- << EOF
 {  
"match": [
                {
                  "host": [
                    "abc.vns.xyz"
                  ]
                }
              ],
"handle": [
                        {
                          "handler": "reverse_proxy",
                          "upstreams": [
                            {
                              "dial": "172.16.199.105:80"
                            }
                          ]
                        }
                      ]
                   
                }
EOF

Now I am able to change the hostname and IP and keep on adding as many hosts i want via my PHP script!

Thank You Sir @francislavoie without your help I could not have done it!

2 Likes

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