Create a reverse proxy for two ports

Additionally, thanks for the suggestion, but it is not in php

hmm, now that I think about it, the file_server directive isn’t going to do anything.

can the docker containers reach each other at the IP? try pinging the IP from the caddy docker container.

How would I do that? Dont have tons of experience with the caddy container

If it helps, I previous had it that if you went to subdomain/ with the reverse proxy at 8080, it would redirect to http:ip:5000

you should be able to run a command from the context of the container using docker exec

for example (caddy is the ID of the container for caddy, can find using docker ps`)

> docker exec -it caddy /bin/sh
/srv # ping php-fpm
PING php-fpm (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.083 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.067 ms
^C
--- php-fpm ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.067/0.075/0.083 ms
/srv #

what does php-fpm represent? i did ping subdomain.example/app1 and i got: bad address

that is the hostname for my php server. you should replace it with the ip portion of ip:5000

Ok. ya they both went through. it was very slow and i hit control-c after like 10-15 seconds, but I did see that first line of 56 data bytes for both ports

Can you paste the output?

the ping command will keep going until you stop it, but you should see multiple successful pings if you ran it for 10-15 seconds.

sure. this is after running for about 30 seconds.
PING “ip”:5000 (“ip”): 56 data bytes
^C
— “ip”:5000 ping statistics —
34 packets transmitted, 0 packets received, 100% packet loss

That is showing some kind of networking issue, none of the pings are reaching their destination. What is the IP of the server hosting something on port 5000? You want to ping just the ip, leave out the port (5000) and any quotes. Also I want to make sure you are replacing ip with the ip of the server hosting something on port 5000.

At this point I think you have something wrong with your networking or something wrong with the values you are giving to the caddyfile. Can you send the whole caddyfile (minus any passwords)? It is hard to troubleshoot when you are redacting even internal IPs.

My boss at the moment is not ok with me putting the domain and ip up :frowning: ill post it if he changes his mind. This is copy and paste of caddy file currently running, with dummy ip obvs.

domain

handle /server/* {
    reverse_proxy 123.123.123.123:8080
}

handle /ui/* {
    reverse_proxy 123.123.123.123:5000
}

Ill believe it is an issue with what is being given to the caddy file, being that

domain

reverse_proxy 123.123.123.123:8080

works just fine.

I think you’re looking for the handle_path, which is the same as handle, but it also does a rewrite to strip the specified prefix from the URL before proxying. This is important, because Caddy preserves the request path when proxying. This is different than the default behaviour of nginx. handle_path is what solves that.

domain

handle_path /api1/* {
	reverse_proxy ipaddress:8080
}

handle_path /api2/* {
	reverse_proxy ipaddress:5000
}

The suggestion of adding the redirect is good as well, i.e. redir /app1 /app1/. This is relevant, because when you use a path matcher like /api1/*, requests to /api1/ and /api1/foo will match, but not /api1. The redirect ensures that if exactly /api1 is requested, it will add the trailing / which would be required to satisfy your path matcher.

You could use a matcher like /api1* to avoid this issue, but it introduces the other issue that that would also match /api1foo which is likely not the intended result.

1 Like

This solution was an improvement, but it did not seal the deal. Occasionally I was able to get through, but I’m still getting this blank white page. It’s very strange. For example, if I go to the /ui route, I see in the network tab in of dev tools the domain/static/ css and js files, which would imply that it is reaching the 5000 port, but the page is just completely white.

current caddy file:

domain

redir /server /server/
handle_path /sever/* {
    reverse_proxy ip:8080
}

redir /ui /ui/
handle_path /ui/* {
    reverse_proxy ip:5000
}

Once again, just having a caddy file with:

domain 

reverse_proxy ip:8080 

works for just one port, so it still implies a syntax error in the caddyfile

When you use a handle or handle_path with a matcher, only requests that match the path will get handled by them. You don’t have anything that handles anything except /ui/* and /sever/* (note your typo!)

I don’t think I understand what your goal is here, so I’m not certain what to suggest. Do you expect any request that isn’t to /ui/* or /server/* to get handled by your service on port 5000 or 8080? Either way, just add a reverse_proxy that is not in a handle to act as a fallback.

When Caddy doesn’t know how to handle a request (i.e. nothing in the configuration tells it what to do with it), it just returns an empty 200 response. This is because it’s technically not an error, Caddy is just following its configuration. It’s up to the user to make sure the config does what they need :smile:

I apologize about the typo. I fixed that, and now when routing to domain/server/, it seems to work a lot better.

However, I am still having issues with the ui route. When I go to http:ip:5000, i get what id expect. When I go to domain/ui, I see: manifest.json:1 Manifest: Line: 1, column: 1, Syntax error. The app running on port 5000 is a docker container running a React Application (with react router). If you think this is causing the issue, or I should be using file-server for that, let me know.

I am also having an issue that if there is every a redirect called on the /server route, it goes back to the / route. So if I have domain/server/route1 that will conclude by redirecting to /route2, it will just redirect to domain/route2. I tried writing in the caddyfile just handle /server (bc of the stuff you mentioned with stripping the prefix), which was not helpful. I tried as a desperate attempt to do redir / /server/, which didn’t solve the issue either.

To clarify my goal, I have one application, the server, running on 8080, and I have the ui running on 5000. I want both of these applications to be under one subdomain.

updated caddy file:

domain

redir /server /server/
handle_path /server/* {
    reverse_proxy ip:8080
}

redir /ui /ui/
handle_path /ui/* {
    reverse_proxy ip:5000
}

I also wanted to say that I am shocked at how fantastic the support has been on this community. I left a question last night with the assumption I’d check it the next day and maybe have an answer. I cannot believe I already have a thread 20 messages long (sorry for my long delay, I’ve gotten maxed out at how many replies a new user can have on their first day :slight_smile: ). Thanks so much!

1 Like

At this point I think you need to update some configuration on your upstream server such that it understands it’s meant to run in a subpath.

Please read this wiki written by @Whitestrake, I think it will illustrate the issues you’re having.

i have the same problem,V2: how can caddyfile reverse_proxy to JSON

i want to proxy filebrowser, in caddyfile of caddy1,the config:
in caddy1, i can do it:

127.0.0.1:2016 {
proxy /filebrowser 127.0.0.1:8080
}
it works well,
but i want to use filebrowser in caddy2
in caddy2 json config file,
{
“handler”: “reverse_proxy”,
“transport”: {
“protocol”: “http”,
“read_buffer_size”: 4096
},
“upstreams”: [
{
“dial”: “127.0.0.1:8080”
}
]
}
proxy / to 127.0.0.1:8080. it work well
but i want to proxy /filebrowser to 127.0.0.1:8080
i search all Internet, but do not find the example of json file
i get a response,
“The easiest thing to do if when learning to write JSON configs with Caddy is to write what you want as a v2 Caddyfile then adapt it to JSON with the caddy adapt command.
In Caddy v2, it would look like either of these, depending on whether your upstream service expects the subpath to be stripped or not.

in caddyfile:
handle /filebrowser {
reverse_proxy 127.0.0.1:8080
}

i use 'caddy adapt ’ to json, and copy to .json file
but it dont work

@Schr0dingerCat in Caddy v2, path matching is exact-match. This means that your matcher /filebrowser only matches exactly /filebrowser and nothing else. You need to append a * to tell Caddy that you want to match anything that begins with /filebrowser.

This is probably all you need:

127.0.0.1:2016 {
	reverse_proxy /filebrowser* 127.0.0.1:8080
}

Also, please don’t forget to use ``` on the lines before and after your config/code to use code block formatting (preserves whitespace, uses a monospaced font) next time you comment on the forums, it’s hard to read your post when it doesn’t use proper formatting.

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