I use nginx as a reverse proxy for my Node.js application(s) which is running on localhost:3000. Both nginx itself and my application are two separate docker containers. (Separate because later I plan to add more apps to it.)

In my app container I have some .webp alternative images. E.g.

$ ls
 
/app/assets/img/image.jpeg
/app/assets/img/image.jpeg.webp
/app/assets/img/other.jpeg

I've tried using try_files with nginx but as far as I know this is not possible because try_files doesn't "see" my files inside another docker container unless they share a volume. Which they cant. The App container is built somewhere else with everything inside.

What I have right now it this:

upstream app {
  server localhost:3000;
}

[...]

location ~* .+\.(jpg|jpeg|svg|png)$ {
  proxy_pass http://app$uri$webp_suffix;
}

[...]

location / {
  proxy_pass http://app;
}

This is in fact working. The client requests .jpg image and gets .jpg.webp (because he can handle it). The problem is he always gets .jpg.webp. What I need is some if to check if the requested file is available in my app.

So something similar like this maybe? But this is not working :-(


location ~* .+\.(jpg|jpeg|svg|png)$ {
  if (-f http://app$uri$webp_suffix) {
    proxy_pass http://app$uri$webp_suffix;
  }
  proxy_pass http://app$uri;
}
answer

You cannot implement such remote check in nginx. And even if you could, it would be slow because nginx would need to make two requests to serve one file.

The preferred solution is to either copy / share the assets to a place where nginx can access them.

Another solution is to implement logic in your application, which checks file extensions and serves files accordingly. Then a simple proxy_pass is enough in the front-end nginx.

Third option is to include nginx also in the app container. In this case a simple proxy_pass can be used in the front-end nginx.