How to do phoenix deployment rollover?

I am trying to figure out how to upgrade a phoenix application on digitalocean for example with zero downtime. I am running phoenix 1.4.9 and elixir 1.9. My application uses channels. I googled some stuff and I am having trouble figuring out what is the definitive idiomatic way of doing this.

My thought are in trying to keep things simple to first try to limit this to one machine rather than deploying the upgraded phoenix app on a second machine and then figure out how to transition to the second machine and shutdown the first machine.

It seems to me that one approach is to have on the machine nginx listening to port 80 and passing off to something like port 8080 on the first phoenix process. Then to upgrade the application we bring up a second phoenix process listening on port 8081. We have this second process join the first one to form a cluster because we need the channels to be able to communicate globabally across the cluster during the rollover. We reconfigure nginx to pass off to port 8081 so all new traffic hits the upgraded phoenix application. Then we somehow send a command to the first phoenix process to close all websockets. The web browser clients will then reconnect the websockets and this will hit the second phoenix process. Then we can safely bring down the first phoenix process.

Does this make any sense? Is this at all normal? What would be the correct way to do this and is there a definitive guide?

There is no ‘definitive guide’ since there are many decisions to be made that depend on your application’s exact circumstances.

However, I wrote a guide detailing the steps I use myself a while back, which also uses a VPS on DigitalOcean or a similar host as starting point. It’s not perfect, but it might give you some initial ides: Using LetsEncrypt with Phoenix (behind Nginx). How to make this more optimal?

1 Like