In your case, the simplest thing to do is to move the plug initialization
and execution to runtime:
defmodule HalfDome.Endpoint do
use Phoenix.Endpoint, otp_app: :half_dome
plug :canonical_host
defp canonical_host(conn, _opts) do
opts = Plug.CanonicalHost.init(canonical_host:
System.get_env("CANONICAL_HOST"))
PlugCanonicalHost.call(conn, opts)
end
end
Now you will properly read the system environment every time and there is
no need for {:system, "something"}.
The {:system, _} tuple environment has been a workaround and right now we
have better solutions to the problem. I have written about how Ecto and
Phoenix, which provide stateful features, are tackling this problem here:
https://elixirforum.com/t/what-is-the-difference-between-using-system-port-and-system-get-env-port-in-deployment/1975/12
However, if the other application always reads from Application.get_env,
then you can simply set the application environment directly with the
desired above when your app starts:
Application.put_env(:plug_canonical_host, :canonical_host,
System.get_env("CANONICAL_HOST"))
To sum the new approach up: runtime/dynamic configuration needs to be done
at runtime, and not in the config files.
*José Valim*
www.plataformatec.com.br
Skype: jv.ptec
Founder and Director of R&D
On Thu, Mar 2, 2017 at 2:26 AM, Christian Nelson <[email protected]>
wrote:
> The version of this issue I ran into today is with a 3rd party plug,
> https://github.com/remiprev/plug_canonical_host. I wanted to do something
> like this:
>
> defmodule HalfDome.Endpoint do
> use Phoenix.Endpoint, otp_app: :half_dome
>
> plug PlugCanonicalHost, canonical_host: System.get_env("CANONICAL_HOST")
>
> #...
> end
>
> But, between the compilation of the file and the "plug" macro expansion,
> System.get_env("CANONICAL_HOST") is resolved at compile time. I'm pretty
> new to Elixir and I tried 4-5 things to have the lookup be dynamic without
> any luck.
>
> So, I submitted a pull request to that library
> <https://github.com/remiprev/plug_canonical_host/pull/7> so that it
> supports the {:system, "CANONICAL_HOST"} syntax. It was easy to do and
> works. Unfortunately we have other situations where we want to do the same
> thing and it's not easy to patch every library that's out there.
>
> Also, I noticed that in the phoenix code, many instances of {:system,
> env_var} are flagged for deprecation in 1.4... which makes me think trying
> to perpetuate this convention could be a bad idea.
>
> Is there some elixir-fu that would make it easy(ish) to fetch the
> CANONICAL_HOST at runtime in the example above?
>
> Thanks!
> Christian
>
> On Wednesday, March 1, 2017 at 9:26:01 AM UTC-8, Almas Sapargali wrote:
>>
>> Hello, I'd vote for this change too, actually found that and other
>> discussion, when I was going to make exact same proposal, and just did a
>> quick search first. Then only notable stopper I've seen is that values
>> would be strong, whilist user may expect int/bool etc. I think we could
>> handle this case by passing some typing info in first element, like
>> {:system_int, "POOL_SIZE"} etc, which would evaluate to nil if env isn't
>> set or not an integer.
>>
>>
>> On Saturday, December 17, 2016 at 3:17:35 PM UTC+6, José Valim wrote:
>> > There has been a couple discussions on the topic either here or on the
>> issues tracker.
>> >
>> >
>> > The consensus is that this problem needs to be solved but we are not
>> quite sure how. The only way to support {:system, "DATABASE_URL"} in a way
>> that it would also work for Erlang applications is by hijacking the
>> application controller using private APIs. We could also try solve this
>> exclusively for Elixir but then there would be gaps where it wouldn't be
>> supported.
>> >
>> >
>> > Ecto 2.1 is trying a new approach where the value is configured using a
>> repository callback, that's what we will try to do when Phoenix 1.3 comes
>> out and see where it will lead us to.
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> > José Valim
>> >
>> > www.plataformatec.com.br
>> > Skype: jv.ptec
>> > Founder and Director of R&D
>> >
>> >
>> > On Sat, Dec 17, 2016 at 1:48 AM, Cory ODaniel <[email protected]>
>> wrote:
>> >
>> > I've definitely run into issues where I need to pass an environment
>> variable at run time, but an application that I use doesn't support the
>> {:system, "DATABASE_URL"} or {:system, "PORT"} style environment variables
>> that Ecto and Phoenix support.
>> >
>> >
>> > I'm curious if it would be beneficial to add support in
>> Application.get_env/2 that when the value that returns matches {:system,
>> var} then System.get_env(var) would be called under the hood.
>> >
>> >
>> >
>> >
>> >
>> >
>> > --
>> >
>> > You received this message because you are subscribed to the Google
>> Groups "elixir-lang-core" group.
>> >
>> > To unsubscribe from this group and stop receiving emails from it, send
>> an email to [email protected].
>> >
>> > To view this discussion on the web visit https://groups.google.com/d/ms
>> gid/elixir-lang-core/9fd6e998-04d2-4d7d-87ee-34abb16ee779%
>> 40googlegroups.com.
>> >
>> > For more options, visit https://groups.google.com/d/optout.
>>
>>
--
You received this message because you are subscribed to the Google Groups
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4KVVZypNBzxPUVCLqrgx-4%2Bs_ccf%2BJO5O96ds-opbYA%2Bw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.