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 getting back to me so quickly @bitwalker!
Some responses to some of the points listed in your response (I've also updated the initial post to reflect clarifications you've made):
I'd be happy to explore this! Would you be able to explain how you envisioned this would work? If you could propose a plan, I'd gladly attempt to submit a PR 😄
In my usecase, I'm using a pull-based deploy system, making use of
user_data
scripts in AWS EC2 servers. This means that I can't know anything about the machine (including its hostname or spec) until boot time. It sounds like the current implementation actually would satisfy my usecase, but I had no idea this was possible - I knew I could replace the vm.args at release packaging time, but of course in my case that's no use.Wow, how'd I miss this? Might I suggest adding a section to the readme with plugins that work with exrm? I'll submit a PR for this.
I agree, this makes sense for everyone. This also seems like a good way for me to learn about the codebase. I will begin contributing by building a debian plugin.
Hmm, just to clarify - which config file are you referring to in this case? I didn't make it clear I was referring to the next section.
So what I was thinking of when I wrote this section, was a clear explanation of the phases of the release process. I was imagining a config that has something like this in it:
Where
PhoenixOverlay
,ExrmDebPlugin
andAptPlugin
are External plugins, andCustomOverlay
is some internal config specific to that app. Does that provide better context?RE notes on 5.1.1 - 5.13: all of those suggestions were supposed to be seen as examples for what the plugin system would be used for, I totally agree with you that none of that should become part of exrm! I was thinking about the different types of potential users and what they would look for in a release plugin: the user who's comfortable with something like capistrano, the user who's deploying across a cluster of machines, etc.
That is most likely correct 😄
That's interesting, I wasn't aware that this is the case. Why is that? Would it make more sense to build a dedicated metadata plugin that other plugins would use to query with, making it easier for plugins to be maintained as exrm (and BEAM, I guess) changes?
I think we can all get behind that 😄
As I mentioned above, I can begin contributing plugins in order to learn how exrm works.
I agree.
I really like way Ember handles deprecated code:
Thoughts?
I agree, but I also have no idea how this would be implemented at this point 😄