Recently we started playing with Elixir which is an awesome language bringing quite a few perks in terms of performance, reliability and scalability but also enforcing a mentality shift to functional programming (as compared to OOP as in modern PHP).
When it came to deployment we basically had two options: using exrm releases or just starting the app (that uses Phoenix framework) in production mode.
Internet didn’t tell us much about which option is more useful aside from exrm being the “cooler” one and the rolling update – “easier”, so we tried both, starting with the cool one 🙂
Basically using releases can be boiled down to following features:
- Generates self sufficient CLI executable with a bunch of nice features
- The executable contains everything needed to run the app including Elixir and Erlang / BEAM, so the server doesn’t need them installed
- Hot updates – one of the selling points of Elixir, it is possible to swap the versions of the app in memory without losing state providing really “seamless” deploys
Rolling update on the other hand is pretty similar to the one we already used, server environment has to be set up and deployment will pull some code and run some CLI commands including restarting the application service.
Now after some time in production (and I must say without having any problems) with both systems, here are few points to keep in mind when choosing one:
- Hot updates are not “set up and forget” kind of feature, you’d have to tag your modules that manage state with versions and write “migrations” to keep the state consistent between upgrades and downgrades
- Creating a release for each deployment can be a hassle if you deploy often (which we do)
- Releases have to be created in an environment similar to the production one, meaning it can not (should not) be done on Windows or Mac systems, which means sooner or later you’ll probably need a build server
- Sometimes hot updates didn’t work for us, probably because of the “bigger” environment changes like Elixir 1.2 to 1.3 update
- If your app uses Database or builds assets (if it’s a web app) you’ll probably end up with Elixir part of it being encapsulated in a release and migrations / asset management being managed “externally”
Considering all of the above we switched to rolling updates in the latest project. Don’t get me wrong, I find being able to perform hot upgrades to be an extremely useful feature, but I’d only use it if I really need it since it requires some maintainance work on my part.
Here is what distillery (exrm’s successor) docs tells us on this issue:
In general, unless you have a strong reason for using hot upgrades, it’s almost always simpler to just do rolling releases. Hot upgrades are an amazing capability, but they are deceptively simple to use due to the automatic appups. If you get to the point where you need to write your own appups, you will need to become intimately familiar with them, and there is a lot of complexity hidden there. However, there is nothing preventing you from using upgrades until you hit that point, doing a rolling release, then continuing with upgrades from there – it ultimately depends on your needs. I would caution anyone thinking of using them to evaluate whether they are truly necessary for their use case.