Is it possible to auto-restart a Phoenix server on config change (in development)?

For most changes made in your app’s files, Phoenix is able to reload individual modules while the app is kept running (using a combination of Phoenix.CodeReloader and Phoenix.LiveReloader).

However, if your config-files or mix.exs change, then this requires a manual restart.


This is of course completely reasonable: we might change what dependencies exist, what options are passed to the Elixir/Erlang compiler(s), etc.

However, it is very common to trigger this situation when e.g. switching between branches in git.

Thus my question: Is there a way to automate this full restart of the application?
Maybe by wrapping the call to mix run --no-halt or iex -S mix in some other command or shell-script?

Thank you for your help!

To me it sounds like this is out of Phoenix’s scope of responsibilities. I think wrapping the command with a file watcher is the way to go. I personally use watchexec to format the code and run my tests (this could be tweaked, but I hope you get the idea):

watchexec -e 'ex,exs,eex,leex,lock' -- 'mix format & mix test --stale'

Seems this could do the job you need.

1 Like

In the past I experimented with using :init.restart/0 by adding it to the Phoenix exception page that is displayed for those exceptions. It seemed to work pretty well but I never got around to making a PR for it.

3 Likes

If you’re on macOS, you could use entr. Something like: find config/ | entr -rs "iex -S mix phx.server"

1 Like

I tried the following:

 watchexec --restart --watch="mix.exs" --watch="config/" --no-process-group -- iex -S mix phx.server

However, it seems that watchexec will override what happens on Ctrl+C, immediately exiting itself (rather than opening the IEx BREAK menu). I have not yet found a way to turn this off.

I tried ls mix.exs config/**.exs | entr -r -s "iex -S mix phx.server", but while IEx starts, it seems that I cannot interact with it, i.e. that entr is running in some kind of non-interactive mode (or gobbling up keypresses maybe?)

Interesting idea!

It seems the error on change of mix.exs / config files is raised as a string (i.e. as a plain ‘RuntimeError’). (see here).

Did you add the code to the ErrorView-function handling a general status code 500? Or in some other place?

That can result with weird corner cases though.

1 Like

I agree that this can happen, but I’m less certain that you want it handled automatically. Lots of things can change when switching branches:

  • package versions
  • database migrations
  • config

Restarting will handle the “config” part of that, but not the other two. :thinking: