basecamp / thruster

MIT License
672 stars 16 forks source link

Gzipping does not seem to work #19

Closed morgoth closed 1 month ago

morgoth commented 2 months ago

I deployed the Rails app using kamal and thruster (bundle exec thrust .bin/rails s).

The request from browser comes through AWS EBL and then to AWS EC2 instance (regular kamal with traefic on front).

If I understand correctly the feature "compression, to efficiently serve static files", I would expect to have js/css files served as gzipped in the browser, thus with header Content-Encoding: gzip, but they are not having it.

Not sure if I need to setup something extra on my infra or should it work out of the box with such setup.

Do you have any clue how I can debug it further?

3v0k4 commented 2 months ago

Please take what follows with a grain of salt as I'm not the author. Just trying to help 🙂

You are using sendfile, correct?

If you enable debug logs, you should see something like "X-Sendfile sending file", "path", filename to confirm sendfile is taking over serving the assets.

Notice that in this case, Rails should have preprocessed the file when precompiling assets. Thruster is just serving it.

Probably, this does not apply to you, but there was a bug in an older version of Thruster: https://github.com/basecamp/thruster/issues/6.

If you are not using sendfile, gzip is always on for all requests.

The library Thruster uses for gzipping does not gzip files below 1024 bytes and filters out already compressed types. Also:

Ranged requests are not well supported with compression. Therefore any request with a "Content-Range" header is not compressed.

Does any apply to your case?

What about localhost? Does Thruster behave as you expect locally? Did you isolate the issue to the AWS environment?

If you can share repro steps to run locally, I'd be happy to take a look.

morgoth commented 2 months ago

Thank you for response.

I didn't tweak thruster defaults, so sendfile should be enabled, yes. I'm using propshaft which does not generate gzipped assets, but only adds a revision to the asset file.

I tried running thrust bin/rails s locally with X_SENDFILE_ENABLED=0 but I don't see any difference. I have files bigger than 1024 bytes, so the gzipping should be triggered I believe.

Locally I also don't see the gzipping working at all.

The local repro would be:

rails new --asset-pipeline=propshaft gzipdebug
cd gzipdebug
bundle add thruster
bin/rails s g scaffold users name
DEBUG=1 thrust bin/rails s
# Visit localhost:3000/users

Then you can open developer console - there are js files (like turbo) that are not gzipped

3v0k4 commented 2 months ago

I think the issue is that you are using localhost:3000, which is puma. You should instead use the port that thruster exposes, which is controlled by HTTP_PORT and defaults to 80.

Locally you can:

HTTP_PORT=8080 DEBUG=1 thrust bin/rails s
open http://localhost:8080 # not :3000
morgoth commented 2 months ago

Yes, now I see it is gzipped locally. Thank you. So the question is how to debug it on the server...

3v0k4 commented 2 months ago

My recommendation would be to make sure the server is forwarding to thruster rather than puma and to look at the debug logs by using DEBUG=1 there too.

morgoth commented 1 month ago

The think that I missed, was exposing port 80 instead of 3000 in the Dockerfile. Found out by https://github.com/rails/rails/pull/51793/files#diff-eadf4526a334fb54e822c9880879c7f8989f4fb7b7225d4e088eb463b2df820fR118

The gzipping works fine now. Thank you for your help @3v0k4