lessless
Hi,
There are a few writeups describing alternative config arrangements by a topic (or an OTP app):
- Configuring Phoenix apps: Two small adjustments with big effects | bitcrowd blog
- Tips for improving your Elixir configuration
I tried it out on a hobby project and found it more convenient than a configuration per environment, and therefore, I’d like to propose changing the default.
In my case, the whole of config.exs was just five lines long
import Config
for config_file <- Path.wildcard(Path.join([File.cwd!(), "config", "compile_time", "*.exs"])) do
import_config(config_file)
end
The longest file in the compile_time dir, the endpoint configuration was
import Config
config :my_app, MyAppWeb.Endpoint,
url: [host: "localhost"],
render_errors: [
formats: [html: MyAppWeb.ErrorHTML, json: MyAppWeb.ErrorJSON],
layout: false
],
pubsub_server: MyApp.PubSub,
live_view: [signing_salt: "tU71HhHQ"]
case config_env() do
:dev ->
config :my_app, MyAppWeb.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 4001],
check_origin: false,
code_reloader: true,
debug_errors: true,
secret_key_base: "ztwTR1eV8qJmsKqFsAHcSu49my17XV5KULr6okIBXz9aRJEc4t8L2q3okO1L+ujE",
watchers: [
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]},
tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]}
]
config :my_app, MyAppWeb.Endpoint,
live_reload: [
patterns: [
~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
~r"priv/gettext/.*(po)$",
~r"lib/my_app_web/(controllers|live|components)/.*(ex|heex)$"
]
]
:test ->
config :my_app, MyAppWeb.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 4002],
secret_key_base: "oKSvXrmhGIz0TZUqB5PzlzJREnh7I1+TMCyWlvEhCR/AgN3jec4kl2s+qTkZsqTP",
server: false
_ ->
:ok
end
I also split runtime.exs under config/runtime, which required a bit more ceremony:
- figure out where from configs should be read (source vs release
- copying runtime configs during release assembly.
# config/runtime.exs
import Config
topic_configs_path =
if config_env() == :prod do
root_dir = :code.priv_dir(:my_app)
release_version = Application.spec(:my_app, :vsn) |> to_string()
runtime_path =
[root_dir, "..", "..", "..", "releases", release_version, "runtime"]
|> Path.join()
|> Path.expand()
Path.join([runtime_path, "*.exs"])
else
Path.join([File.cwd!(), "config", "runtime", "*.exs"])
end
for config_file <- Path.wildcard(topic_configs_path) do
Code.require_file(config_file)
end
defmodule MyApp.MixProject do
def project do
[
releases: [
sesame: [
steps: [:assemble, ©_prod_runtime_configs/1],
]
]
]
end
defp copy_prod_runtime_configs(%Mix.Release{version_path: path} = release) do
release_config_dir = "runtime"
File.mkdir!(Path.join([path, release_config_dir]))
all_configs =
[File.cwd!(), "config", "runtime", "*.exs"]
|> Path.join()
|> Path.wildcard()
for config_file <- all_configs do
dst_path = Path.join([path, release_config_dir, Path.basename(config_file)])
Logger.info("COPYING #{config_file} as #{dst_path} ")
File.cp!(
config_file,
dst_path
)
end
release
end
Btw, if anyone have suggestions on better ways to get a releases directory than
root_dir = :code.priv_dir(:my_app)
release_version = Application.spec(:my_app, :vsn) |> to_string()
runtime_path =
[root_dir, "..", "..", "..", "releases", release_version, "runtime"]
|> Path.join()
|> Path.expand()
that would be a very welcomed change
Trending in Proposals: Ideas
We are seeing a lot of warning logs like this:
navigate event to "https://someurl" failed because you are redirecting across live_sessio...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 7- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
D4no0
The question is, how do you plan on enforcing correct app configuration, do you make any checks whether the correct application is configured in those
.exsfiles?lessless
How do you mean?
LostKobrakai
I‘m not a fan tbh. I don‘t want to look through N files just to figure out how my project is configured for e.g. testing or development. There might even be M files out of the N, which don‘t even have any config for a specific env. But I‘d still need to look at those just to notice that.
lessless
What’s the use case for looking into how a “project” is configured vs. peeking into a configuration for a specific app, an ecto repo or a phx endpoint?
LostKobrakai
I‘ve worked on a project with quite a few dependencies and nerves (multiple MIX_TARGETs) involved. Knowing how things are configured for a certain place code runs in is more important than how individual parts might be configured. Often configuration on app A kinda correlates with configuration on app B for a certain target and you loose that relation quite easily if it is scattered around a handful of individual config files, mixed in an even larger set of existing config files.
It would be a pain to build a mental model of how target A is configured over target B if you need to look through 10-30 individual files, parse all their conditionals and combine in your mind how all the individual pieces are configured to make the larger whole work. I prefer have less branches and larger chunks of „all this happens together in this branch“ over branching by individual applications and then branching those individually by all already existing criteria.
lessless
That project sounds like an outlier to me.
dimitarvp
If you have already made up your mind then use your way, nobody is stopping you. No need to argue which case is more representative, plus you are biased in this case so it’s not an honest discussion.
If you really want to argue statistics and representation: I worked on no less than 25 Elixir projects and all of them used per-env config files, and bigger teams also employed sorting configs by app name alphabetically which made them trivial to browse and modify.