Phoenix: Should `mix run` also run the application?

Created on 12 Mar 2019  路  3Comments  路  Source: phoenixframework/phoenix

Environment

  • Elixir version (elixir -v): 1.8.1
  • Phoenix version (mix deps): 1.4.1
  • NodeJS version (node -v): --
  • NPM version (npm -v): --
  • Operating system: OS X

Context

I've been working with Phoenix for a while and I always used it with mix, even in produciton (Heroku), however this time I'm using it inside an umbrella app with distillery.

So I wanted to start the application as a whole, and I was issuing $ mix run --no-halt command to run all the applications inside umbrella, but with that the Phoenix endpoint doesn't start listen on the configured port, so as the build generated by distillery, only with $ mix phx.server which starts all apps too, but I don't think this command is appropriate to run the umbrella app, IMHO.

Diving into Phoenix's source code, I found the phx.server mix task setting up a configuration just before running run mix's task, which made me think if this configuration shouldn't be set by default in config/config.exs (or even in some env related config file), or even if this should be a configuration at all, since when I start an application I think I'd like to have the endpoint listening to requests (I couldn't come up with a scenario in which this shouldn't happen). I'm saying that because to have my Phoenix app running with distillery I had to take that configuration to the app's config (in order to have :phoenix, serve_endpoints: true).

I'm not saying that we should remove the $ mix phx.server command, which is great for standalone Phoenix applications, but I think we should also have $ mix run putting the application up and running.

Expected behavior

Be able to run an umbrella app and have all Phoenix endpoints running only with $ mix run [--no-halt] command.

Actual behavior

Phoenix's endpoints only start when executing $ mix phx.server command.

Disclaimer

I'm not sure should I open this as an issue since this is not a bug report, neither a feature request, neither a doubt on "how to" to have it on any other place.

Thank you!

Most helpful comment

since when I start an application I think I'd like to have the endpoint listening to requests (I couldn't come up with a scenario in which this shouldn't happen)

Here's a few scenarios when starting the endpoint on application start by default might be undesirable:

  • you wouldn't be able to start more than one iex -S mix session because the 2nd run would try to bind to an already taken http port. Same goes for running mix run script.exs or running Mix tasks. Imagine you have a Mix task that performs some ops work and requires app start (e.g. needs repo, cache etc to be started), you'd now have to explicitly _disable_ endpoint in that task
  • somewhat similar to above, imagine you're deploying your Phoenix app with Mix; if you try to start a new session on production box it will fail for the same reason
  • starting the endpoint by default will also start it for tests and which is not needed unless you're actually hitting the real server in them

As you pointed out, it's relatively easy to start the endpoint by setting serve_endpoints: true, so you could configure your app in dev to do just that.

All 3 comments

since when I start an application I think I'd like to have the endpoint listening to requests (I couldn't come up with a scenario in which this shouldn't happen)

Here's a few scenarios when starting the endpoint on application start by default might be undesirable:

  • you wouldn't be able to start more than one iex -S mix session because the 2nd run would try to bind to an already taken http port. Same goes for running mix run script.exs or running Mix tasks. Imagine you have a Mix task that performs some ops work and requires app start (e.g. needs repo, cache etc to be started), you'd now have to explicitly _disable_ endpoint in that task
  • somewhat similar to above, imagine you're deploying your Phoenix app with Mix; if you try to start a new session on production box it will fail for the same reason
  • starting the endpoint by default will also start it for tests and which is not needed unless you're actually hitting the real server in them

As you pointed out, it's relatively easy to start the endpoint by setting serve_endpoints: true, so you could configure your app in dev to do just that.

Wojtek answered this perfectly. Thanks!

Got it! Thank you guys!

Was this page helpful?
0 / 5 - 0 ratings