patmaddox
How to reload env vars when restarting a mix release app?
I have encountered something surprising when restarting a mix release app - it doesn’t pick up new env vars.
$ mix new release_test
$ cd release_test
$ mix release
$ FOO=foo _build/dev/rel/release_test/bin/release_test daemon
$ _build/dev/rel/release_test/bin/release_test rpc 'System.fetch_env("FOO") |> IO.inspect()'
This prints {:ok, "foo"} as expected.
Now I want to change the FOO environment variable and restart:
$ FOO=bar _build/dev/rel/release_test/bin/release_test restart
$ _build/dev/rel/release_test/bin/release_test rpc 'System.fetch_env("FOO") |> IO.inspect()'
But it still prints {:ok, "foo"} - it didn’t pick up the updated env var.
When I look at the OS processes, I see a run_erl and a beam.smp process that have the same PIDs as before the restart. So it seems like it may be more of a reload than actually stopping and starting the process, and maybe those long-running processes only read the env var when they first start?
Is there a way, using the mix release scripts, to restart the app and read new env vars as part of the restart?
Most Liked
patmaddox
Just to follow up: I did figure out how to lean heavily on FreeBSD’s rc system. The main thing is running the app under daemon(8) rather than using the elixir daemon. This produces a pid file, and so the service can use the built-in stop / restart / status behavior.
The following RC script is auto-generated by ExFreeBSD:
#!/bin/sh
#
# PROVIDE: release_test
# REQUIRE: DAEMON
. /etc/rc.subr
name=release_test
rcvar=${name}_enable
pidfile="/var/run/${name}.pid"
procname="/usr/local/libexec/release_test/erts-13.0.2/bin/beam.smp"
: ${release_test_env_file:=/usr/local/etc/release_test.env}
command="/usr/local/libexec/release_test/bin/release_test"
extra_commands="remote"
start_cmd="daemon -f -t $name -p $pidfile $command start"
remote_cmd=release_test_remote
#rpc_cmd=release_test_rpc
release_test_remote()
{
export TERM=xterm
$command remote
}
#release_test_rpc()
#{
# $command rpc "$1"
#}
load_rc_config $name
run_rc_command "$@"
patmaddox
Okay. Do you have any suggestions on how to do a “real” restart, so I can reload the env vars?
I can run _build/dev/rel/release_test/bin/release_test stop but that can take a minute or two, and I’m not sure how to tell when it’s done in an automated way.
Typically daemons will write a pid file somewhere that you can use to reliably check the status. I don’t see anything like that.
I may be misunderstanding here - how do you do that? I can open up a new terminal tab, run the same second command, and get the same result. So, that’s not it.
Interesting… my takeaway from reading all this is that you should not configure Elixir apps using env vars, because once the erlang process is running, that’s it - there’s no way to get new env vars into it.
Instead, you use env vars to configure the erlang process. Then your application reads its own config from a file. Some of those tools you linked look like they’re intended to simulate env vars by reading the config from env-var-like files - but they’re not actually env vars.
I think for production releases, it’s probably important to cleanly separate these, and not load any app config from env vars since that only applies to app start. Vapor looks like it should do the trick there, but reading a config file should be simple enough. Thank you for the pointers!
Popular in Questions
Other popular topics
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









