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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="chulkilee" data-post="11" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chulkilee/48/6207_2.png" class="avatar"> chulkilee:</div>
<blockquote>
<p>Another idea: I’m wondering we can define common configuration spec in each app module, and expose back to config tools, not vice versa. By doing that, we can enforce the config is actually being passed (e.g. avoiding an error that I add config at config tool but not using it app…)</p>
</blockquote>
</aside>
<p>I’ve seen people do this with Vapor. The module will define a group of providers. All of the providers are composed together and loaded on application start.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Process do
  alias Vapor.Provider.{Group, Env}
  def config do
    %Group{
      name: :process_config,
      providers: [
        %Env{bindings: [port: "PROCESS_PORT"]},
      ]
    }
  end
end

defmodule Application do
  def start(_, _) do
    config = Vapor.load!([
      Process.config(),
    ])
   children = [
      {Process, config.process_config},
    ]

    Supervisor.init(children, startegy: :one_for_one)
  end
end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164547" 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/runtime-configuration-library-with-casting-validation-etc-for-native-releases/29365/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-164547" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164547"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="164581" data-post-id="164581">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This is a very interesting discussion!</p>
<p>I do not see the current landscape as overly fragmented. It seems like the different solutions have different design goals behind them, and exploring all of those is valuable.</p>
<p>Nevertheless, what I think is <em>most</em> valuable are discussions like these, in which we can compare approaches. <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p>
<p><code>Specify</code> was created based on a description of <code>Vapor</code>, when Vapor was still vaporware (either during last year’s ElixirConf.EU or on one of the Elixir Outlaws episiodes). It took the idea of a layered stack of configuration providers from Vapor.<br>
However, the main and more important idea behind Specify is to make it explicit what keys (having which types) you are expecting your configuration to define. Based on the configuration specification it will:</p>
<ul>
<li>Automatically validate/parse the values passed in, raising errors when values are malformed.</li>
<li>Add a description of all the configuration fields to the documentation of the module it is defined in.</li>
<li>Raise errors when required fields are missing (i.e. are not defined anywhere in your configuration stack).</li>
</ul>
<p>As such, I think that’s quite close to the “expose back to config tools, not vice versa” that <a class="mention" href="/u/chulkilee" rel="nofollow">@chulkilee</a> is asking about.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164581" 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/runtime-configuration-library-with-casting-validation-etc-for-native-releases/29365/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-164581" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164581"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="164609" data-post-id="164609">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>By the way, another key idea behind Specify was to be explicit in what is read from where. It is meant to be able to be used by libraries just as much as applications, which was based on a discussion on this forum two years ago about structuring configuration (<a href="https://forum.elixirforum.com/t/rethinking-app-env/14315/20" class="inline-onebox" rel="nofollow">Rethinking app env - #20 by blatyo</a>).<br>
The key idea is that a library can specify clearly what values (and types of values) are expected, as well as default ways to structure the configuration-layering. People using the library can then override this default configuration-layering (as well as the values passed at any of those layers).<br>
The configuration-layer that always takes the most precedence is the one where we pass in values explicitly when calling <code>YourConfigModule.load(explicit_values: %{...}, _other, _options)</code> or <code>YourConfigModule.load_explicit(..., _options)</code>, to allow for easy testability or per-location defaults (rather than only per-process or only globally).</p>
<p><a class="mention" href="/u/sasajuric" rel="nofollow">@sasajuric</a> I wonder about the choice of your new to-be-released configuration library to use functions to retrieve the configuration for two reasons:</p>
<ol>
<li>This does not allow ‘local’ overrides to the configuration. Of course, one might argue that the kinds of settings that need local overrides should not be stored in (this kind of) configuration at all. However, deciding whether that is the case for some value is then e.g. placed on the burden of a library designer, unless your library is not intended to be used by other libraries but only by top-level applications.</li>
<li>It hides the internal details of fetching the configuration. What if fetching configuration is slow but we write code where we call one of the configuration functions many times per second? This is probably the kind of stuff that works fine in development but might break in production, where configuration might be fetched from other locations. And what if race conditions happen where we fetch two related configuration-values, but between the two reads the configuration source is updated, so we end up with one ‘old’ and one ‘new’ value?</li>
</ol>
<p>Nevertheless, I love the idea of having clear specs (and therefore code-completion-suggestions and potentially some type-checks or other compile-time-checks) and would love to pick your brain on if there are ways to combine this while leaving the two properties I mentioned intact.</p>
<hr>
<p><a class="mention" href="/u/chulkilee" rel="nofollow">@chulkilee</a></p>
<aside class="quote no-group" data-username="chulkilee" data-post="11" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chulkilee/48/6207_2.png" class="avatar"> chulkilee:</div>
<blockquote>
<p>One thing I’d like to ask: what kind of validation besides type check (e.g. parsing to integer) do you want to put in config-read time <em>not inside the app init</em> ?</p>
</blockquote>
</aside>
<p>I think this depends on what you are configuring.</p>
<ul>
<li>wrong field names being used in the code that consumes the configuration could be catched at compile-time.</li>
<li>missing configuration should prevent the piece of code that requires that configuration to be run. If your whole application depends on something, that should prevent it from starting. If only part of it depends on it, you can still use the rest (just using normal supervision techniques; processes that require something fetch that during their startup).</li>
<li>Although rare, sometimes it makes sense to reload configuration at runtime (i.e. alter the configuration independently from your app’s release cycle). We do get close to the deeper question of ‘when can we call something configuration’?</li>
</ul>
<aside class="quote no-group" data-username="chulkilee" data-post="11" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chulkilee/48/6207_2.png" class="avatar"> chulkilee:</div>
<blockquote>
<p>I know there are some “bad config” we don’t want to even let the whole apps start… but doesn’t it make duplicate work? Shouldn’t we leverage apps and supervision trees instead?</p>
</blockquote>
</aside>
<p>I think this is also covered by my reply above <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>
<aside class="quote no-group" data-username="chulkilee" data-post="11" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chulkilee/48/6207_2.png" class="avatar"> chulkilee:</div>
<blockquote>
<p>Also I’m curious how these tools work well with Config.Provider - or whether we need some changes in Config.Provider.</p>
</blockquote>
</aside>
<p>This is a good question. Specify predates the new Mix release changes, and I have not had time to look into how these changes might enable special interoptability.</p>
<p>A related question to ask, however, is in which way the two should interact:<br>
Should we see Mix releases as a single configuration source, or should we instead see Specify/Vapor/Saša’s new tool as a source for Mix’s way to do configuration?<br>
I currently lean towards the former, because Mix’s way of doing configuration is more rigid than what these tools can provide, but I am very interested in the opinions of <a class="mention" href="/u/keathley" rel="nofollow">@keathley</a> and <a class="mention" href="/u/sasajuric" rel="nofollow">@sasajuric</a> and anyone else on this matter.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164609" 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/runtime-configuration-library-with-casting-validation-etc-for-native-releases/29365/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-164609" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164609"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="164616" data-post-id="164616">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Qqwy" data-post="14" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/qqwy/48/1349_2.png" class="avatar"> Qqwy:</div>
<blockquote>
<p>I wonder about the choice of your new to-be-released configuration library</p>
</blockquote>
</aside>
<p>I’m certain that we don’t support all the scenarios. Lib was designed specifically for the limited (but very real) set of problems which my clients face. So for example, we currently don’t support <code>nil</code> at all. You can provide an optional value but you have to give it a default which is not <code>nil</code>. I’m sure this is not enough, and I spent a bit of time thinking it through, but I don’t yet have a clear view on how to tackle it, and we don’t need it so far, so I’m still letting it simmer <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>
<aside class="quote no-group" data-username="Qqwy" data-post="14" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/qqwy/48/1349_2.png" class="avatar"> Qqwy:</div>
<blockquote>
<p>This does not allow ‘local’ overrides to the configuration.</p>
</blockquote>
</aside>
<p>Not sure what you mean, but we do allow local dev/test defaults as I said before:</p>
<aside class="quote no-group" data-username="sasajuric" data-post="8" data-topic="29365">
<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>The way we approached this is by allowing the following spec:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">{:db_name, dev: "my_db_dev", test: "my_db_test"}
</code></pre>
<p>This is interpreted as follows:</p>
<ul>
<li>in dev mode, the default is my_db_dev</li>
<li>in test mode, the default is my_db_test</li>
<li>both defaults can be overridden via os env</li>
<li>there’s no default in prod - the app will fail to start if os env is not provided</li>
</ul>
</blockquote>
</aside>
<p>Is that what you have in mind, or are you talking about some other scenarios?</p>
<aside class="quote no-group" data-username="Qqwy" data-post="14" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/qqwy/48/1349_2.png" class="avatar"> Qqwy:</div>
<blockquote>
<p>What if fetching configuration is slow but we write code where we call one of the configuration functions many times per second?</p>
</blockquote>
</aside>
<p>This is currently indeed not tackled, simply b/c we’re only using OS env, so we don’t care about it. However, there is some basic plumbing in place to make it work.</p>
<p>First, beyond individual getters, we also inject <code>fetch_all</code> which returns the complete map. This allows clients to cache the stuff however they want to. For example, you could retrieve this during app startup and pass it through the supervision tree. Alternatively, you might want to store it in some ets table, or even app config (which is after all an ets table <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>
<p>Admittedly, with <code>fetch_all</code> you lose compilation guarantees, but we still get typespecs, so that’s still something at least.</p>
<p>It’s also worth mentioning that <code>fetch_all</code> paves way for merging configurations from different sources. Basically, you can define multiple config modules, fetch all from them, and then perform a map merge.</p>
<p>It’s not perfect though, b/c you currently have to copy-paste the definition. I’ve deliberately coupled config definition with the adapter, b/c that’s the simplest interface that fits my client’s needs, but I’m aware that it’s not very flexible, so I’m definitely open to expanding it, though I’d like to hear the exact use cases first.</p>
<p>Another plumbing for faster retrieval is in the source adapter contract which looks as follows:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">@callback values([Provider.param_name()]) :: [Provider.value()]
</code></pre>
<p>So the generic code asks the source to fetch all the params at once, which means that the adapter can make a single round trip to the underlying source, such as an external database.</p>
<p>We might add some internal caching logic too, but I want to defer that until the need arises. The benefit of internal caching is that we could keep functions as getters (so compile-time guarantees), and still have fast access. OTOH, caching brings a lot of complexity, so I’m a bit cautious about it.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164616" 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/runtime-configuration-library-with-casting-validation-etc-for-native-releases/29365/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-164616" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164616"
                     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 #14"></div>
  </section>
</div>
    <div class="postbit" id="164617" data-post-id="164617">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Qqwy" data-post="14" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/qqwy/48/1349_2.png" class="avatar"> Qqwy:</div>
<blockquote>
<p>Should we see Mix releases as a single configuration source, or should we instead see Specify/Vapor/Saša’s new tool as a source for Mix’s way to do configuration?</p>
</blockquote>
</aside>
<p>My current opinion on this matter is that I avoid doing anything in releases.exs if I can help it. The reason is that this is a free-form code which runs only in production, which means that it’s not easily (if at all) testable on CI. I’m not confident with writing such code, and so I like to keep as much of config as possible outside of it. Providing config during app boot has a few shortcomings, but on the plus side it brings production and dev/test much closer to each other, and so I strive to have as much config as I can in the app start.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164617" 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/runtime-configuration-library-with-casting-validation-etc-for-native-releases/29365/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-164617" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164617"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="164624" data-post-id="164624">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thank you for your detailed response! <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p>
<aside class="quote no-group quote-modified" data-username="sasajuric" data-post="15" data-topic="29365">
<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>
<aside class="quote no-group" data-username="Qqwy" data-post="14" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/qqwy/48/1349_2.png" class="avatar"> Qqwy:</div>
<blockquote>
<p>This does not allow ‘local’ overrides to the configuration.</p>
</blockquote>
</aside>
<p>Not sure what you mean …</p>
</blockquote>
</aside>
<p>I mean: What happens if you want to use something twice in your application (or even twice within a single process), configured differently? Use cases of these are for instance:</p>
<ul>
<li>Any library that depends on configuration but you might want to use two or more times in your application.</li>
<li>Single tests wanting to run in a slightly different environment from other tests (for instance to test how the app responds being configured in certain ways).</li>
<li>Abstract datatypes where we want to configure what concrete implementation of that datatype is being used for some reason (like performance vs. memory tradeoffs) in one place of our code differently from other place(s).</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164624" 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/runtime-configuration-library-with-casting-validation-etc-for-native-releases/29365/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-164624" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164624"
                     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 #16"></div>
  </section>
</div>
    <div class="postbit" id="164627" data-post-id="164627">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Qqwy" data-post="17" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/qqwy/48/1349_2.png" class="avatar"> Qqwy:</div>
<blockquote>
<p>I mean: What happens if you want to use something twice in your application (or even twice within a single process), configured differently?</p>
</blockquote>
</aside>
<p>Then I believe you need two config values. E.g. if you want to run two Phoenix endpoints, say main site and admin, then you need e.g. <code>public_http_port</code> and <code>admin_http_port</code>, right?</p>
<aside class="quote no-group" data-username="Qqwy" data-post="17" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/qqwy/48/1349_2.png" class="avatar"> Qqwy:</div>
<blockquote>
<p>Single tests wanting to run in a slightly different environment from other tests (for instance to test how the app responds being configured in certain ways).</p>
</blockquote>
</aside>
<p>I’d first attack this by having the code under test accept config as function parameters, and then provide different parameters from the corresponding tests.</p>
<aside class="quote no-group" data-username="Qqwy" data-post="17" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/qqwy/48/1349_2.png" class="avatar"> Qqwy:</div>
<blockquote>
<p>Abstract datatypes where we want to configure what concrete implementation of that datatype is being used for some reason (like performance vs. memory tradeoffs) in one place of our code differently from other place(s).</p>
</blockquote>
</aside>
<p>This is something I’m not considering for the foreseeable future. In my view, config provisioning should be about fetching atomic values (connection params, auth tokens, pool sizes, logger leves &amp; such). Building arbitrary complex data representation is IMO usually best left to the app code. Perhaps I’m wrong, but I definitely want to start lightweight and expand from that. That said, I’d like to hear more about concrete use cases you have in mind.</p>
<p>I should mention that our provider internally uses ecto changesets for type conversion, so custom complex types and arbitrary variations might be possible via ecto types. TBH I didn’t even explore this, we just use changesets because they are convenient for converting types and reporting errors <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="164627" 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/runtime-configuration-library-with-casting-validation-etc-for-native-releases/29365/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-164627" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164627"
                     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 #17"></div>
  </section>
</div>
    <div class="postbit" id="164631" data-post-id="164631">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>These are exactly my feelings. Our individual solutions might look slightly different. But this is the core problem.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164631" 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/runtime-configuration-library-with-casting-validation-etc-for-native-releases/29365/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-164631" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164631"
                     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 #18"></div>
  </section>
</div>
    <div class="postbit" id="164643" data-post-id="164643">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="keathley" data-post="4" data-topic="29365">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/keathley/48/2652_2.png" class="avatar"> keathley:</div>
<blockquote>
<p>In order to support a nice dev experience, we check in the <code>.env</code> files to our repos. Vapor’s dotenv provider supports a hierarchy of files and one of those is <code>.env.local</code> . This is where developers will overwrite values or add tokens, etc. We ensure <code>*.local</code> files are git ignored so they don’t get checked in.</p>
</blockquote>
</aside>
<p>Checking a <code>.env</code> file into git is a bad security practice. The <code>.env</code> should always be in the <code>.gitignore</code> file. Not doing so can lead to leak sensitive information in plain text to the version control system. Even if you are in control of such system, and it’s private, you should not leak the <code>.env</code> file outside the server running your code.</p>
<p>Instead you should use the <code>.env.local</code> with the sane defaults for development, but I would prefer to be explicit in it’s name and call it <code>.env.dev</code>.</p>
<p>Then the README for the project could have the instructions to copy the <code>.env.dev</code> file to <code>.env</code>, or if you have a setup script for development you add this step there.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164643" 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/runtime-configuration-library-with-casting-validation-etc-for-native-releases/29365/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-164643" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164643"
                     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 #19"></div>
  </section>
</div>
    <div class="postbit" id="164644" data-post-id="164644">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sasajuric" data-post="8" data-topic="29365">
<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>there’s no default in prod - the app will fail to start if os env is not provided</p>
</blockquote>
</aside>
<p>That’s it, the way to go when dealing with environment values for production.</p>
<p>Defaults values may lead to have production running with credentials of type <code>user: admin</code> and <code>password: admin</code> , just to give the most obvious example.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="164644" 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/runtime-configuration-library-with-casting-validation-etc-for-native-releases/29365/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-164644" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="164644"
                     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 #20"></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/29365/load_more?page=3">Load more posts (14 remaining)</a>
</div></template></turbo-stream>