How to set environment variables in dev.exs?

Hi All,
I set a environment variables in dev.exs , like below code.
when i start server, how can i set the ${enable} value?
thanks.

dev.exs
config :myapp, :enable, value: “${enable}”

I don’t remember there’s such thing like ${} in Elixir, you might mean #{} for string interpolation?

You can use System.get_env("enable") to get environment variable in your dev.exs file.

1 Like

Hi chensan,
Thanks for help.
seen like this , currently i am keep trying.
http://engineering.avvo.com/articles/using-env-with-elixir-and-docker.html

That post is using Exrm for building OTP release, that’s why it’s using ${}, also exrm is deprecated now. Since you’re configurating your dev.exs, there’s no need to use exrm, just use System.get_env.

2 Likes

Check out this guide Kubernetes Native Phoenix Apps.

I’ve had to adapt it a little to my umbrella use case but is really good and up to date.

Hi, @sen!
For using environment variables you can create a .env file anywhere in your project folder, I prefer to create it in project_name/config folder, with a content like here:

export FILE_FOLDER='/home/username/file_folder'
export FIRST_VARIABLE='some_var'

after saving file, source it using source config/.env from project directory, then u can use those variables in your project using commmand:
System.get_env("FILE_FOLDER")
Good luck!

IMPORTANT: don’t add spaces before and after equal sign.

10 Likes

I am very strongly interested in a blog post about this, if you decide to write one!

Thanks all.
I am doing like this, when i build and run docker after, can get the value in HomeController test.
But endpoint and route nothing to change, cant get the value.
I want to enable/disable plugin. if true will enable that plugin.
Anyone know the reason? if cant doing like this, i will change other way.

prod.exs
config :myapp, :enable, value: “${ENABLE}”

endpoint.ex
if Application.get_env(:myapp, :enable)[:value] do
disable/enable plugin…
end

I’m a little confused about the best way to store secrets.

When I looked for a way to automatically load a .env file, I found a dotenv package that says “This isn’t the Elixir way.”

The tutorial I read said to hard-code the Guardian secret in config/config.exs, but that doesn’t seem right.

I was going to do this, but I’m wondering if it isn’t a good idea because of the message in the README of that dotenv package:

# config/config.exs
config :app_name, AppName.Guardian,
       issuer: "app_name",
       secret_key: System.get_env("GUARDIAN_SECRET")

I could manually source config/.env before starting the server, but I’m probably going to forget to do that sometimes.

It’s confusing, because prod.secret.exs also uses System.get_env("DATABASE_URL"). If secrets were meant to be hard-coded there, why would it look for environment variables by default and/or not be excluded automatically in .gitignore?

Does anyone know of an automated way to load the .env file that still follows “the Elixir way”?

6 Likes

I don’t know if this is the correct solution, but it looks like development keys are meant to be hard-coded into version control, like the default secret_key_base in config/config.exs? I usually create a .env for development when using other languages, but after looking through all the config files, it looks like the default setup will override the default config.exs settings (and dev.exs isn’t loaded) when you’re running in production.

(I’m guessing that the tutorial I read probably should have recommended putting the Guardian key in dev.exs instead of config.exs.)

If I’m mistaken, please let me know. :slight_smile:

@Josh, here’s what I’m doing for now, which I’m happy with so far. :slight_smile:

Development

I find text files convenient in dev, and don’t want to have to export env vars every time I run the app locally.

config/dev.secret.exs contains dev secrets that shouldn’t be in version control. (secret_key_base keys could be moved into this file, but I’ve left mine in dev.exs for now as it’s only for signing and encrypting in dev while testing.)

.gitignore contains **/*.secret.exs so that ‘secret’ files are kept out of Git version control.

Production

I use Mix releases and use environment variables via systemd, and so keep the System.get_env(ENV_VAR) calls.

Important to note is that there’s a new recommended way of handling run time (as opposed to compile time) config in Elixir >= 1.9: the Config module. The whole page is worth reading, but here’s the upshot:

The Config module in Elixir was introduced in v1.9 as a replacement to Mix.Config , which was specific to Mix and has been deprecated.

You can leverage Config instead of Mix.Config in two steps. The first step is to replace use Mix.Config at the top of your config files by import Config .

In Phoenix, rename prod.secret.exs to the special filename releases.exs.

Then, the environment variables read in this file are read at run time on the server, and not when building (perhaps locally).

4 Likes

Second the releases.exs. I recently migrated to this and was rudely surprised when my compile time values didnt show up in prod :sweat_smile: but it’s definitely the right way to do things.

1 Like

Thanks, I’ll try that.

I don’t see it mentioned but it solved this problem for me: https://github.com/direnv/direnv

3 Likes

I just started at a place that is using direnv. I thought I would hate it… I don’t.

4 Likes

Thanks, I just installed it and it looks good.