12
votes

I created a Phoenix app then added the bamboo module for sending email, and I successfully sent my first email using Elixir this afternoon, but I had to hard code the username and password into the config.exs.

I read this article and set up a .env file in the root of my phoenix project, and I am trying to load the environment variables using the following statement(s), within the config.exs file.

username: System.get_env("SMTP_USERNAME"),
password: System.get_env("SMTP_PASSWORD"),

However, the emails are not being sent, and bamboo is giving me a rather cryptic error message.

I am building the phoenix app using the following command from the terminal,

iex -S mix

and I'm manually sending the emails within a iex session with a command similar to the one below,

CrjApi.Email.hello_text_email("[email protected]") |> CrjApi.Mailer.deliver_now

but the emails are only being sent when the username / password are hard coded into the config.exs file. How can I use the .env file I setup so I don't have to hard code the username / password into the config.exs?

Note: I'm running OS X, and using the fish shell.

4
If you go into iex and type System.get_env("SMTP_USERNAME"), do you get the expected value? Do the same for the password.Justin Wood
@JustinWood the command you suggested is returning nil. And thanks for pointing me in the right direction ;)ipatch
The article is working if you strictly follow every step. Still there is a typo in source .env.sekrett

4 Answers

10
votes

You can use confex module in your project. https://github.com/Nebo15/confex

This is a helper module that provides you with the option to read env configuration at runtime.

config.exs example

config :app_name,
  smtp_username:  {:system, "SMTP_USERNAME", "default_user_name"},
  smtp_password:  {:system, "SMTP_PASSWORD", "default_password"}

In your module

username = Confex.get(:app_name, :smtp_username)
password = Confex.get(:app_name, :smtp_password)

Into your iex type

System.put_env("SMTP_USERNAME", "real_username")
System.put_env("SMTP_PASSWORD", "real_password")
2
votes

I ended up creating a smtp.exs file within config directory which looks like the following,

smtp.exs

use Mix.Config

config :crj_api, CrjApi.Mailer,
  username: "foo",
  password: "secret_password"

and then added the following to config.exs

import_config "smtp.exs"

Now when I load the application with iex -S mix it loads in these application variables everytime, and I don't have source an environment variable for each terminal session.

2
votes

You can put all your environment variables in a file named for example .env.dev or .env.prod (don't forget to add .env.* to .gitignore file):

export SMTP_DOMAIN=smtp.trumpy.xyz
export [email protected]
export SMTP_PASSWORD=donny123
export SMTP_PORT=587
...

Load that file and run Phoenix server:

source .env.dev && mix phx.server

Remember to use this syntax

port: {:system, "SMTP_PORT"},
username: {:system, "SMTP_USERNAME"},

In place of this

port: System.get_env("SMTP_PORT"),
username: System.get_env("SMTP_USERNAME"),

in order to load ENV variables at runtime.

0
votes

Like the article you wrote about, I use ENV vars for Phoenix from my System. Just create them via export:

export SMTP_USERNAME=you_variable

and so on and Phoenix will se them and get at the start server time. Also there is possible to use .env file, but I only use it with 'heroku local'.

Check this hex dotenv_elixir but it realy not elixir way.