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>")
Popular in Guides/Tuts
I thought I’d share a small project I’m working on to gain some familiarty with LiveView in a Phoenix app.
Github Repo
Deployment
It’s...
New
Hi all!
Just want to share a small code snippet which allows writing CASE expressions using macro which is similar to cond.
Here is an ...
New
Ran across this recently, it’s a set of cheatsheet inforgraphic things of the OTP behaviours on the BEAM:
https://github.com/Telichkin/o...
New
I just published an article on creating Phoenix LiveView modals using Tailwind CSS and AlpineJS.
New
For those of you who might be interested in using ZeroMQ in Elixir, I converted the Erlang examples in the ZeroMQ “zguide” to Elixir. I ...
New
Hello everyone,
I created a deployment tutorial for Phoenix applications with Kubernetes (microk8s) a few months back with the goal of s...
New
Complete beginners Todo List Tutorial in Phoenix 1.5.3 (latest and greatest):
https://github.com/dwyl/phoenix-todo-list-tutorial
It’s a...
New
Here is a quick guide to uploading a file from the browser to DO spaces.
It is crude, but will hopefully save sometime time and frustrat...
New
I’ll post this here, It might help someone in the future.
Feedback is greatly appreciated.
I use it with direnv on NixOS, It should wor...
New
Just a quick heads up: There seems to be a bug in Erlang/OTP 21.3, which can cause some errors when making http requests. If you’re using...
New
Other popular topics
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Hello!
tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability.
After spen...
New
After calling mix ecto.create I get this error:
17:00:32.162 [error] GenServer #PID<0.412.0> terminating
** (Postgrex.Error) FATAL...
New
Phoenix 1.4.0 released
Phoenix 1.4 is out! This release ships with exciting new features, most notably
with HTTP2 support, improved deve...
New
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
New
Good day to you all.
I have been struggling to get a query involving like and ilike to work.
Can anyone assist me on this, please?
pro...
New
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
Hi everyone!
I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
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
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









