envoyproxy/envoy

Ability to serve static files

garrettheel opened this issue ยท 18 comments

It would be great to have the ability to serve static files from Envoy.

My use-case is to serve static files for an HTML frontend (HTML, JS, CSS, etc.), which should be a fairly common one. Right now you would have to put something like nginx in the middle to efficiently do this.

@garrettheel would this end up turning Envoy into full fledged web server? Because, we would now have to take care of file encodings, gzip stuff, cache headers, and so on. Just afraid of code complexity/bloat.

This would only ever be added as a standalone filter, but overall I agree with @rshriram that we are unlikely to add this into the core server. But will leave open just for tracking purposes.

bgaff commented

Why not add fastcgi as a filter? Seems like a win-win.

@mattklein123, what I was hoping for was a way to serve static files on certain non-2xx responses, such as a 500 or 403. So rather than returning the envoy default msg, it could return a file.

something along the lines of haproxy's errorfile 403 /etc/haproxy/403.json HAProxy loads these up in memory at startup (at least they did in 1.6).

is something like that doable?

[edit]: add haproxy note

@skippy it's definitely doable and I'm not opposed, but someone would need to do a proper design and implement.

@mattklein123 if you are ok with it, I'll make a separate issue to design and track static files for error handling... that is a much more specific use-case than general static files (I agree with your comments on that score).

but in the meanwhile, time to dust off haproxy so I can serve error files :)

if you are ok with it, I'll make a separate issue to design and track static files for error handling

sure sounds good

Is this still being done? If it isnt is there an example of how I can serve static files from an upstream?

htuch commented

@weilip1803 you can do basic file serving with https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route.proto#route-directresponseaction. This is not a full fledged web server. I think this thread captures current status, which is "help wanted".

I found this from an (older?) Envoy docs page. Is this module still maintained? https://jteso.github.io/envoy/documentation/site/modules/static/

Was this functionality implemented or it is still work in progress ? Thanks!

So has Envoy supported this function?

There's an additional feature in the work to provide custom error response based on if the upstream request errored: #21441

investigating nginx alternatives. Envoy looks promising but really surprised to find it can't serve static content. shame.

EDIT: not sure why people find this confusing. am i missing something?

@Spongman give a try to caddy instead

@Spongman

I used below configuration to get local static page directly

# cat envoy-demo-static.yaml
static_resources:

  listeners:
  - name: listener_0
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          access_log:
          - name: envoy.access_loggers.stdout
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                direct_response:
                  status: 200
                  body:
                    filename: "/etc/envoy/hello-envoy.html"

And start a container with above configuration

docker run -v /tmp/envoy-demo-static.yaml:/etc/envoy/envoy.yaml \
-v /tmp/hello-envoy.html:/etc/envoy/hello-envoy.html \
-d  --name envoy-static-container -p 9901:9901 -p 10000:10000 \
envoyproxy/envoy:v1.27-latest  -c /etc/envoy/envoy.yaml

(hello-envoy.html is a very simple static file)

You can also add Content-Type to response header with value text/html to be parsed as an html file in your browser.

sample config:

...
route_config:
  name: local_name: local_route
  virtual_hosts:
  - name: local_service
    domains: ["*"]
    routes:
    - match:
        prefix: "/"
      direct_response:
        status: 200
        body:
          filename: "/etc/envoy/hello-envoy.html"
    response_headers_to_add:
        - header:
              key: "Content-Type"
              value: "text/html"
...

We use Istio/envoy for a quite complex K8s system without any need for Nginx. Except, to serve static files. Would be really nice to have one gateway/reverse proxy to rule them all.