gjaldon / heroku-buildpack-phoenix-static

A Heroku buildpack for building Phoenix's static assets
MIT License
230 stars 224 forks source link

Sometimes problem binding to Heroku's port #23

Closed Trevoke closed 8 years ago

Trevoke commented 8 years ago

I ran into Heroku's R10 error twice; once deleting the heroku instance and recreating it fixed it, the second time I was able to fix it by deleting the buildpacks, reinstalling them, and pushing an empty commit.

https://stackoverflow.com/questions/36229118/phoenix-on-heroku-error-r10

I don't know if this buildpack is the root of the problem, but it was part of the fix process both times; I'm hoping that you have enough knowledge to point me in the right direction so I can help make sure this gets fixed for everyone.

gjaldon commented 8 years ago

@Trevoke have you tried adding the PORT var to config_vars_to_export in your phoenix_static_buildpack.config? Something like:

config_vars_to_export=(DATABASE_URL PORT)
Trevoke commented 8 years ago

I didn't know this was something I could or should do. I'll try it now.

I'm also a bit unsure of how to check and see if this fixes the problem other than deploying a lot and maybe changing MIX_ENV ... Any ideas?

Trevoke commented 8 years ago

Cursory examination seems to indicate that fixes it. I don't know how to make a deeper examination. I can open a PR with that change, if you want?

gjaldon commented 8 years ago

As long as the PORT env variable is recognized in your Phoenix app, then we know it's working. :) This has to be done for every ENV var we want to set in Heroku and be recognized in our buildpack.

What change would you be adding for the PR? I think what's needed is only to make this clear in our README. Feel free to make a PR to point out how to use config_vars_to_export and use that as a sample use case.

ericmj commented 8 years ago

When using Phoenix you don't need to have PORT set at compile time so I think it's another issue. Is the code public so we can take a look at it?

Trevoke commented 8 years ago

Yeah, it's free: https://github.com/Trevoke/great-strides

This commit is the last one where I remember pushing and seeing the issue.

It's worth noting that, concurrent to that, I was trying to make ueberauth work and was missing hackney, for some reason. I don't think it's related, though.

What I did do was try to change MIX_ENV. Also, this had happened once before and a stackoverflow answer recommended just destroying/recreating the heroku instance, so I'd done that and forgot to set the secret key env variable -- but I set it and that didn't fix the problem.

What I did see in the logs - a sample is available on this SO question and I'm copying it here for posterity - is that it was trying to bind to port 4000.

2016-03-25T22:22:54.716907+00:00 heroku[web.1]: State changed from crashed to starting

2016-03-25T22:23:03.156662+00:00 heroku[web.1]: Starting process with command mix phoenix.server

2016-03-25T22:23:07.985368+00:00 app[web.1]: [info] Running AppName.Endpoint with Cowboy using http on port 4000

2016-03-25T22:23:10.027386+00:00 app[web.1]: 25 Mar 22:23:10 - info: compiled 5 files into 2 files, copied 3 in 1.5 sec

2016-03-25T22:24:03.442109+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch

2016-03-25T22:24:03.442109+00:00 heroku[web.1]: Stopping process with SIGKILL

2016-03-25T22:24:04.195291+00:00 heroku[web.1]: Process exited with status 137

2016-03-25T22:24:04.211713+00:00 heroku[web.1]: State changed from starting to crashed

ericmj commented 8 years ago

You usually shouldn't change the MIX_ENV. I see in the log you posted that phoenix is running on port 4000, this indicates that you are running in the dev environment. If you change back to prod it should pick up the port from the system environment variable heroku sets.

Trevoke commented 8 years ago

Does this mean that Phoenix in dev environment would use port 4000 over the port set in an environment variable?

ericmj commented 8 years ago

Yes, that's what is configured in your config:

https://github.com/Trevoke/great-strides/blob/master/config/prod.exs#L15 https://github.com/Trevoke/great-strides/blob/master/config/dev.exs#L10

Trevoke commented 8 years ago

Okay, I see.

I went and checked, because it really seemed like I had just made a silly mistake, so I went and make the silly mistake again:

  1. I committed a change removing PORT from the phoenix buildpack config
  2. I made sure I was in MIX_ENV=prod (on Heroku, that's the default)
  3. I pushed. It bound to whatever port Heroku gave it.
  4. I set MIX_ENV=dev ; this restarted Heroku on port 4000.
  5. I unset MIX_ENV ; this restarted Heroku on port 4000
  6. I set MIX_ENV=prod ; this restarted Heroku on port 4000.
Trevoke commented 8 years ago

Additionally, once I set PORT in the phoenix buildpack config, it doesn't matter what my environment is: it properly binds to the port.

ericmj commented 8 years ago

I think something weird is going on because you change MIX_ENV without recompiling your project which is very fragile - it is not supported, it may work or it may not.

Additionally, once I set PORT in the phoenix buildpack config, it doesn't matter what my environment is: it properly binds to the port.

That doesn't make sense because it only changes what variables are exposed when compiling and we don't read the port when compiling. I am guessing it suddenly worked because the project recompiled when you pushed the change.

Trevoke commented 8 years ago

Well, I'm open to making all the changes and tests you like; I can even make you a contributor on the Heroku instance if you want to tinker around yourself.

What I meant was:

  1. I committed the change so I export DATABASE_URL and PORT.
  2. Before pushing to Heroku, I unset MIX_ENV (so, default to prod).
  3. I pushed. It bound properly.
  4. I set MIX_ENV to dev. It restarted and bound properly.
  5. I set MIX_ENV back to prod. It restarted and bound properly.
  6. I unset MIX_ENV. It restarted and bound properly.
ericmj commented 8 years ago

Again, I don't know what's going on but I am fairly certain it's unrelated to config_vars_to_export because Heroku does not even set PORT at compilation.

I set MIX_ENV to dev. It restarted and bound properly.

What do you mean by properly? In dev it should use 4000, it shouldn't use the PORT Heroku sets.

I am not sure if MIX_ENV changes are even picked up without recompiling since both the elixir and phoenix buildpacks set it in the .profile.d file.

Trevoke commented 8 years ago

I mean it restarted and bound to the port provided by Heroku.

ericmj commented 8 years ago

I mean it restarted and bound to the port provided by Heroku.

When MIX_ENV=dev it shouldn't use the port heroku provides. So far everything suggests it works when MIX_ENV is set to prod and that MIX_ENV changes are only picked up when the project is recompiled. if that is true everything is working as intended.

Trevoke commented 8 years ago

What about https://github.com/gjaldon/heroku-buildpack-phoenix-static/issues/23#issuecomment-204200269 when I push a change (prod -> prod) and then change the environment to dev ?

ericmj commented 8 years ago

I don't know, as I said, it's fragile to change MIX_ENV without recompiling and it's not supported.

Trevoke commented 8 years ago

Alright, thanks. I'll close this for now.

I'll stop changing MIX_ENV on Heroku -- and I'm also going to leave the PORT as an exported variable in the config.