rogach
How to: Tweak mix release to work with hot code reloading
I’ve spent some time understanding how to do hot code reloading with releases built using mix release, and here I’d like to detail the steps needed, in hopes that it will help someone.
So, in order to make hot-reloadable release you need:
- Write an appup file (the Erlang’s Appup cookbook is a great resource for that: Appup Cookbook — Erlang System Documentation v29.0.2).
- Tweak the release generated by
mix release, by copying the .rel & .appup files into expected places and generating the relup file. This can be done by hand, but I’ve wrote a simple function that can do that right inside themix releasetask:
def project do
[
releases: [
app_name: [
include_executables_for: [:unix],
steps: [:assemble, &release_fixup_step/1, :tar],
],
],
...
]
end
defp release_fixup_step(release) do
releases_dir = Path.join(release.path, "releases")
rel_file = Path.join([releases_dir, release.version, "#{release.name}.rel"])
:ok = :release_handler.create_RELEASES(releases_dir, rel_file, [])
# Yes, we have three copies of a same file in the same place.
# This is necessary to appease the release_handler.
File.cp!(rel_file, Path.join([releases_dir, release.version, "#{release.name}-#{release.version}.rel"]))
File.cp!(rel_file, Path.join([releases_dir, "#{release.name}-#{release.version}.rel"]))
# Copy appup file into the correct location and generate the relup.
appup_file = Path.join("appups", "#{release.version}.appup")
if File.exists?(Path.join("appups", "#{release.version}.appup")) do
File.cp!(
appup_file,
Path.join([release.path, "lib", "#{release.name}-#{release.version}", "ebin", "#{release.name}.appup"])
)
{:ok, appup} = :file.consult(appup_file)
[{appup_release_version, [{version_up_from, _}], [{version_down_to, _}]}] = appup
if appup_release_version != to_charlist(release.version) do
raise "Unexpected version in appup: #{appup_release_version} (expected #{release.version})"
end
if version_up_from != version_down_to do
raise "Unexpected versions in appup instructions: #{version_up_from} != #{version_down_to}"
end
:systools.make_relup(
~c"#{release.name}-#{release.version}",
[~c"#{release.name}-#{version_up_from}"],
[~c"#{release.name}-#{version_down_to}"],
path: [to_charlist(Path.join(release.path, "releases/*")), to_charlist(Path.join(release.path, "lib/*/ebin"))],
outdir: to_charlist(release.version_path)
)
end
release
end
Now, after running mix release you will get a release archive in _build/<env>/app_name-<version>.tar.gz.
- Copy this archive into the
releases/directory of your running release. - Connect to the Iex shell of the running release.
- Carefully run the commands:
:release_handler.unpack_release(~c"app_name-<version>")
:release_handler.install_release(~c"<version>")
:release_handler.make_permanent(~c"<version>")
Trending in Guides/Tuts
Other Trending Topics
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #performance
- #security









