Based on my recent experience of deployment, I've become rather frustrated with the deployment tooling in Elixir. This document is the result of me thinking to myself, "I wish we had x...". This document isn't meant to dishearten anyone who has built tooling for elixir - thank you so much for what you've done. This is meant more as what I personally see as something that would help a lot of Erlang/Elixir newbies like myself to be able to get deploying quickly and efficiently.
It should be possible to add in custom configuration to the bootstrap scripts. This would allow plugins to be able to add extra steps to the startup / shutdown / upgrade procedure. One way to implement this would be to make all scripts which handle bootstrapping or controlling the machine .eex templates. This would allow other parts of the release system to inject new functionality where needed.
vm.args
contains information about how the VM should run your elixir app. If you don't know what the server is like beforehand, it can be hard to produce a vm.args
that will fit your needs. Creating the vm.args
as part of the bootstrapping process would allow for more efficient use of BEAM, as well as configuration of things like the name
and sname
, which are often dependent on the hostname of the machine.
It's been established that this is actually already possible. Better documentation around this would be great.
Init scripts will remain largely the same across projects. It makes sense to provide defaults for each init type, in the same way foreman works.
We agree that this is not the responsibility of exrm
directly, but rather that of a plugin.
The release config file should be easy to configure, and match closely the patterns that people are used to following in config.exs
.
I think the phases of the release process should be simple to add to & reason about. I was imagining a config that has something like this in it:
def deploy_pipeline(foo) do
foo
|> PhoenixOverlay.compile_static_assets
|> Exrm.build
|> CustomOverlay.do_thing_a
|> CustomOverlay.do_thing_b
|> ExrmDebPlugin.package
|> AptPlugin.release
end
Where PhoenixOverlay
, ExrmDebPlugin
and AptPlugin
are External plugins, and CustomOverlay
is some internal config specific to that app.
The release configuration file can override steps with custom steps, and also add new steps. In addition, plugin steps can be added to the pipeline.
External Output plugins would be able to take a successful build, and do something with it (exrm-rpm is already capable of this). This could be:
- SCP the result to a server and upgrade
- Build a debian Package - DONE! exrm_deb now exists.
- Send a notification on Slack
Advantages over not being a plugin:
Can use information from mix.exs automaticallyCan upgrades can be handled automatically through apt hooksAbility to create metapackages for umbrella apps
I've began work on a deb plugin, which you can check out here: https://github.com/johnhamelink/exrm-deb
Advantages:
- Is able to detect when an update is happening automatically
- Simple to setup when deploying to a non-cloud VPS or bare metal
Advantages:
- Can provide information about
- which apps changed (if in an umbrella)
- what environment they were built to deploy to
Thanks for the feedback! Stuff like this is how we improve as a community rather than stagnate, so you never need to fear providing constructive criticism (at least you shouldn't have to, but as we know, this is the internet).
before_release
hook), which effectively is the same thing. I can't think of anything you would want to do by overriding steps that you can't do with a plugin.5.1. You can do this via the
after_release
hook in a plugin. This is in fact how the exrm-rpm package works if I recall.5.1.1. All plugins can access the current project's
mix.exs
, so I don't think that one is an issue. Handling upgrades through packaging hooks is also something that can be done with a plugin (exrm-rpm does this). The only one that (currently) cannot be done is creating a metapackage of an umbrella app, but that's because umbrella apps are not fully supported in exrm the way I would like them to be. When support for building a release of a full umbrella is added, then this becomes a non-issue.5.1.2. Could you clarify why this plugin would need to be part of exrm and not a library? My primary red flag is how to support such things, I neither use this approach for deploys, nor do I have an adequate way to test it. I do not want to offer anything in exrm that I can't support, or that I'm not already pretty much on the hook for implicitly because of decisions early on in the project. The advantage to keeping plugins such as these external is so that interested parties can build and maintain them properly. The caveat to all of this of course is that if exrm in some way prevents things like this from being built, then I'm open to developing additional hooks or configuration mechanisms to keep exrm out of the way as much as possible. There are certain limitations to how releases can be built and deployed, but as far as I'm able I want to offer the capability to customize your releases to the extent possible.
5.1.3. Definitely would have to be an external plugin, but would be trivial to do via the
after_release
hook, since all the information you mentioned is present at that time.Notes
My own list of issues