<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="82492" data-post-id="82492">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lorenzosinisi" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lorenzosinisi/120/10574_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lorenzosinisi
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Love the idea of questioning this point because it has definitely been painful in the past when configuring Elixir apps (especially umbrella). The main problem that we encountered was related to the fact that there are multiple ways to configure and app, and even within the configuration files themselves, you can use System.get_env or also load_os_vars.</p>
<p>Since the release, as far as I know, is one. The all process could be simplified by doing the following:</p>
<p>Instead of <code>on_boot</code>, that does not seem to be explicit enough for developers that come from other languages such as Ruby, why not having something like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">use Application.Config

production do
  config :ui, UI.Endpoint, url: [host: System.get_env("HOST")]
end

dev do
  config :ui, UI.Endpoint, url: [host: "localhost"]
end

test do
  config :ui, UI.Endpoint, url: [host: "localhost"]
end
</code></pre>
<p>Since the release is one also for umbrella applications, the developer can be ‘forced’ to move all the config in one single place (maybe in the root folder under /config/) so that:</p>
<ol>
<li>It is clear where the configuration is and should be defined</li>
<li>It is easy to understand what will be loaded in production, dev and testing</li>
<li>The order by which the configuration keys and values are set is more obvious (currently, umbrella apps load the config in a funny way and may override some keys without any warnings)</li>
<li>We have less confusion about what happens to the code that is not defined in the scope of <code>on_boot/1</code></li>
<li>We generate a module from each of those calls that could be compiled and replaced using hot swapping</li>
</ol>
<p>I am new to Elixir and compiled languages so please bear with me if I say something completely senseless</p>
<p>Nice discussion tho!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82492" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302/34">Post #33</a>
	                </div>
	            </div>
              <div id="likers-container-82492" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82492"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #33"></div>
  </section>
</div>
    <div class="postbit" id="82496" data-post-id="82496">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="yurko" data-post="31" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/yurko/48/2369_2.png" class="avatar"> yurko:</div>
<blockquote>
<p>I very much like the idea, am I right to assume that it’s still the end goal?</p>
</blockquote>
</aside>
<p>We are not sure that will be exactly the end goal but that’s the direction we are going. The goal of this proposal is to improve interoperability with releases. We will continue improving bits of the language until releases are effectively part of the language.</p>
<aside class="quote group-Rebar3" data-username="talentdeficit" data-post="32" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/talentdeficit/48/1302_2.png" class="avatar"> talentdeficit:</div>
<blockquote>
<p>i don’t think there’s anything wrong with either of these proposals but i think incremental improvements to config are not enough. the risk is that it gets good enough that no further work is done and the real issue (that of libraries not exposing their internals in a way that is flexible enough for more than just archetypal users) is never addressed</p>
</blockquote>
</aside>
<p>Besides what <a class="mention" href="/u/sasajuric" rel="nofollow">@sasajuric</a> said, there is also work happening on this front as “configuration providers”. So we will make sure we go all the way and not only half way. Regardless, the built-in provider should be as solid as it gets.</p>
<aside class="quote no-group" data-username="lorenzosinisi" data-post="34" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lorenzosinisi/48/10574_2.png" class="avatar"> lorenzosinisi:</div>
<blockquote>
<p>Since the release is one also for umbrella applications, the developer can be ‘forced’ to move all the config in one single place (maybe in the root folder under /config/) so that:</p>
</blockquote>
</aside>
<p>The problem we are trying to solve though is not about the understanding of configuration (it probably deserves a separate discussion) but rather how to control what is evaluated at compile time and what happens at runtime, regardless of the environment (dev/test/prod). Introducing blocks for dev/test/prod does not address the root issue here.</p>
<p>We agree there are issues with umbrella though. As mentioned in the original post, those will be discussed separately, otherwise we end-up mixing too many topics and the discussion ends up too dispersed.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82496" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302/35">Post #34</a>
	                </div>
	            </div>
              <div id="likers-container-82496" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82496"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #34"></div>
  </section>
</div>
    <div class="postbit" id="82499" data-post-id="82499">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="blatyo" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/blatyo/120/4554_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  blatyo
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Conduit Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="30" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>The current proposal was seen a smaller step. We could always add <code>on_boot</code> later and we thought restricting <code>import_config</code> was going to be a good thing nonetheless. But I guess the opposite direction is also true: we can add <code>on_boot</code> now and restrict <code>import_config</code> later.</p>
</blockquote>
</aside>
<p>I assumed the <code>import_config</code> change was a required step for supporting releases. If just <code>on_boot</code> were done, wouldn’t a release still not know where to pull in config?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82499" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302/36">Post #35</a>
	                </div>
	            </div>
              <div id="likers-container-82499" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82499"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #35"></div>
  </section>
</div>
    <div class="postbit" id="82504" data-post-id="82504">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bitwalker" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/120/998_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bitwalker
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Leader</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I am unfortunately late to this discussion, but I do have some thoughts:</p>
<p>I dislike <code>on_boot</code>, I fail to see what problem it is actually solving. The config file is <em>already</em> evaluated during boot, so this is effectively a misnomer - and I’m completely against something like this only applying to releases, since it is a big part of the motivation for these improvements, to streamline the transition from dev to prod.</p>
<p>I’ve seen numerous mentions about the build-time/runtime confusion - but that is a problem beyond the scope of these changes (in my opinion). The biggest win we get here is by closing the gap between dev and releases, getting rid of dirty hacks like <code>REPLACE_OS_VARS</code>.</p>
<p>In general I agree with <a class="mention" href="/u/sasajuric" rel="nofollow">@sasajuric</a> about configuration, but I personally feel that we have to, at a minimum, address the biggest pain with configuration today, which is dealing with releases. I’m all for eventually restricting the capabilities and pushing the community in a better direction, but we have a very real, very painful problem right now to deal with, and I would rather see us simplify the situation rather than add even further layers of complexity to it. Simplification here meaning that we no longer have two different ways of configuring a system between dev and prod, and instead we have (more or less) the same old system everyone is already familiar with in <code>config.exs</code>.</p>
<blockquote>
<p>If we had configuration providers, this is about improving the built-in provider. Custom providers is a separate topic and I believe <a class="mention" href="/u/bitwalker" rel="nofollow">@bitwalker</a> was working on this.</p>
</blockquote>
<p>Yeah this is something I added in Distillery as part of the work along these lines - <code>Mix.Config</code> or <code>Application.Config</code> would just be another provider, and custom ones could be built to fetch configuration from other files, or even external systems like etcd/Consul/etc.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82504" data-batch-url="/posts/batch_likers">
                        9
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302/37">Post #36</a>
	                </div>
	            </div>
              <div id="likers-container-82504" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82504"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #36"></div>
  </section>
</div>
    <div class="postbit" id="82509" data-post-id="82509">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="cybrox" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cybrox/120/10045_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  cybrox
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Fist of all, I think there is a very important point to make here, in order to assure this reasonable attempt of improvement is not going sideways:</p>
<aside class="quote no-group" data-username="bitwalker" data-post="37" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>we have a very real, very painful problem right now to deal with, and I would rather see us simplify the situation rather than add even further layers of complexity to it.</p>
</blockquote>
</aside>
<p>Currently, the <code>{:system ,value}</code> tuple exists as a de-facto standard in many situations. However, it is usually only used in the production environment. More specifically, the <code>config/prod.exs</code>. However, this is less of a problem of Elixir itself but more of the paradigms introduced by frameworks that generate configurations this way. If  this was used consistently across environments, I think more developers would automatically start correctly offloading those dynamic parameters into environment variables.</p>
<p>I understand the appeal of using optional - as in <code>if-exists</code> approach to - configurations and it certainly is a way of solving the issue at hand, alebit by introducing a duplication of functionality. - In my opinion. As far as I can see (and I’d be happy to be proven wrong) this proposal only changes a bit of complexity (<em>when is configuration part X actually evaluated?</em>) into another bit of complexity (<em>which method do I use to configure my application?</em>).</p>
<p><strong>Bottom line is</strong><br>
As mentioned in the <em>Summing up</em> of the original post, the idea is to make calls like <code>System.get_env/1</code> transparent across environments. Which it already would be if it was used in <code>config/config.exs</code> alone instead of <strong>only</strong> using it in <code>config/prod.exs</code> and introducing <strong>different</strong> behaviour in the other dynamically imported environment configs. - Which is an issue with the software generating that structure, imo.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82509" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302/38">Post #37</a>
	                </div>
	            </div>
              <div id="likers-container-82509" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82509"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #37"></div>
  </section>
</div>
    <div class="postbit" id="82510" data-post-id="82510">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="bitwalker" data-post="37" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>I dislike <code>on_boot</code> , I fail to see what problem it is actually solving. The config file is <em>already</em> evaluated during boot, so this is effectively a misnomer</p>
</blockquote>
</aside>
<p>We have two scenarios here:</p>
<ol>
<li>
<p>Config files are not evaluated in a release at all. This means that config files are only evaluated at compile time. The evaluated configuration is there when you boot your system but you can’t evaluate any code during boot.</p>
</li>
<li>
<p>Config files are evaluated in a release. If you are doing this today, it requires a shim of Mix. This discussion is how to improve things so we don’t require a shim of Mix.</p>
</li>
</ol>
<p>We want to address the second point but the question is: how do we control what is evaluated during boot/release? The initial proposal is about evaluating the exact same config files that we evaluate during a release. However, as we have seen examples in this thread, folks may even call <code>System.cmd/2</code> in their config files. Simply executing all of the config files inside the release is prone to cause issues. A better approach would be if we could explicitly say what runs on boot. That’s what <code>on_boot</code> is about.</p>
<p>So when you say the config is already evaluated inside boot, I am wondering if you are thinking about the current state of 1 or 2? But those are exactly where we don’t want to be.</p>
<aside class="quote no-group" data-username="bitwalker" data-post="37" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>I’ve seen numerous mentions about the build-time/runtime confusion - but that is a problem beyond the scope of these changes (in my opinion).</p>
</blockquote>
</aside>
<p>If many are talking about those points, it is a very strong sign that it is a problem in the scope of the proposal. When we introduced overridable and optional callbacks, there were a lot of confusion, so we broke the proposal in two and everything was clearer. So in my opinion something has to be done, even if that something is rewording the proposal or breaking it apart.</p>
<p>Although I think the issue does run deeper. Until very recently you couldn’t configure a release using mix configs, so the majority of developers treat mix config as compile time. But now we are saying that the config files will run both at compile time and runtime (on boot), this means we are adding ambiguity to the config files. We should discuss how this ambiguity should be addressed.</p>
<aside class="quote no-group" data-username="cybrox" data-post="38" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cybrox/48/10045_2.png" class="avatar"> cybrox:</div>
<blockquote>
<p><strong>Bottom line is</strong><br>
As mentioned in the <em>Summing up</em> of the original post, the idea is to make calls like <code>System.get_env/1</code> transparent across environments. Which it already would be if it was used in <code>config/config.exs</code> alone instead of <strong>only</strong> using it in <code>config/prod.exs</code> and introducing <strong>different</strong> behaviour in the other dynamically imported environment configs. - Which is an issue with the software generating that structure, imo.</p>
</blockquote>
</aside>
<p>I think the issue with the current proposal is that it focused on making all of the configuration also run in a release. However, this has two issues:</p>
<ol>
<li>There is some code that you don’t want to run in a release</li>
<li>The code that you want to run in a release is actually the smaller part of the configuration</li>
</ol> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82510" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302/39">Post #38</a>
	                </div>
	            </div>
              <div id="likers-container-82510" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82510"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #38"></div>
  </section>
</div>
    <div class="postbit" id="82512" data-post-id="82512">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bitwalker" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/120/998_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bitwalker
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Leader</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<blockquote>
<p>We want to address the second point but the question is: how do we control what is evaluated during boot/release? The initial proposal is about evaluating the exact same config files that we evaluate during a release. However, as we have seen examples in this thread, folks may even call System.cmd/2 in their config files. Simply executing all of the config files inside the release is prone to cause issues. A better approach would be if we could explicitly say what runs on boot. That’s what on_boot is about.</p>
</blockquote>
<p>The reason we have a compile-time/run-time dichotomy in the first place is because people <em>couldn’t</em> use their Mix configs in a release - but that is where virtually everyone starts, and they find out the hard way that, oh actually, you can’t do that, because reasons. My take on the situation is that people already assume that configuration is unified by default, and only change that perspective once they have had to go to production. I think it represents not only an easier system to learn, but a pretty painless thing for existing applications to adapt to (anyone already deploying releases would be unaffected by these changes, barring things like invoking <code>git</code> inside their <code>config.exs</code>, and I think such things could be dealt with via warnings as part of the transition for this process (you’ve already invited discussion on that topic originally).</p>
<p>In other words, I think releases should be in a position to work like Mix with regards to configuration (evaluating them during boot). I don’t think there is value in two different sets of config files, or in a special DSL for wrapping “boot-only” config bits. Those things should be pushed into application code then, not defined in <code>config.exs</code>.</p>
<blockquote>
<p>If many are talking about those points, it is a very strong sign that it is a problem in the scope of the proposal. When we introduced overridable and optional callbacks, there were a lot of confusion, so we broke the proposal in two and everything was clearer. So in my opinion something has to be done, even if that something is rewording the proposal or breaking it apart.</p>
</blockquote>
<p>Not to diminish anyone’s complaints, but having been dealing with every shade of configuration problem with releases for years now, I have seen far more people stumble against the fact that <code>config.exs</code> did two different things between dev and releases, than that it <em>doesn’t</em> do two different things. I think the current confusion in this thread is a symptom of the solution we’ve had in place for a very long time now, and that this discussion is derailing into solving a problem which shouldn’t exist in the first place. To put it more plainly, I think that by unifying configuration (i.e. one config file, one set of semantics), it becomes easier to understand, and is easy to adapt to for older systems.</p>
<p>Configuration should be mostly static in nature - if people need to execute “boot-only” code, it should go in their applications, not in the config files. It is not clear to me what else would fall under this umbrella and <em>not</em> belong in your application code.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="39" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<ul>
<li>There is some code that you don’t want to run in a release</li>
<li>The code that you want to run in a release is actually the smaller part of the configuration</li>
</ul>
</blockquote>
</aside>
<p>I’m not sure I agree with the premise that either of these are true and fall under the umbrella of “configuration”. Do we have some examples?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82512" data-batch-url="/posts/batch_likers">
                        10
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302/40">Post #39</a>
	                </div>
	            </div>
              <div id="likers-container-82512" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82512"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #39"></div>
  </section>
</div>
    <div class="postbit" id="82514" data-post-id="82514">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="bitwalker" data-post="40" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>The reason we have a compile-time/run-time dichotomy in the first place is because people <em>couldn’t</em> use their Mix configs in a release</p>
</blockquote>
</aside>
<p>That’s definitely not the reason. Some configuration are truly compile-time. For example, if you change the ecto adapter in a release, <strong>it won’t work</strong>:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">config :my_app, MyApp.Repo,
  adapter: (if System.get_env("DB_ADAPTER") == "mysql", do: MySQL, else: Postgrex
</code></pre>
<p>So the configuration above is a compile-time configuration. There are many other examples. For example, the mime configuration mentioned in this thread. Some of the Logger configuration keys. Even the host configuration for <code>force_ssl</code> in Phoenix was compile time until recently fixed. This will exist regardless of the configuration provider and it is rather decided by how libraries consume configuration. This was less of an issue in the past because mix config only applied at compile time anyway.</p>
<p>It is a problem that definitely exists and we have definitely seen confusion about this on Elixir, Ecto and Phoenix side of things too.</p>
<aside class="quote no-group" data-username="bitwalker" data-post="40" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>Configuration should be mostly static in nature - if people need to execute “boot-only” code, it should go in their applications, not in the config files. It is not clear to me what else would fall under this umbrella and <em>not</em> belong in your application code.</p>
</blockquote>
</aside>
<p>Then this is an argument for not supporting <code>System.get_env/1</code> in config files in the first place. The only reason why we are doing this is because people want to read configuration such as HOST, PORT and DATABASE_URL at boot time (i.e. when the release starts).</p>
<aside class="quote no-group" data-username="bitwalker" data-post="40" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>I’m not sure I agree with the premise that either of these are true and fall under the umbrella of “configuration”. Do we have some examples?</p>
</blockquote>
</aside>
<ul>
<li>
<p>For 1: see the git example in thread</p>
</li>
<li>
<p>For 2: because of what you just said above: configuration is mostly static in nature. Get any production application and notice that the number of configurations that actually use <code>System.get_env</code> is a small part of the overall configuration</p>
</li>
</ul>
<p>I have a hunch that we are talking past each other here. <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82514" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302/41">Post #40</a>
	                </div>
	            </div>
              <div id="likers-container-82514" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82514"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #40"></div>
  </section>
</div>
    <div class="postbit" id="82515" data-post-id="82515">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>EgadsThisLongThread…  My opinion slightly changes and refines by the end of typing this post, feel free to jump to the end for the TL;DR but a lot of context is missed then.</p>
<aside class="quote no-group" data-username="sasajuric" data-post="15" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>These are not system configuration parameters, they’re constants derived from the current state of code on the build machine.</p>
</blockquote>
</aside>
<p>Yeah this is a good example.</p>
<p>In C++ we traditionally have multiple levels of such ‘configurations’ and information available to the program.  First is of course the build system and it’s own data, like building in Release, this information is not available to the program unless explicitly passed in (or one of the few built-in variables) via the ‘macro’ (more like global Elixir module attributes, not like Elixir macro’s), thus being explicit, and when passed in this way they are only available at build-time, not at run-time.  Next you have the config file generation, which is a source file with the above ‘macros’/global_attributes baked into the source for access at runtime, but overall are still constants.  Then of course you have the pure runtime configuration data such as the system environment (which the defaults of course could be pulled from the macros/attributes from before) or database or whatever else, of which these might only be read once then never again, then you have the configurations that are accessed multiple times in the program and thus can be changed with inpunity (and perhaps even scoped to certain areas so different code can access the data differently).</p>
<p>Elixir having a way to manage this simply would be quite nice.</p>
<p>For example, the <code>git rev-parse ...</code> bit would be ran by the build system into a global named attribute (though these are scoped, but globally accessible from within their scope of compiled files), as well it would probably be baked into the source config definition file as well.</p>
<p>Things like url host’s and so forth would likely have either a hard-coded or a macro/attribute default, but use an entry from the system environment if available.</p>
<p>Etc… etc…</p>
<aside class="quote no-group" data-username="sasajuric" data-post="15" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>As I mentioned in the article, <code>:render_errors</code> and <code>:pubsub</code> are parameters to the library, not configuration.</p>
</blockquote>
</aside>
<p>And things like this, which are application specific, would literally just be passed in arguments to the libraries setup code (or in Elixir terms it would be passed in as options to the supervisor that is added to the application).</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="16" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>The proposal does not change this aspect of configuration and this exact issue exists today.</p>
</blockquote>
</aside>
<p>This is why I actually quite like the C++ forced style that configurations that are used at different times have to be put in different places, which is why I like the whole staged config style entirely.</p>
<p>Elixir kind of has this already, build system configuration is put in mix.exs, however all three of compile-time, load-time, and run-time configurations are combined into this mess that you cannot distinguish between so you don’t know which is safe or not to edit at load time (the system environment) or run-time (like Application.put_env) or so…</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="16" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p><code>runtime.dev.exs</code> , <code>runtime.prod.secret.exs</code> , etc</p>
</blockquote>
</aside>
<p>Things like this just yell to me that some of the configuration belongs in the system environment and <em>NOT</em> in the config files…</p>
<p>Really though:</p>
<ul>
<li>Build system all configs should be in mix.exs</li>
<li>Compile-time global config should be in the config.exs file.</li>
<li>Compile-time environment-specific config’s should be in the system environment that defaults to the config.exs if unspecified.</li>
<li>Start/Load-time global config should in the supervisor start’s as options (that maybe should default to the compile-time config).</li>
<li>Start/Load-time environment-specific config’s should be in the system environment or via passed in command-line options that defaults do the supervisor start options (that maybe should default to the compile-time config).</li>
<li>Run-time global configs should be in the Application environment (defaulting up as above, which could of course pull and be updated from a database or something, though a callback that code could register for changes to specific application environment keys would be nice, so a new module would be good).</li>
<li>Run-time scoped-configs should be passed in as arguments to functions or be some kind of scoped access via some new module to handle it all (delegating up as always).</li>
</ul>
<aside class="quote no-group" data-username="michalmuskala" data-post="17" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/michalmuskala/48/20288_2.png" class="avatar"> michalmuskala:</div>
<blockquote>
<p>I don’t agree with the premise that mix config is for operator configuration - it is most definitely not. Things that are usually operator configuration - API keys, component addresses should not go in there. But things such as configuring rendering or names of components, etc, should be there.</p>
</blockquote>
</aside>
<p>Exactly, these kind of things belong in the system environment or passed in to the build system or passed in to the starting server depending (that could be updated at run-time as well).</p>
<aside class="quote no-group" data-username="michalmuskala" data-post="17" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/michalmuskala/48/20288_2.png" class="avatar"> michalmuskala:</div>
<blockquote>
<p>That’s what allows us to have loosely coupled components that are joined through configuration (great example are pubsub name, etc in the phoenix endpoint configuration) - this is a good thing.</p>
</blockquote>
</aside>
<p>I still think most/all of this stuff belongs in being passed to the startup supervisor’s for the relevant areas (or ETS or so).</p>
<aside class="quote no-group" data-username="michalmuskala" data-post="17" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/michalmuskala/48/20288_2.png" class="avatar"> michalmuskala:</div>
<blockquote>
<p>They are better served by environment variables or other ways</p>
</blockquote>
</aside>
<p>Absolutely this, the system environment should be the default place to get many of these things, not some compile-time baked config file.</p>
<aside class="quote no-group" data-username="michalmuskala" data-post="17" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/michalmuskala/48/20288_2.png" class="avatar"> michalmuskala:</div>
<blockquote>
<p>Addressing your proposal for separate runtime and compile-time config files - that’s an idea I had in the past as well. The downside is that if you want to have both per-environment (and you’d probably do want that), now you get 8 config files - the problem of what goes where and how to understand what is the final value just got even worse not better.</p>
</blockquote>
</aside>
<p>Or none depending, hardcoding configs belong as options to supervisors, user-configurable configs should be in the system environment, etc… etc…</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="18" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Ideally we want to conciliate both intents: if the user of the library wants to configure something on boot, then we want to check that with the intent of the writer of the library: can that configuration be set on boot or is it a compile time configuration?</p>
</blockquote>
</aside>
<p>I’m constantly amazed at the number of libraries that don’t allow load-time config adjustement, and especially the ones that don’t allow run-time config adjustment (irritating ueberauth’s strategies hardcode options into their modules, like what the heck were they thinking there…).  A lot of this needs to be enforced better, somehow, so it is harder to make stupid decisions like that…</p>
<p>Optimally I’d prefer <code>user-configurable is preferred to environment-configured is preferred to options-configured is preferred to build-time-configured is preferred to hard-coded</code>, but it is amazing the number of libraries that do either the hard-coding or build-time-configured, thus forcing you to build new code and hot-swap-and-pray it into prod (or reboot the server and take it down during).</p>
<p>I could foresee almost all options that make sense to be changed at run-time existing in the Application environment, but there is also a system to ‘listen’ to changes, important for, say, a database connection so it can spool up the updated connection on demand instead of checking the application environment on every-single-request, which is easier than the user looking up the code to call into the library to change the connection and have it update it’s internal bits that way.</p>
<aside class="quote no-group" data-username="blatyo" data-post="21" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/blatyo/48/4554_2.png" class="avatar"> blatyo:</div>
<blockquote>
<p>Environment variables (solved for</p>
</blockquote>
</aside>
<p>Not really solved because a lot of libraries and main elixir things don’t support the <code>{:SYSTEM, "blah"}</code> setup to access them, nor an easy way for a fallback to be specified if not there, so you end up having to write the code yourself, every-single-time.</p>
<aside class="quote no-group" data-username="blatyo" data-post="21" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/blatyo/48/4554_2.png" class="avatar"> blatyo:</div>
<blockquote>
<p>Secrets file in config format e.g. prod.secrets.exs (solved for)</p>
</blockquote>
</aside>
<p>Ugh, this is, again, what the system environment is for, it’s designed for this kind of stuff…</p>
<aside class="quote no-group" data-username="blatyo" data-post="21" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/blatyo/48/4554_2.png" class="avatar"> blatyo:</div>
<blockquote>
<p>which provides better security than an environment variable.</p>
</blockquote>
</aside>
<p>If it’s on disk and accessible by your program then it’s already more ‘open’ and available then environment variables (and you can encrypt environment variables just as easily, while also scoping their access and even able to clear it on program start after it read what it wants).</p>
<aside class="quote no-group" data-username="blatyo" data-post="21" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/blatyo/48/4554_2.png" class="avatar"> blatyo:</div>
<blockquote>
<p>A secrets manager, like vault. Where config is leased from a manager that has the ability to invalidate secrets. (not solved for)</p>
</blockquote>
</aside>
<p>Or from a database or from a network server or from joe-bobs-config-store or from whatever.</p>
<aside class="quote no-group" data-username="blatyo" data-post="21" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/blatyo/48/4554_2.png" class="avatar"> blatyo:</div>
<blockquote>
<p>This could be moved to another discussion, but I would like the ability to specify another type of configuration provider that may be more suitable for the type of configuration that is being read.</p>
</blockquote>
</aside>
<p>Absolutely this, I store a lot of configs in the database except the libraries that are broken in their configuration handling (like a lot of ueberauth’s strategies).</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="28" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Introduce <code>on_boot</code> as an explicit block of code to be evaluated on boot (e.g. during a release or during mix app.start)</p>
</blockquote>
</aside>
<p>Would be useful, especially if there was also an <code>on_build</code>/<code>on_compile</code> and an <code>on_runtime</code> somehow (though that would would likely need another interface that is already mostly satisfied by <code>Application/put_env</code> and so forth, except for callback support on change).</p>
<aside class="quote no-group" data-username="yurko" data-post="31" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/yurko/48/2369_2.png" class="avatar"> yurko:</div>
<blockquote>
<p>One question though, from the initial proposal I had a feeling that it’s a “hack” or a “workaround” that would temporary make stuff clearer without fixing anything, but reading the discussion I get a feeling that it’s a first step towards unifying the configuration and the workings of mix and releases, is that so?</p>
</blockquote>
</aside>
<p>That’s how it feels to me too, it doesn’t go far enough into Doing Things Right, which if it is being re-made then it really should be re-made all the way.</p>
<aside class="quote group-Rebar3" data-username="talentdeficit" data-post="32" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/talentdeficit/48/1302_2.png" class="avatar"> talentdeficit:</div>
<blockquote>
<p>i think the core problem with elixir’s use of an executable script to populate the application env and the use of <code>Application.get_env/3</code> as the means to retrieve config is that it makes it acceptable and idiomatic to put configuration in <code>config.exs</code> . this is fine for examples and most standalone apps but it breaks down for users who have to integrate elixir into existing ecosystems where things like vault/etcd/dynamodb/encrypted json blobs/etc are used.</p>
</blockquote>
</aside>
<p>This, so very much this…  The System Environment is already a great place for this for build time and load/boot time as it is scoped, settable by other configuration methods (database, environment, another server, encrypted blobs, whatever), and for run-time the Application Environment is already pretty decent, with perhaps some enhancements.  I’m not strictly opposed to a config file (even an ‘executable’ config.exs one), but it should not be environment dependent and is used as a fallback/defaults only (where the command-line or system environment can override anything and everything specified within it either at build time when calling mix or boot time by calling <code>myapp foreground</code> or so).  Preferably I’d prefer a different file format entirely, instead of the current config system each application’s config should be included and inside the config’s should be all the option that application wants/needs, the defaults they are set to, and help text that is used when the program is queried about the option, preferably even with restricted types it can be and so forth, which would make it much easier to validate options, make interfaces for them, etc… etc…</p>
<aside class="quote group-Rebar3" data-username="talentdeficit" data-post="32" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/talentdeficit/48/1302_2.png" class="avatar"> talentdeficit:</div>
<blockquote>
<p>i don’t think there’s anything wrong with either of these proposals but i think incremental improvements to config are not enough. the risk is that it gets good enough that no further work is done and the real issue (that of libraries not exposing their internals in a way that is flexible enough for more than just archetypal users) is never addressed</p>
</blockquote>
</aside>
<p>This, I’ve seen it happen quite a number of times, it just gets ‘good enough’ where most have this constant irritants in it but never big enough to encourage another rewrite.  Java’s system is a bit abhorrant, but it does indeed support most of the options I want above out-of-the box, from an (XML) base config file of defaults, can pass options in the command line, can set them in the environment, can use them from a vault, can access them from a database via plugins, etc… etc…</p>
<aside class="quote no-group" data-username="sasajuric" data-post="33" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>Not sure about other apps, but with ecto/phonenix there was always a workaround without a fork. The way I solved it in older versions was to populate the missing pieces of app env in my app start callback before starting the supervision tree. It wasn’t very pretty, but it worked. These days, we have a proper solution for Phoenix/Ecto in the shape of <code>init/2</code> callbacks (see <a href="https://hexdocs.pm/phoenix/Phoenix.Endpoint.html#c:init/2" rel="noopener nofollow ugc">here </a> and <a href="https://hexdocs.pm/ecto/Ecto.Repo.html#c:init/2" rel="noopener nofollow ugc">here</a>).</p>
</blockquote>
</aside>
<p>That still only handles boot-time options, not run-time dynamically reconfigurable options, not that Ecto has many, but phoenix definitely could, and other third-party libraries <em>VERY</em> much can (ueberauth’s strategies is a constant thorn in my side).  I really like how CacheX does it for example, or my own TimeAfter or so forth libraries, there are default configs, then options that override those passed to the supervisors, and that can further be overridden by changing the application environment, and that yet still can be overriden by passing further options to the actual functions.</p>
<aside class="quote no-group" data-username="sasajuric" data-post="33" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>I’ve seen it happen with Erlang libs as well. In fact the most annoying episode I had was with <code>riak_ensemble</code> which loads the database storage location <a href="https://github.com/basho/riak_ensemble/blob/develop/src/riak_ensemble_storage.erl#L110" rel="noopener nofollow ugc">during its startup</a> (so before my app startup), which made it very hard to establish a local cluster by starting multiple instances from the same folder.</p>
</blockquote>
</aside>
<p>Yeah for it to support this use-case it either needs to poll the Application environment constantly, or you yourself needs to tell it to check it for changes, or if the Application environment has a callback then it could listen to it and know when to update it’s internal state based on the environment setting.</p>
<aside class="quote no-group" data-username="sasajuric" data-post="33" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>I share this sentiment too. I believe that in a mid-to-long term it would be better if we motivated developers, and in particular library authors, to avoid app env unless absolutely necessary.</p>
</blockquote>
</aside>
<p>I’m not sure about this, <code>Application.get_env</code> and it’s ilk are very useful and great for even down to run-time configuration, if and only if libraries updated when you updated the values within it (this part needs fixing).  Some things access it on every access, some don’t because it is infeasible too (like an active database connection).</p>
<aside class="quote no-group" data-username="lorenzosinisi" data-post="34" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lorenzosinisi/48/10574_2.png" class="avatar"> lorenzosinisi:</div>
<blockquote>
<p>Instead of <code>on_boot</code> , that does not seem to be explicit enough for developers that come from other languages such as Ruby, why not having something like:</p>
</blockquote>
</aside>
<p>I still find this whole embedded environment method a horror coming from other languages, it seems so very limiting for the user to change…  &gt;.&gt;</p>
<p><em>/me is starting to lean more and more to the Java way, though preferably sans XML…</em></p>
<aside class="quote no-group" data-username="lorenzosinisi" data-post="34" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lorenzosinisi/48/10574_2.png" class="avatar"> lorenzosinisi:</div>
<blockquote>
<p>It is clear where the configuration is and should be defined</p>
</blockquote>
</aside>
<p>And if a library is added then you need to update the ‘global’ main configs to include it, even if it had it’s own sensible default config…</p>
<aside class="quote no-group" data-username="lorenzosinisi" data-post="34" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lorenzosinisi/48/10574_2.png" class="avatar"> lorenzosinisi:</div>
<blockquote>
<p>It is easy to understand what will be loaded in production, dev and testing</p>
</blockquote>
</aside>
<p>And what if you are wanting to change the url host on dev so cross-machine access can be tested, now you have to change the config and recompile, instead of just setting a temporary environment variable and running it like <code>elixir_args='-Dui.url.host=0.0.0.0' mix phx.server</code> for a single invocation (as is the Java’ish way).</p>
<aside class="quote no-group" data-username="lorenzosinisi" data-post="34" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lorenzosinisi/48/10574_2.png" class="avatar"> lorenzosinisi:</div>
<blockquote>
<p>We generate a module from each of those calls that could be compiled and replaced using hot swapping</p>
</blockquote>
</aside>
<p>You really only want to do this if you have no other option, updating the runtime application environment is far superior.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="35" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>We agree there are issues with umbrella though. As mentioned in the original post, those will be discussed separately, otherwise we end-up mixing too many topics and the discussion ends up too dispersed.</p>
</blockquote>
</aside>
<p>Each umbrella app should hold and manage it’s own configuration.  Things that are ‘configured’ from other apps in the umbrella should be passed in via arguments to supervisors or ETS or whatever.</p>
<aside class="quote no-group" data-username="bitwalker" data-post="37" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>I’ve seen numerous mentions about the build-time/runtime confusion - but that is a problem beyond the scope of these changes (in my opinion). The biggest win we get here is by closing the gap between dev and releases, getting rid of dirty hacks like <code>REPLACE_OS_VARS</code> .</p>
</blockquote>
</aside>
<p>Two different issues indeed, one is ‘when’ the configuration is needed by the system, and the other is ‘where’ that configuration comes from.  Both really need to be solved far <em>far</em> better than they currently are though.</p>
<aside class="quote no-group" data-username="bitwalker" data-post="37" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>In general I agree with <a class="mention" href="/u/sasajuric" rel="nofollow">@sasajuric</a> about configuration, but I personally feel that we have to, at a minimum, address the biggest pain with configuration today, which is dealing with releases.</p>
</blockquote>
</aside>
<p>Very, not being able to control where a configuration value comes from and how to update it is a freaking <em>major</em> pain, the amount of things that get hardcoded at build-time that should be changeable at boot-time or even run-time is astoundingly painful…</p>
<aside class="quote no-group" data-username="cybrox" data-post="38" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cybrox/48/10045_2.png" class="avatar"> cybrox:</div>
<blockquote>
<p>Currently, the <code>{:system ,value}</code> tuple exists as a de-facto standard in many situations.</p>
</blockquote>
</aside>
<p>No, no it’s not, it would be nice if it was, and sure the usual phoenix/ecto and so forth libraries support it, but so <em>so</em> very few third-parties support it.  Compare this to Java where third-party libraries have a built-in default config, of which the main application/jar can override some of those defaults with it’s own (without respecifying the whole thing), and of course you as the user/server can override those on the command line or system environment or a vault or whatever else, all without the third-party application needing to be touched, they were never built with that in mind, etc… etc…  (assuming the third-party library uses the standard Java configuration system, which almost every single one I’ve ever seen does).</p>
<aside class="quote no-group" data-username="cybrox" data-post="38" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cybrox/48/10045_2.png" class="avatar"> cybrox:</div>
<blockquote>
<p>However, it is usually only used in the production environment.</p>
</blockquote>
</aside>
<p>I don’t see why?  I use the system environment excessively for production and development (and rarely, but occasional on test too).</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="39" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>So in my opinion something has to be done, even if that something is rewording the proposal or breaking it apart.</p>
</blockquote>
</aside>
<p>Yeah, they probably should be broken apart.  One thing to determine how and where a config variable gets set, and another to figure out How To Determine ‘when’ the config is accessed.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="39" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Although I think the issue does run deeper. Until very recently you couldn’t configure a release using mix configs, so the majority of developers treat mix config as compile time. But now we are saying that the config files will run both at compile time and runtime (on boot), this means we are adding ambiguity to the config files.</p>
</blockquote>
</aside>
<p>Very much this yes.</p>
<p>And honestly I really <em>really</em> hate the environment concept.  Just let me define the variables however I wish in my own context, like if I want to use a default json config file or something to override some other defaults then I could do <code>ELIXIR_CONFIG=prod.json mix phx.server</code> or so to specify some things to override the internal config defaults…</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="39" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>We should discuss how this ambiguity should be addressed.</p>
</blockquote>
</aside>
<p>I’m thinking such namespace options as exampled shortly above would be quite useful differentiators.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="39" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>I think the issue with the current proposal is that it focused on making all of the configuration also run in a release. However, this has two issues:</p>
<ol>
<li>There is some code that you don’t want to run in a release</li>
<li>The code that you want to run in a release is actually the smaller part of the configuration</li>
</ol>
</blockquote>
</aside>
<p>Very true, this would just be a ‘release’ set of configs (that of course delegate defaults to the global build configs, but not boot or runtime for obvious reasons).</p>
<aside class="quote no-group" data-username="bitwalker" data-post="40" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>The reason we have a compile-time/run-time dichotomy in the first place is because people <em>couldn’t</em> use their Mix configs in a release - but that is where virtually everyone starts, and they find out the hard way that, oh actually, you can’t do that, because reasons.</p>
</blockquote>
</aside>
<p>In the C++ ecosystem you ‘do’ indeed set all your options in the build script (say the CMakeLists.txt file, which is like C++'s mix.exs file), and <em>yes</em> you can indeed override them from the command line for the build and hardcoded boot setup (and many libraries allow for boot-time overriding via environment/commandline as well).  Again, the JVM does not handle this bad at all…</p>
<aside class="quote no-group" data-username="bitwalker" data-post="40" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>Those things should be pushed into application code then, not defined in <code>config.exs</code> .</p>
</blockquote>
</aside>
<p>Please…  Then more libraries would accept options in a non-build-time-only way…</p>
<aside class="quote no-group" data-username="bitwalker" data-post="40" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>To put it more plainly, I think that by unifying configuration (i.e. one config file, one set of semantics), it becomes easier to understand, and is easy to adapt to for older systems.</p>
</blockquote>
</aside>
<p>So you favor the JVM style then (which solves what you seem to be describing what you want solved, it handles where the config is set, but it otherwise unified, it makes no distinction upon ‘when’ they are accessed but you can override it in specific scopes as well)?</p>
<aside class="quote no-group" data-username="bitwalker" data-post="40" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>Configuration should be mostly static in nature - if people need to execute “boot-only” code, it should go in their applications, not in the config files.</p>
</blockquote>
</aside>
<p>That is how the JVM’s is.  A static XML file of ‘defaults’ (please don’t use XML… or YAML, or JSON… erlang’s syntax I actually quite like though, or elixir’ified) that can be overridden in a variety of ways.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="41" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>So the configuration above is a compile-time configuration. There are many other examples. For example, the mime configuration mentioned in this thread. Some of the Logger configuration keys. Even the host configuration for <code>force_ssl</code> in Phoenix was compile time until recently fixed. This will exist regardless of the configuration provider and it is rather decided by how libraries consume configuration. This was less of an issue in the past because mix config only applied at compile time anyway.</p>
</blockquote>
</aside>
<p>Yeah all this kind of stuff I think does <em>not</em> belong in the config.exs, but rather in either the mix.exs if it is build-time or in a supervisor options list or ETS or something if boot-time.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="41" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Then this is an argument for not supporting <code>System.get_env/1</code> in config files in the first place. The only reason why we are doing this is because people want to read configuration such as HOST, PORT and DATABASE_URL at boot time (i.e. when the release starts).</p>
</blockquote>
</aside>
<p>This is where the JVM style of a static file that can be overridden by a multitude of ways (including the system environment or command line or so) is immensely useful.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="41" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>For 1: see the git example in thread</p>
</blockquote>
</aside>
<p>Honestly I think that should be a generated file, I.E. just in mix.exs that is used to do whatever (name output files or whatever) as well as could be dumped into a module at compile-time, same as both C++ and the JVM work to do the same things.  It should absolutely not be in the config as it is very very static once a build is complete.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="41" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>For 2: because of what you just said above: configuration is mostly static in nature. Get any production application and notice that the number of configurations that actually use <code>System.get_env</code> is a small part of the overall configuration</p>
</blockquote>
</aside>
<p>Precisely, most should be either baked in to code via mix.exs or via explicitly passing in options at boot time, the things that are changeable should probably use the JVM method of a static default config file that is overrideable via a vast variety of methods.</p>
<p>But yeah, I think I prefer the JVM model at this point odd as that feels for me to type, it’s similar to how C++ does it but more built-in, as it should be…</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82515" data-batch-url="/posts/batch_likers">
                        8
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302/42">Post #41</a>
	                </div>
	            </div>
              <div id="likers-container-82515" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82515"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #41"></div>
  </section>
</div>
    <div class="postbit" id="82522" data-post-id="82522">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bitwalker" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/120/998_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bitwalker
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Leader</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="41" data-topic="14302">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>I have a hunch that we are talking past each other here. <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
</blockquote>
</aside>
<p>Haha probably <img src="https://forum.elixirforum.com/images/emoji/apple/stuck_out_tongue.png?v=15" title=":stuck_out_tongue:" class="emoji" alt=":stuck_out_tongue:" loading="lazy" width="20" height="20"></p>
<p>I guess <a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a> came closest to my feelings on compile-time configuration, which is that <code>config.exs</code> feels like the wrong place for that kind of thing. People have had a tendency to use <code>config.exs</code> for <em>all</em> configuration, compile-time (i.e. baked into the build), runtime global, and runtime local (i.e. really should be a parameter to a supervisor spec, or a function, but is instead read from the app env).</p>
<p>Why not use <code>mix.exs</code> for compile-time configuration? It is already used for a variety of compile-time only config items, such as <code>:elixirc_paths</code>, <code>:compilers</code>, etc. Some of that blends with project configuration, but as you can see from one of the examples you provided, it is not uncommon to see references to <code>Mix.Project.config</code> in <code>config.exs</code>, which implies that project configuration can be seen as just another set of compile-time config values. Not to mention that you can already do “compile-time” configuration for your own application in <code>mix.exs</code>:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def application do
  [env: [key: value, ...]]
end
</code></pre>
<p>I guess my beef is with the fact that we are looking to make the distinction between compile-time and runtime configuration in <code>config.exs</code> with <code>on_boot</code>; and I think we should re-evaluate why we think <code>config.exs</code> is the right place for compile-time config in the first place. <a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a> has some interesting thoughts on that, and I think there is something to be said for how Go, Java, and others deal with it. You can set application env variables via the command line already, so I think we have that covered, but what we can’t do is define compile-time constants, for example the current commit hash as demonstrated in one of the examples earlier. I think virtually all the examples we’ve seen here fall in that category. Having a convenient place to set those, or set defaults, seems like a sane choice, and what better place than <code>mix.exs</code>, which effectively already carries some of those constants (app name, version, etc.).</p>
<p>If we are going to view <code>config.exs</code> as compile-time config though, I think that is confusing, and is going to continue to be confusing, even with additions like <code>on_boot</code>. I’ve always viewed <code>config.exs</code> in the same way that I view <code>.conf</code>, <code>.ini</code> and other config files in that vein - and I suspect I’m far from alone in that.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="82522" data-batch-url="/posts/batch_likers">
                        9
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302/43">Post #42</a>
	                </div>
	            </div>
              <div id="likers-container-82522" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="82522"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #42"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/14302/load_more?page=5">Load more posts</a>
</div></template></turbo-stream>