Reverse Proxy without files

Is it possible to somehow configure Caddy as a Reverse proxy without having the server files in the local server?

Say I have this structure

Internet ↔ Server 1 (Germany) ↔ VPN ↔ Server 2 (France)

And the Server 1 is where the Caddy proxy lives, which forwards traffic to Server 2, but without having the files locally hosted in Server 1.

Is this possible?

What do you mean by “files”? Which files?

Please fill out the help topic template as per the forum rules.

1 Like

I cannot edit the OP

1. The problem I’m having:

Would it be possible to somehow configure Caddy as a Reverse proxy to redirect requests to another server, without having the server files in the local server?

Let’s say I have this following structure

Internet ↔ Server 1 (Germany) ↔ VPN ↔ Server 2 (France)

And the Server 1 is where the Caddy proxy lives, which forwards traffic to Server 2 (PHP-FPM server), but without having the files locally hosted in Server 1 (file_server)

Is this possible?

2. Error messages and/or full log output:

N/A

3. Caddy version:

Docker caddy:latest

4. How I installed and ran Caddy:

Default Docker caddy config
I’m trying to figure out a possible Caddyfile to make this work

a. System environment:

Server 1 (Germany): Docker + Caddy docker image
Server 2 (France): Docker + PHP-FPM docker image

b. Command:

N/A

c. Service/unit/compose file:

N/A

d. My complete Caddy config:

This is what I’m trying to figure out

I don’t understand what you mean by “server files” though. Which files? Your Caddyfile config file? Why would you want that to not be on that server? I don’t get it.

Maybe you misunderstand how a reverse proxy works? All it does is take the incoming HTTP request and make a new HTTP request to the upstream, takes the response and forwards it along to the original client. There’s no files involved for that.

1 Like

One month ago, I was setting this local server with PHP-FPM and Caddy for reverse proxy

This was the config:

root * /srv/
encode gzip zstd
file_server
php_fastcgi unix//run/php/php-fpm.sock {
    root /var/www/html
}

It needed the root directive In the /srv/ directory where I served all the static files.
Without this config the PHP-FPM was not working

If I have to be sincere I still dont fully understand the utility of the rootandfile_server` directives, I have read the docs but I don’t know why I could not simply forward requests as-is to the php-fpm server.

Because this is what I’m trying to achieve now. Having two servers where one server is the Caddy one, the other is the PHP-FPM one, and there is no root or file_server in case its possible this scenario since in the root docs it says:

The root directive is commonly paired with file_server to serve static files and/or with php_fastcgi to serve a PHP site:

That’s because PHP-FPM is purely a processor for PHP scripts. There’s a huge amount of requests you might make to a web server that aren’t PHP requests.

All the static assets, for example, are most likely not PHP. Images, scripts, stylesheets, videos.

Index requests, even. You browse to https://example.com/ - that’s a request to the web root. That’s not nominating any specific PHP script, it could imply /index.php, but it also might not. You browse to https://example.com/foo/bar/ - that implies /foo/bar/index.php but what if there’s not even a /foo/bar/ folder?

Caddy does a lot of work handling all these outliers. It ensures only requests for PHP scripts get sent to PHP-FPM. It cleans up index requests, makes sure valid scripts are processed, returns 404s when they don’t exist, serves static files as required.

The question you’re asking is specifically:

“Can I use Caddy to reverse proxy all requests to a remote FastCGI backend without having website files on the Caddy host?”

The answer is: yes, but for PHP, things are going to be quite broken unless you know exactly what you’re doing - and I can only imagine that if you knew exactly how to do it, you’d probably choose something, anything else as a solution for whatever you’re actually trying to achieve.

You could do it with reverse_proxy, configuring the transport as fastcgi: reverse_proxy (Caddyfile directive) — Caddy Documentation

But the specifics of the implementation would be up to you to solve.

3 Likes

I was writing this before @Whitestrake answered and I forgot to click send :rofl: but anyway:

Okay that’s different than “reverse proxy”, you’re trying to serve PHP. Those are different requirements altogether (though under the hood Caddy’s fastcgi support is implemented as a proxy transport).

Why do you need Caddy to be on a separate server from PHP-FPM? What are you trying to solve with that?

Caddy needs to see the PHP files on disk because it needs to know whether it needs to rewrite the request to /index.php or to serve your static files (CSS/JS/images). Read through php_fastcgi (Caddyfile directive) — Caddy Documentation which explains how it works.

root sets a variable in the request context saying “other things will read files in here”. The file_server directive is what enables serving static files like your CSS/JS/images/etc. The file_server takes the defined root variable then appends the request path to it then tries to find a file there. If it finds one then it serves it. If it doesn’t, it throws a 404.

When you have php_fastcgi, then there’s a try_files test that happens before file_server runs, to basically intercept the 404 case to instead rewrite to /index.php to delegate any unknown request paths to your PHP app to handle instead (for /api/foo/bar or w/e which your PHP app might handle).

3 Likes

Ok, now everything makes sense

So technically, the solution could be, to have simply two Caddy services, one in each server. The first server will forward requests to the second Caddy service as-is and the second server with a Caddy service will work with the local PHP-FPM to serve the PHP files.

So the first server, will not need any static files, it will only be forwarding all the requests to the second Caddy server.

Yep, we see that kind of deployment pretty frequently. The front Caddy is just a regular reverse proxy, the upstream Caddy is for the PHP site.

2 Likes

See Common Caddyfile Patterns — Caddy Documentation for some tips on doing that

3 Likes

I’m going to check if I can make it work, looks pretty straight forward, except for tha part, that this is not internal between both servers (unless I create a tunnel, that I’m considering to simplify things).

Since the server 1 proxy is the one handling the whole connection, I understand that certificates should be handled on server 1 and creating a tunnel between server 1 and server 2, because the transactions between both servers will be probably unencrypted.

On the back, http:// is used to accept HTTP on port 80. The front instance terminates TLS, and the traffic between front and back are on a private network, so there’s no need to re-encrypt it.

Or there is a better way encrypting them again handled by Caddy?

Yeah an SSH tunnel or wireguard between them would be the easiest option to avoid needing to set up mTLS to have HTTPS between them.

mTLS is possible, but it’s a bit of a hassle to set up initially. Here’s a guide for that if you want to give it a shot tho Use Caddy for local HTTPS (TLS) between front-end reverse proxy and LAN hosts

1 Like

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