Search code examples
quarkustraefik

serving images (static files) from quarkus is failing on server


I'm using Next.js to submit a form with images to my backend (quarkus; 3.1.2; Kotlin). So far so good. IT WORKS on my machine with with showing the upload images, but on the deployed version it does not work.

I'm using docker and treafik for the deployment. The images are save to attached volume under src/main/resources/META-INF/resources (as mentioned in the following post https://stackoverflow.com/a/73294744/354164)

on localhost http://localhost:8080/api/image-123.png works but on the my deployed version https://domain.de/api/image-123.png does not work.

configured following on in application.properties file:

quarkus.http.root-path=/api
quarkus.http.non-application-root-path=${quarkus.http.root-path}

docker labels in treafik:

backend:
...
  treafik: 
      "traefik.http.routers.server.entrypoints": "websecure"
      "traefik.http.routers.server.rule": "Host(`domain`) && PathPrefix(`/api`)"

all other calls to the backend like getting the data or submitting the form (post) works without an issue.


Solution

  • META-INF/resources is used to serve static resources coming from the jar. You may not add new resources there.

    To serve static resources, you should add a specific Vert.x Web route to serve the files from a given directory. In the example above, I serve resources from the static/ directory on the static/ path, e.g. static/image3.png will be served on http://localhost:8080/static/image3.png.

    Note that in the example, we are serving files from a directory relative to where you started the app, this is recommended. By adjusting the option of StaticHandler.create(), you can serve files from an absolute path but that's definitely not something we recommend as it could cause security issues.

    You can inject @ConfigProperty properties there if you want the paths to be configurable.

    package org.acme;
    
    import io.quarkus.runtime.StartupEvent;
    import io.vertx.core.http.HttpMethod;
    import io.vertx.ext.web.Router;
    import io.vertx.ext.web.handler.StaticHandler;
    import jakarta.enterprise.event.Observes;
    
    
    public class StaticResources {
    
        void installRoute(@Observes StartupEvent startupEvent, Router router) {
            router.route()
                    .method(HttpMethod.GET).method(HttpMethod.HEAD)
                    .path("/static/*")
                    .handler(StaticHandler.create("static/"));
        }
    }
    

    Thanks for asking this question, I will improve our documentation.