polypush135

polypush135

The hard 3 day lesson I learned trying to use http2 with Phoenix, Cowboy and Nginx

So I’ve been banging my head to the wall trying to figure out why my upstream was not being handled by phoenix.

I first checked my nginx configs.
Upstream set to right host and post of 4000 :white_check_mark:
Proxy headers all set :white_check_mark:
Cert via lets encrypt :white_check_mark:
Phoenix app confirmed running via logs and curl on localhost:4000 on server :white_check_mark::white_check_mark::white_check_mark::white_check_mark:
Http2 request coming in on 443 proxy up to phoenix :fire::fire::fire::fire::fire::fire::fire::fire::fire::fire::fire::fire::fire:

So something got me thinking, does this request fall back to http1.1 if htt2 does not work?
That lead me to look into the qa section of nginx where I found this little nugget.

Q&A
Q: Will you support HTTP/2 on the upstream side as well, or only support HTTP/2 on the client side?
A: At the moment, we only support HTTP/2 on the client side. You can’t configure HTTP/2 with proxy_pass. [Editor – In the original version of this post, this sentence was incorrectly transcribed as “You can configure HTTP/2 with proxy_pass.” We apologize for any confusion this may have caused.]

I maybe reading this wrong, but if I’m correct this is saying you can’t using http2 requests with upstreaming your request via proxy.

I than cut out my nginx stack from my app and ran cowboy as my primary http server and all is working fine now. In the end the only indiction my request even hit my server was in my nginx error logs where it simply said

upstream prematurely closed connection while reading response header from upstream

:poop:

well any how I thought I would share my lesson in hopes it saves someone else a few days of their life

Most Liked

alexgaribay

alexgaribay

Phoenix Core Team

I actually ran in to this issue recently without knowing that it wouldn’t work. I decided to drop Nginx completely and let Phoenix handle the certs and http/2 requests. I wrote about the steps I need to do to make that transition.
https://blog.progressplum.app/ssl-migration-from-nginx-to-cowboy-2-in-phoenix-1-4/

Gazler

Gazler

Phoenix Core Team

It is worth noting that this is the same with Application Load Balancers when using AWS Listeners for your Application Load Balancers - Elastic Load Balancing

Application Load Balancers provide native support for HTTP/2 with HTTPS listeners. You can send up to 128 requests in parallel using one HTTP/2 connection. The load balancer converts these to individual HTTP/1.1 requests and distributes them across the healthy targets in the target group. Because HTTP/2 uses front-end connections more efficiently, you might notice fewer connections between clients and the load balancer. You can’t use the server-push feature of HTTP/2.

yurko

yurko

Those “subtle” things that may just cause a lot of debugging fun is the reason I try to avoid any moving parts that are not absolutely necessary (not using nginx with phoenix for this reason). Thanks for sharing!

Last Post!

polypush135

polypush135

So something I didn’t understand right away was that I don’t need to have encryption between the reverse proxy an elixir. Even though the upstream proxy is talking with elixir (cowboy) via http1.1 nginx is still returning h2

So in the end it still works to have nginx running in front of your app.

Where Next?

Popular in Discussions Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54921 245
New
AstonJ
I’ve just started the Phoenix part of the utterly brilliant online course by @pragdave. On generating the Phoenix app he uses the --no-ec...
New
chulkilee
Here are the list of HTTP client libraries/wrappers, and some thoughts on HTTP client in general. I’d like to hear from others how they w...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 40042 209
New
eteeselink
Hi all, In the last days, two things happened: A blog post titled “They might never tell you it’s broken” made the rounds. It’s about ...
New
RudManusachi
What configs will make sense to put to runtime.exs? – A bit of how I configure apps: I have generic configs in config/config.exs, dev...
New
AstonJ
Can you believe the first professionally published Elixir book was published just 8 years ago? Since then I think we’ve seen more books f...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54006 488
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New

We're in Beta

About us Mission Statement